为什么将布局设置为 BorderLayout 意味着永远不会调用 PaintComponent
在下面的示例程序中,如果将 useBorderlayout 设置为 true,则永远不会调用 PaintComponent 方法 - 为什么?!
import javax.swing.*;
import java.awt.*;
public class PaintComponentTest extends JPanel {
private final boolean useBorderLayout;
public PaintComponentTest(boolean useBorderLayout){
this.useBorderLayout = useBorderLayout;
initialiseComponents();
}
public void initialiseComponents(){
setOpaque(true);
setBackground(Color.RED);
if(useBorderLayout){
//this appears to be the offending line:
setLayout(new BorderLayout());
}
final JPanel panel = new JPanel();
panel.setOpaque(true);
panel.setBackground(Color.GREEN);
add(panel, BorderLayout.CENTER);
}
@Override
public void paintComponent(Graphics g){
System.out.println("PaintComponentTest.paintComponent");
super.paintComponent(g);
}
public static void main(String [] args){
final boolean useBorderLayout = (args.length == 1 && Boolean.parseBoolean(args[0]));
System.out.println("Running with"+(useBorderLayout?"":"out")+" BorderLayout as layout manager...");
SwingUtilities.invokeLater(new Runnable(){
public void run(){
final JFrame frame = new JFrame("BorderLayout/PaintComponent test");
frame.setPreferredSize(new Dimension(200, 200));
frame.getContentPane().setLayout(new BorderLayout());
final PaintComponentTest componentTest = new PaintComponentTest(useBorderLayout);
frame.getContentPane().add(componentTest);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
In the following example program, if you set useBorderlayout to true, the paintComponent method is never called - why?!
import javax.swing.*;
import java.awt.*;
public class PaintComponentTest extends JPanel {
private final boolean useBorderLayout;
public PaintComponentTest(boolean useBorderLayout){
this.useBorderLayout = useBorderLayout;
initialiseComponents();
}
public void initialiseComponents(){
setOpaque(true);
setBackground(Color.RED);
if(useBorderLayout){
//this appears to be the offending line:
setLayout(new BorderLayout());
}
final JPanel panel = new JPanel();
panel.setOpaque(true);
panel.setBackground(Color.GREEN);
add(panel, BorderLayout.CENTER);
}
@Override
public void paintComponent(Graphics g){
System.out.println("PaintComponentTest.paintComponent");
super.paintComponent(g);
}
public static void main(String [] args){
final boolean useBorderLayout = (args.length == 1 && Boolean.parseBoolean(args[0]));
System.out.println("Running with"+(useBorderLayout?"":"out")+" BorderLayout as layout manager...");
SwingUtilities.invokeLater(new Runnable(){
public void run(){
final JFrame frame = new JFrame("BorderLayout/PaintComponent test");
frame.setPreferredSize(new Dimension(200, 200));
frame.getContentPane().setLayout(new BorderLayout());
final PaintComponentTest componentTest = new PaintComponentTest(useBorderLayout);
frame.getContentPane().add(componentTest);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
因为它不需要。 PaintComponentTest 类是一个 JPanel,它有一个绿色的 JPanel 作为内容。设置了 BorderLayout 后,绿色面板会占据面板中的所有空间,并且不需要 PaintComponent 方法。
将此方法添加到您的代码中,您应该会看到它发生:
Because it doesn't need to. The PaintComponentTest class is a JPanel that has one green JPanel as content. When the BorderLayout is set, the green panel takes up all the space in panel and the PaintComponent method is not needed.
Add this method to your code and you should see it happen:
因为嵌套面板覆盖了所有组件。损坏的区域(要重新绘制)已传递给子级,因为子级边界覆盖了所有损坏的区域。
Because the nested panel covers all the component. Damaged region (to be repainted) is past to the children because the child bounds cover all the damaged region.