Swing は単一のスレッドを使用してイベントをディスパッチし、再描画要求を処理します。このスレッドをブロックすると、EDT によるこれらの再描画要求の処理が停止され、UI が「停止」したように見えます。
代わりに、 a のようなものを使用しjavax.swing.Timer
て遅延を挿入し、アクションを実行します。これにより、EDT 内でアクションが実行されますが、バックグラウンド スレッドで待機します。
詳細については、 The Event Dispatching Threadをお読みください...
タイマーの例で更新
public class SlowDecline {
public static void main(String[] args) {
new SlowDecline();
}
private TestPane last;
public SlowDecline() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
TestPane parent = new TestPane(Color.RED);
TestPane tp = add(parent, Color.BLUE);
tp = add(tp, Color.GREEN);
tp = add(tp, Color.CYAN);
tp = add(tp, Color.LIGHT_GRAY);
tp = add(tp, Color.MAGENTA);
tp = add(tp, Color.ORANGE);
tp = add(tp, Color.PINK);
last = tp;
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(parent);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Timer timer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (last != null) {
Container parent = last.getParent();
if (parent != null) {
parent.remove(last);
parent.repaint();
if (parent instanceof TestPane) {
last = (TestPane) parent;
}
} else {
last = null;
}
} else {
(((Timer)e.getSource())).stop();
}
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
});
}
public TestPane add(TestPane parent, Color color) {
TestPane child = new TestPane(color);
parent.add(child);
return child;
}
public class TestPane extends JPanel {
public TestPane(Color background) {
setLayout(new BorderLayout());
setBorder(new EmptyBorder(10, 10, 10, 10));
setBackground(background);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(50, 50);
}
}
}