【问题标题】:Java Swing NullPointerException when drawing绘制时Java Swing NullPointerException
【发布时间】:2010-04-07 16:12:27
【问题描述】:

我正在使用自定义的 JLayeredPane。 我有几个形状需要在 JLayeredPane 的不同图层上绘制。

为了测试这一点,我创建了一个 JPanel 并询问它的图形。然后我在 JPanel 上绘制一个测试矩形(准备图形),并在 JLayeredPane 的paintComponent 方法中最终绘制所有内容。但这失败了(NullPointerException)。

public class MyCustomPanel extends JLayeredPane {

// test
JPanel testpane;
Graphics g2;
// test

// constructor
public MyCustomPanel() {
    testpane = new JPanel();
    this.add(testpane, new Integer(14));
    g2 = testpane.getGraphics();
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);

    g2.drawRect(10, 10, 300, 300);
}

}

// run:
//Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
//        at view.MyCustomPanel.paintComponent(MyCustomPanel.java:65)

为什么我不能从我的 JLayeredPane 中绘制这样的 JPanel?我可以从我的paintComponent 方法中直接在我的JLayeredPane 上绘制,但这是在JLayeredPane 的默认面板上。我需要在我的 JLayeredPane 中添加的几个图层上创建和绘制。

我做错了什么? :s

【问题讨论】:

    标签: java swing drawing nullpointerexception jlayeredpane


    【解决方案1】:

    您应该使用g2 转换传递给您的Graphics

    Graphics2D g2 = (Graphics2D)g;
    

    你为什么不尝试解耦呢?

    class InnerPanel extends JPanel
    {
      public void paint(Graphics g)
      {
         Graphics2D g2 = (Graphics2D)g;
         g2.drawRect(....);
      }
    }
    
    class MyLayered extends JLayeredPane()
    {
      MyLayered()
      {
        this.add(new InnerPanel(), 14);
      }
    }
    

    这更有意义..

    还因为您正在尝试做一些不符合 Swing 行为的事情。 Swing 会自动调用适当的paint 方法来处理必须显示的内容,并且要使用此协议,您应该告诉Graphics 对象当Swing 向您的对象询问时要绘制什么(调用paint)方法,而不是在你想这样做的时候。

    这样,每当 Swing 想要绘制您的 JLayeredPane 时,您只需在其他事物的 Graphic 对象上绘制事物,而无需考虑 Swing 会在适当的时候调用它们的适当方法。

    总结:你不能在你想要的时候在Graphic对象上画东西。您可以在 Swing 调用的方法中执行此操作,否则这些对象中的 Graphics 没有任何意义

    【讨论】:

    • 但这将使用 JLayredPane 中的图形,而不是我的 JPanel 中的图形。所以我会在我的 JLayredPane 上而不是在我的 JPanel 上画画? :s
    • @你为什么不尝试解耦?我不想解耦这个。如何在不创建自定义 JPanel 的情况下从 JPanel 上的 JLayredPane 中绘图? :s
    • 那你应该三思而后行面向对象编程,为什么要在自己之外实现对象的自定义绘制呢?这毫无意义.. 你会用 5 个不同的面板做什么?存储他们所有的图形对象并在分层窗格的paintComponent上绘制?
    • 我也打算建议在内面板中绘制矩形,但你也打败了我。 +1。
    【解决方案2】:

    变量 g2 可能为 null,因为您在构造函数中设置了它,而不是在绘制时设置。而是使用传入的“g”。

    您只能从当前正在绘制的组件中获取合法的 Graphics。否则,它是无效的。在您提出请求时,未显示 MyCustomPanel(),测试窗格也未显示。

    【讨论】:

    • 但是 g 来自 JLayeredPane 而不是来自 JPanel。我需要在我的 JFrame 上绘制那个矩形,所以我需要来自那个 JFrame 的图形,而不是来自我的 JLayeredPane 的 g(图形):s
    • @jufo,您只能从当前正在绘制的组件中获取合法的图形。否则,它是无效的。在您请求它时,未显示 MyCustomPanel(),也未显示 testpane。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-21
    • 1970-01-01
    相关资源
    最近更新 更多