这是关于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",所以如果调用它,它会导致编译器错误。这种设计是不可避免的吗?
当你这样做时,有必要发生吗? 我非常想知道这一点,当然还有解决方案。
附言:根据官方文件,只有我打电话给repaint()
,它才会打电话给paintComponent()
。所以我可以在 paintComponent
内编写我的自定义代码。
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<>()
,这将避免检查 null。我也会尊重Java的命名约定:类和变量名中没有下划线,驼峰。
> 意识到您无法控制何时或是否调用paint(...)
或paintComponent(...)
,repaint()
仅建议重绘管理器应该绘制组件,但这并不总是发生,一旦渲染组件就会发生绘制,然后接受这一点并调整您的代码以解决此问题。考虑:
- 将pics_to_be_drawn初始化为 null(因此将其初始化为某些内容)
- 然后在绘制之前检查它是否不为 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);
}
}
}
简单
当窗口变得可见(未覆盖或最小化)或调整大小时,会自动调用 Jpanel 的 paintComponent。下面是有关何时可以调用 paintComponent 的更多信息。