【问题标题】:Java draw on component in XOR mode draws nothingJava 在 XOR 模式下绘制组件不绘制任何内容
【发布时间】:2013-05-24 02:55:58
【问题描述】:

当我在 Graphics 中遇到我不理解的行为时,我尝试在 Graphics 中使用 XOR 模式在平面背景上绘制 1 位彩色纹理。

这是我的意思的一个例子,孤立的:

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 中创建了它,因为当时我没有截屏)。

【问题讨论】:

  • 我读过这个问题。我知道 XOR 模式应该做什么。这里的问题是它什么也没画。我将在原始问题中包含屏幕截图。
  • 当我运行它时,我得到第二张图片,除了蓝色是粉红色的。虽然有时它是空白的。
  • 我可能记错了蓝色,它很可能是粉红色的。但我很高兴您可以重现该错误。如果它是不可预测的,这似乎是java中的一个错误。
  • 更多类似竞争条件。但是我对 java 中的图形理解不够好,无法调试它。

标签: java swing graphics xor


【解决方案1】:

如果没有相反的令人信服的理由,在JPanel 中覆盖paintComponent() 会更容易、更可靠,默认情况下是双缓冲的。出于令人信服的理由,请遵循BufferStrategy and BufferCapabilities 中的指导方针。另请注意,

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();
            }
        });
    }
}

【讨论】:

  • 我确实有一个令人信服的理由不使用paintcomponent。我需要它与我的其他逻辑在同一个线程中。我会考虑你的其他建议。
  • @Scaatis:很公平,但您仍然需要同步访问共享数据;您可以使用super(false) 禁用JPanel 缓冲;还要注意setXORMode() 中“颜色以不可预测但可逆的方式更改”的情况。
  • 我认为“不可预测的方式”是颜色在各处异或,而不是整个绘图失败。我仍然不明白为什么我在 XOR 模式下绘图时只会出现灰屏,但无论如何我都会将您的答案标记为已接受。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多