我试图在Graphics中使用XOR模式在平面背景下绘制1bit纹理,当我在Graphics中遇到一个我不理解的行为时。
这是我的意思的一个例子,隔离:
package teststuff;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
public class XORTest extends JFrame {
public XORTest() {
super("Test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 400);
setIgnoreRepaint(true);
setResizable(false);
setVisible(true);
createBufferStrategy(2);
Graphics graphics = getBufferStrategy().getDrawGraphics();
graphics.setColor(Color.black);
graphics.fillRect(0, 0, getWidth(), getHeight());
graphics.setColor(Color.green);
graphics.fillRect(30, 40, 100, 200);
graphics.setXORMode(Color.white); // (*)
graphics.fillRect(60, 80, 100, 200);
graphics.dispose();
getBufferStrategy().show();
}
public static void main(String[] args) {
XORTest test = new XORTest();
}
}
如果我取消注释标有(*)的行,则会按预期绘制两个绿色矩形。如果我离开它,则不会将任何内容绘制到组件中,甚至不会绘制预先绘制的黑色背景或绿色矩形。更奇怪的是,它曾经工作过一次。之前我的颜色为Color.green而不是白色。我改变后,它按预期绘制。但是,当我关闭应用程序并再次启动它时,它不再起作用,而且从那时起它就没有了。
这是java中的错误吗?在我的jre?图形的未记录行为?我在Windows上运行jdk7上的示例。
屏幕截图:Imgur album because it won't let me post 3 links
第三个屏幕截图是上面的代码,第一个带有(*)注释,第二个是它看起来如何工作(我在GIMP中创建了因为我没有截取屏幕截图)。
答案 0 :(得分:3)
如果没有相反的令人信服的理由,在paintComponent()
中覆盖JPanel
会更容易,更可靠,默认情况下是双缓冲。有令人信服的理由,请遵循BufferStrategy and BufferCapabilities中的指南。另请注意,
覆盖getPreferredSize()
以指定组件的首选大小。
应在event dispatch thread上仅构建和操作Swing GUI对象。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* @see https://stackoverflow.com/a/16721780/230513
*/
public class Test {
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new XORPanel());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static class XORPanel extends JPanel {
@Override
public Dimension getPreferredSize() {
return new Dimension(190, 320);
}
@Override
protected void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
graphics.setColor(Color.black);
graphics.fillRect(0, 0, getWidth(), getHeight());
graphics.setColor(Color.green);
graphics.fillRect(30, 40, 100, 200);
graphics.setXORMode(Color.white);
graphics.fillRect(60, 80, 100, 200);
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Test().display();
}
});
}
}