Почему я должен установить положение моей JLabel на каждом компоненте краски? - PullRequest
0 голосов
/ 07 октября 2019

Я хочу использовать 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?

1 Ответ

2 голосов
/ 07 октября 2019

почему я должен устанавливать местоположение на каждом перекрашивании.

Вы не делаете. На самом деле, вы никогда не должны устанавливать позицию или какие-либо ограничения компонента внутри метода paintComponent. paintComponent метод предназначен только для рисования, но не для ориентации или чего-либо еще.

Когда положение jpanel.add(myComponent, constraints) компонента будет определяться текущим контейнером LayoutManager . (Когда вы jpanel.add(myComponent); без каких-либо ограничений, будут иметь место ограничения по умолчанию, при этом у каждого менеджера макета будет свой собственный стандарт).

Метка размещается в верхней части панели, поскольку вы не задаете макетпанели, поэтому она имеет значение по умолчанию, FlowLayout. . Чтобы изменить его, вам нужно будет использовать другой менеджер компоновки с соответствующими ограничениями.

Например, чтобыпоместите его в центр панели, вы должны сделать:

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

Наконец, сделав while(true) внутри потока, в котором работает ваш графический интерфейс, он повесит поток, это означает, что графический интерфейс будет «заморожен». "поскольку события не могут иметь место.

...