简体   繁体   English

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

[英]Why does as the JPanel class object be created, the paintComponent method is automatically called?

This is the java code about JPanel : 这是关于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);
    }       
}

As I set up the GUI: 在设置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);

I found that the creation of Battle_field() object above will call the paintComponent automatically. 我发现上面的Battle_field()对象的创建将自动调用paintComponent

But here, I didn't initialize the variable "pics_to_be_drawn" yet,so if it is called, it would cause compiler error. 但是在这里,我还没有初始化变量“ pics_to_be_drawn” ,所以如果调用它,将会导致编译器错误。 Is this design unavoidable? 这种设计是不可避免的吗?
As you do so, it's necessary to happen? 当您这样做时,有必要发生吗? I wanna know this very much and of course the solution. 我非常想知道这一点,当然也知道解决方案。

ps: According to the official document,only if I call repaint() , it will call paintComponent() . ps:根据官方文档,仅当我调用repaint() ,它才会调用paintComponent() So I can write my customized code within paintComponent . 因此,我可以在paintComponent编写我的自定义代码。

Realize that you do not have control over when or if paint(...) or paintComponent(...) are called, that repaint() only suggests the repaint manager that the component should be painted, but that this doesn't always happen, that painting will occur as soon as the component is rendered , and then accept this and gear your code to work around this. 意识到您无法控制何时或是否调用paint(...)paintComponent(...) ,因此repaint()仅建议重新绘制管理器应绘制该组件,但这并不总是如此发生这种情况时,将在渲染组件后立即进行绘画,然后接受它并调整您的代码以解决此问题。 Consider: 考虑:

  • Initialize pics_to_be_drawn to null (so you initialize it to something) 将pics_to_be_drawn初始化为null(因此将其初始化为某种东西)
  • Then check that it's not null before drawing it. 然后在绘制之前检查它是否不为null。

Change this: 更改此:

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

to this: 对此:

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

Simple 简单

Swing calls the paintComponent() method when the panel must be painted. 当必须绘制面板时,Swing调用paintComponent()方法。 I don't think it will call it until the panel is made visible. 我认为在面板可见之前不会调用它。

That said, your panel should be in a paintable state as soon as it's added to the GUI. 就是说,一旦将面板添加到GUI,它就应该处于可绘制状态。 So the paintComponent() method should handle the case where the pictures have not been added yet, by simply checking that the list if not null (and not empty): 因此, paintComponent()方法应该处理尚未添加图片的情况,只需检查列表是否不为null(并且不为空)即可:

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

Side note: I would initialize the list to Collections.emptyList() or to new ArrayList<>() , which would avoid the check for null. 旁注:我会将列表初始化为Collections.emptyList()new ArrayList<>() ,这将避免检查null。 I would also respect the Java naming conventions: no underscore in class and variable names, camelCasing. 我还要遵守Java的命名约定:在类和变量名下没有下划线,camelCasing。

Jpanel's paintComponent is automatically called when a window becomes visible (uncovered or deminimized) or is resized. 当窗口变为可见(未覆盖或最小化)或调整大小时,将自动调用Jpanel的paintComponent。 Here's some more info about when paintComponent can be called. 这是有关何时可以调用paintComponent的更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM