为 javax 重绘不起作用

repaint for javax not work

这是我的代码:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

public class Main {
// code main
public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setSize(460, 500);
    frame.setTitle("Circles generator");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            frame.setVisible(true);

        }

    });

    String input = JOptionPane.showInputDialog("Enter n:");
    CustomComponents0 component = new CustomComponents0();
    frame.add(component);
    frame.getContentPane().validate();
        System.out.println("work before");
    frame.getContentPane().repaint();
        System.out.println("work");

    frame.getContentPane().repaint();
        System.out.println("work after");

}

// why is not JComponent
static class CustomComponents0 extends JLabel {

    private static final long serialVersionUID = 1L;

    @Override
    public Dimension getMinimumSize() {
        return new Dimension(200, 100);

    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(300, 200);

    }

    @Override
    public void paintComponent(Graphics g) {
        System.out.println("paint");
        int margin = 10;
        Dimension dim = getSize();
        super.paintComponent(g);
        g.setColor(Color.red);
        g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2);

    }

}

这是代码,我希望 运行 在工作前重绘,运行 在工作后重绘。 当我 运行 它时,它应该打印

work before
paint
work
paint
work after

但是只有一张油漆,而且是下班后,为什么会这样?我该如何解决?

谢谢。

must construct and manipulate Swing GUI objects only on the event dispatch thread. Because your program is incorrectly synchronized, any result is possible. It will depend in part on how far the initial thread gets before starting the EventQueue. Moreover, println() itself may be synchronized,和"events being posted to the EventQueue can be coalesced."

下面的变体可靠地显示了以下输出,因为事件已分派 "In the same order as they are enqueued." 请特别注意如何合并对 repaint() 的调用。虽然此方法是说明性的,但对于您的可能目标而言,它是不必要的麻烦。相反,使用 javax.swing.Timer to pace animation as shown here.

控制台:

paint
work before
work
work after
paint

代码:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JLabel;

/** @see  */
public class Main {

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            JFrame frame = new JFrame();
            frame.setTitle("Circles generator");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            CustomComponent component = new CustomComponent();
            frame.add(component);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
            EventQueue.invokeLater(() -> { System.out.println("work before"); });
            EventQueue.invokeLater(() -> { frame.repaint(); });
            EventQueue.invokeLater(() -> { System.out.println("work"); });
            EventQueue.invokeLater(() -> { frame.repaint(); });
            EventQueue.invokeLater(() -> { System.out.println("work after"); });
        });
    }

    static class CustomComponent extends JLabel {

        private static final int N = 10;

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(300, 200);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            System.out.println("paint");
            g.setColor(Color.red);
            g.fillRect(N, N, getWidth() - N * 2, getHeight() - N * 2);
        }
    }
}