一个应该在本地运行时使用双缓冲,但是当窗口在远程会话时不使用双缓冲,如果想要获得每个模式的最佳性能.
ListView控件具有扩展样式,LVS_EX_DOUBLEBUFFER
它自动双重缓冲ListView的内容.
是否需要注册以通知本地和远程会话之间的更改,并相应地更新此标志?或者ListView会自动执行此操作吗?
我正在研究一个项目,我已经尽可能多地阅读了java中的双缓冲.我想要做的是添加一个组件或面板或其他东西到我的JFrame,其中包含要绘制的双缓冲表面.我想尽可能使用硬件加速,否则使用常规软件渲染器.到目前为止我的代码看起来像这样:
public class JFrameGame extends Game {
protected final JFrame frame;
protected final GamePanel panel;
protected Graphics2D g2;
public class GamePanel extends JPanel {
public GamePanel() {
super(true);
}
@Override
public void paintComponent(Graphics g) {
g2 = (Graphics2D)g;
g2.clearRect(0, 0, getWidth(), getHeight());
}
}
public JFrameGame() {
super();
gameLoop = new FixedGameLoop();
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new GamePanel();
panel.setIgnoreRepaint(true);
frame.add(panel);
panel.setVisible(true);
frame.setVisible(true);
}
@Override
protected void Draw() {
panel.repaint(); // aquire the graphics - can I acquire …
Run Code Online (Sandbox Code Playgroud) 这是我第一次尝试使用BufferStrategy
,我真的很感激一些提示.
1)为什么在下面的代码中,getSize()
在调整窗口大小之前返回0的尺寸?如何立即检测窗口的大小?
2)为什么什么时候getSize()
返回的东西不是窗户的全尺寸?IE为什么底部和右边都有一条黑色条带?
3)调整窗口大小时有没有办法摆脱闪烁?
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BSTest extends JFrame {
BufferStrategy bs;
DrawPanel panel = new DrawPanel();
public BSTest() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800,420);
setLocationRelativeTo(null);
setIgnoreRepaint(true);
setVisible(true);
createBufferStrategy(2);
bs = getBufferStrategy();
panel.setIgnoreRepaint(true);
add(panel);
panel.drawStuff();
}
public class DrawPanel extends JPanel {
public void drawStuff() {
while(true) {
try {
Graphics2D g = (Graphics2D)bs.getDrawGraphics();
g.setColor(Color.BLACK);
System.out.println("W:"+getSize().width+", H:"+getSize().height);
g.fillRect(0,0,getSize().width,getSize().height);
bs.show();
g.dispose();
Thread.sleep(20);
} catch (Exception e) { System.exit(0); …
Run Code Online (Sandbox Code Playgroud) 在下面的代码中,我正在使用doubleBuffer来避免图像的闪烁,就像我在这个问题中所建议的那样
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TestProgram extends JFrame implements KeyListener {
private Image doubleBuffer;
private Graphics myGraphics;
private BufferedImage TestImage;
private int cordX = 100;
private int cordY = 100;
public TestProgram() {
setTitle("Testing....");
setSize(500,500);
imageLoader();
setVisible(true);
}
public static void main(String[] args) {
new TestProgram();
}
public void imageLoader() {
try {
String testPath = "test.png";
TestImage = ImageIO.read(getClass().getResourceAsStream(testPath));
} catch …
Run Code Online (Sandbox Code Playgroud) 如果我需要使用双缓冲,我需要抑制WM_ERASEBKGND
消息.
我可以WM_ERASEBKGND
立即处理并返回.但是,我可以设置WNDCLASS
/ WNDCLASSEX
的hbrBackground
来NULL
,而不是处理的WM_ERASEBKGND
消息?这是正确的方法吗?
我编写了以下简单程序,它每100毫秒在屏幕上绘制一行(由timer1触发).我注意到绘图有点闪烁(也就是说,窗口并不总是完全是蓝色的,但是有些灰色闪耀).所以我的想法是使用双缓冲.但是当我这样做时,情况变得更糟.现在屏幕几乎总是灰色的,只是偶尔会出现蓝色(由timer2演示,DoubleBuffered
每2000毫秒切换一次).
对此有什么解释?
using System;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void Form1_Paint(object sender, PaintEventArgs e) {
Graphics g = CreateGraphics();
Pen pen = new Pen(Color.Blue, 1.0f);
Random rnd = new Random();
for (int i = 0; i < Height; i++)
g.DrawLine(pen, 0, i, Width, i);
}
// every 100 ms
private void timer1_Tick(object sender, EventArgs e) {
Invalidate();
}
// every 2000 ms
private …
Run Code Online (Sandbox Code Playgroud) 我已经创建了一个可以正常工作的动画,但是它很轻松.我需要双缓冲的帮助,因为我对它一无所知.
这是我onPaint()中的代码:
VOID onPaint(HDC hdc)
{
Graphics graphics(hdc);
Pen pen(Color(255, 0, 0, 255));
graphics.DrawEllipse(&pen, sf , 0, 10, 10);
}
Run Code Online (Sandbox Code Playgroud)
它工作正常,但闪烁.我试过这段代码,但它不起作用:
VOID onPaint(HDC hdc,HWND hWnd)
{
HDC hDC=GetDC(hWnd);;
HDC memDC = CreateCompatibleDC(hDC);
HBITMAP hMemBmp = CreateCompatibleBitmap(hDC,10,10);
HBITMAP hOldBmp = (HBITMAP)SelectObject(memDC,hMemBmp);
BitBlt(hDC, 0, 0, 10, 10, memDC, 0, 0, SRCCOPY);
Graphics graphics(memDC);
Pen pen(Color(255, 0, 0, 255));
graphics.DrawEllipse(&pen, sf , 0, 10, 10);
// Always select the old bitmap back into the device context
SelectObject(memDC, hOldBmp);
DeleteObject(hMemBmp);
DeleteDC(memDC);
}
Run Code Online (Sandbox Code Playgroud) private void button3_Click(object sender, EventArgs e)
{
this.DoubleBuffered = true;
for (int i = 0; i < 350; i++)
{
using (Graphics g = this.CreateGraphics() )
{
g.Clear(Color.CadetBlue);
g.DrawImage(Properties.Resources._256, 100, 100, i-150, i-150);
}
}
}
Run Code Online (Sandbox Code Playgroud)
然而,我认为我将DoubleBuffered设置为true,图像仍然闪烁.有什么想法我做错了什么?谢谢!
我在互联网上找到了这个双缓冲代码,但它没有解释.我在这段代码中有点困惑.
为什么使用Image"i"?如果要使用一次它有什么用?
当我们已经设置了颜色时,为什么我们要为前景颜色指定更改颜色?
什么是g.drawImage()方法呢?
这是代码:
public void update(Graphics g)
{
if(i==null)
{
i=createImage(getWidth(), getHeight());
graph=i.getGraphics();
}
graph.setColor(getBackground());
graph.fillRect(0, 0, getWidth(),getHeight());
graph.setColor(getForeground());
paint(graph);
g.drawImage(i,0,0,this);
}
Run Code Online (Sandbox Code Playgroud)
问候
一个简单的问题可能不是那么简单的解决方案.我的代码应该在黑色背景上显示一个可以在屏幕上移动的三角形.只显示任何内容,只显示无法右键单击的白色区域.它在appletviewer或HTML文档中都不起作用,并且没有显示语法错误.我的代码出了什么问题?
import java.awt.*;
import java.applet.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.awt.event.*;
public class Shipmovementtest extends Applet implements Runnable,KeyListener{
Graphics2D g2d;
Ship ship1 = new Ship();
BufferedImage backbuffer;
AffineTransform identity = new AffineTransform();
Shape ship1shape;
Thread gameloop;
public void start()
{
gameloop = new Thread(this);
gameloop.start();
}
public void run()
{
Thread t = Thread.currentThread();
while(gameloop==t)
{
try
{
Thread.sleep(20);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
repaint();
}
}
public void stop()
{
gameloop = null;
}
public void init()
{ …
Run Code Online (Sandbox Code Playgroud)