【问题标题】:Java swing drawing graphics nullpointer?Java swing 绘制图形空指针?
【发布时间】:2013-12-20 17:40:40
【问题描述】:

我想在我的JFrame 窗口中绘制一个矩形,但我总是收到nullpointer 错误。 为什么会这样?绘制矩形、渐变等图形或秋千落雪等图形的最佳(正确)方法是什么?

这是个例外:

Exception in thread "Thread-0" java.lang.NullPointerException
    at gui.Window.run(Window.java:24)
    at gui.Window$1.run(Window.java:34)
    at java.lang.Thread.run(Unknown Source)

来源:

public class Window extends JFrame implements Runnable {

    private boolean run = true;

    public Window() {
        super.setSize(500, 500);
        super.setTitle("MY GUI");
        super.setDefaultCloseOperation(EXIT_ON_CLOSE);
        super.setContentPane(new Container());
    }

    @Override
    public void run() {
        Graphics g = super.getContentPane().getGraphics();
        while (this.run) {
            g.setColor(new Color(0, 0, 0, 255));
            g.fillRect(0, 0, 200, 200);
        }
    }

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Window window = new Window();
                window.run();
            }
        }).start();
    }   
}

第 24 行错误:g.setColor(new Color(0, 0, 0, 255));

为什么要这么做?

【问题讨论】:

  • g 可能为 null 检查 super.getContentPane().getGraphics();, 在那里设置断点并调试它..

标签: java swing exception nullpointerexception


【解决方案1】:

您发布的代码毫无意义。

首先,与 Swing 组件的每次交互(对repaint() 的调用除外)都必须在事件调度线程中完成。

其次,运行一个不断在图形上绘制相同内容的无限循环是没有意义的。

第三,它不是这样工作的。您无法获取与组件关联的图形并在其上进行绘制。相反,您必须重写 Swing 组件的 paintComponent(Graphics) 方法,等待 swing 调用此方法,然后使用提供的 Graphics 参数来绘制您想要的任何内容。如果要更改正在绘制的内容,则需要在此元素上调用 repaint()。不要用 JFrame 那样做。创建 JComponent 或 JPanel 的子类,并将子类的实例添加到 JFrame 中,然后使该 JFrame 可见:

public class CustomComponent extends JComponent {
    @Override
    public void paintComponent(Graphics g) {
         // paint here
    }

    @Override
    public Dimension getPreferredSize() {
        // return preferred size here
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame f = new JFrame();
                f.add(new CustomComponent());
                f.pack(); 
                f.setVisible(true);
            }
        });
    }
}

【讨论】:

    【解决方案2】:

    如果组件不可见,getGraphics 将返回 null。

    要让您的Window 可见,您必须致电setVisible(bool)

    你也要小心using threads with Swing

    【讨论】:

    • 谢谢!但是为什么我运行它时它会如此滞后?
    • @user3123545:可能是因为你一直在画画。无限繁忙循环不是一个好主意。
    • 因为你在无限循环中重新绘制窗口
    • @user31223545 使用 JPanel 绘制并覆盖 paintComponent 方法。你不应该在 JFrame 之类的顶级容器上绘画
    猜你喜欢
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多