为什么在创建JPanel类对象时,会自动调用paintComponent方法?

时间:2012-07-03 14:06:27

标签: java swing jpanel repaint paintcomponent

这是关于JPanel

的java代码
class Battle_field extends JPanel{
    public List<Image_Obj> pics_to_be_drawn;    

    @Override   
    public void paintComponent(Graphics g){     
            super.paintComponent(g);                 
            g.drawImage(pics_to_be_drawn.get(0).Get_the_buf_img() , 41, 41, 59, 59, Color.black, null);
    }       
}

当我设置GUI时:

added_panel= new Battle_field();
added_panel.setBorder(new LineBorder(SystemColor.activeCaption, 3));
added_panel.setBounds(27, 10, 397, 630);
added_panel.setBackground(Color.white);
this.getContentPane().add(added_panel);

我发现上面Battle_field()对象的创建会自动调用paintComponent

  

但是在这里,我还没有初始化变量“pics_to_be_drawn”,所以如果调用它,会导致编译错误。 这个设计是否不可避免?   
当你这样做时,有必要发生吗?   我非常想知道这一点,当然还有解决方案。

P.S: 根据官方文件,只有当我拨打repaint()时,它才会拨打paintComponent()。所以我可以在paintComponent内编写自定义代码。

3 个答案:

答案 0 :(得分:2)

意识到您无法控制何时或是否调用paint(...)paintComponent(...)repaint()仅建议重绘管理器应该绘制该组件,但这不是总是会发生这种情况,只要组件呈现就会出现这种情况,然后接受这种情况并调整代码以解决这个问题。考虑:

  • 将pics_to_be_drawn初始化为null(因此将其初始化为某些内容)
  • 然后在绘制之前检查它是否为空。

改变这个:

class Battle_field extends JPanel{
    public List<Image_Obj> pics_to_be_drawn;    

    @Override   
    public void paintComponent(Graphics g){     
            super.paintComponent(g);                 
            g.drawImage(pics_to_be_drawn.get(0).Get_the_buf_img() , 41, 41, 59, 59, Color.black, null);
    }       
}

到此:

class Battle_field extends JPanel{
    public List<Image_Obj> pics_to_be_drawn;    

    @Override   
    public void paintComponent(Graphics g){     
            super.paintComponent(g);          
            if (pics_to_be_drawn != null) { 
               g.drawImage(pics_to_be_drawn.get(0).Get_the_buf_img() , 41, 41, 59, 59, Color.black, null);
            }
    }       
}

简单

答案 1 :(得分:2)

当必须绘制面板时,Swing会调用paintComponent()方法。在面板可见之前,我认为它不会调用它。

也就是说,一旦将面板添加到GUI,您的面板就应该处于可绘制的状态。所以paintComponent()方法应该处理尚未添加图片的情况,只需检查列表是否为空(而不是空):

@Override   
public void paintComponent(Graphics g){     
    super.paintComponent(g);                 
    if (pics_to_be_drawn != null && !pics_to_be_drawn.isEmpty()) {
        g.drawImage(pics_to_be_drawn.get(0).Get_the_buf_img() , 41, 41, 59, 59, Color.black, null);
    }
}

旁注:我会将列表初始化为Collections.emptyList()new ArrayList<>(),这样可以避免检查空值。我还要尊重Java命名约定:类和变量名中没有下划线,camelCasing。

答案 2 :(得分:2)

当窗口变为可见(未覆盖或最小化)或调整大小时,将自动调用Jpanel的paintComponent。 Here's some more info about when paintComponent can be called.