为什么必须在每个paintComponent上设置JLabel的位置?

问题描述 投票:0回答:1

我想在一个非常简单的环境中使用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上设置setLocation?

java swing awt java-2d
1个回答
2
投票

为什么我必须在每次重涂上设置位置。

你不知道。实际上,绝对不要在paintComponent方法内设置组件的位置或任何类型的约束。 paintComponent方法仅用于绘画,而不用于方向或其他任何方法。

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

标签位于面板顶部,因为您没有设置面板的布局,因此它具有默认值,即FlowLayout.。要更改它,您将不得不使用具有适当布局的另一个布局管理器。约束。

例如,为了将其放置在面板的中央,必须执行以下操作:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.