为啥我必须在每个paintComponent 上设置我的JLabel 的位置?

Posted

技术标签:

【中文标题】为啥我必须在每个paintComponent 上设置我的JLabel 的位置?【英文标题】:Why do I have to set the position of my JLabel on every paintComponent?为什么我必须在每个paintComponent 上设置我的JLabel 的位置? 【发布时间】:2020-02-04 21:24:10 【问题描述】:

我想在一个非常简单的环境中使用 JLabel,但我想知道为什么我必须在每次重绘时设置位置。

代码:

public class Example 
    public static void main(String[] args) 
        JFrame frame = buildFrame();
        TestPane pane = new TestPane();

        frame.add(pane);

        while (true) 
            pane.repaint();
            frame.setVisible(true);
        
    

    private static JFrame buildFrame() 
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setSize(480, 272);
        frame.setVisible(true);
        return frame;
    


public class TestPane extends JPanel 
    JLabel testLabel = new JLabel("TEST");

    TestPane() 
        super();
        add(testLabel);
        testLabel.setLocation(200, 200);
    

    @Override
    protected void paintComponent(Graphics g) 
        super.paintComponent(g);
        testLabel.setLocation(200, 200); // without this line, the label will always be at the top center
    

基于循环的布局来自我正在做的各种带有图像的动画。为什么重绘总是重置所有标签的位置,所以我必须在每个paintComponent上设置位置?

【问题讨论】:

在 while 循环中不断重绘是个坏主意。也许您可以改用Timer。不太可能产生不必要的副作用。 JPanel 的默认布局管理器可能会覆盖您对JLabel 的显式定位。尝试在 JPanel 的构造函数中添加 setLayout(nulll) 【参考方案1】:

为什么我必须在每次重绘时设置位置。

你没有。实际上,您永远不应该在paintComponent 方法中设置组件的位置或任何类型的约束。 paintComponent 方法只用于绘画,不能用于定位或其他任何东西。

当你jpanel.add(myComponent, constraints) 时,组件的位置将由容器当前的LayoutManager 决定。 (当你jpanel.add(myComponent); 没有任何约束时,默认约束将发生,每个布局管理器都有自己的默认值)。

标签放置在面板的顶部,因为您没有设置面板的布局,所以它有它的默认值,即FlowLayout. 为了更改它,您必须使用另一个布局管理器与适当的约束。

例如,要将其放置在面板的中心,您必须这样做:

jpanel.setLayout(new BorderLayout());
jpanel.add(myLabel,BorderLayout.CENTER);

最后在运行 GUI 的线程内执行while(true),它将挂起线程,这意味着 GUI 将被“冻结”,因为事件无法发生。

【讨论】:

以上是关于为啥我必须在每个paintComponent 上设置我的JLabel 的位置?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 renderInContext 比绘制到屏幕慢得多?

JAVA、GUI JPanel、JFrame、paintComponent、图形

油漆组件是如何工作的?

为啥我必须费心在每个文件的末尾添加换行符?

永远不会调用paintComponent()

为啥我必须将每个 Thread.sleep() 调用包装在 try/catch 语句中? [复制]