일부 무거운 작업의 EDT 스레드를 해제하고 별도의 스레드에서 수행하면됩니다. 이 경우 GIF 애니메이션은 실행중인 다른 프로세스와 함께 작동합니다.
응용 프로그램 인터페이스를 표시 할 때까지는 별도의 스레드 (예 : EDT 내에 있지 않음)에 응용 프로그램 인터페이스를 만들 수도 있습니다. 이후 EDT 내에서 모든 변경 작업을 수행해야합니다. 그렇지 않으면 많은 문제가 발생할 수 있습니다.
나중에 별도의 스레드에서 더 많은 UI 요소를로드 할 수 있습니다. EDT 내부의 표시된 프레임/컨테이너에 추가해야합니다. 이것이 가장 중요한 요소입니다. 모든 인터페이스 업데이트 작업이 EDT에서 만들어진, 다른 모든 다른 스레드 내에서 실행 -
public static void main (String[] args) throws InvocationTargetException, InterruptedException
{
// Main window
final JFrame frame = new JFrame();
final JPanel panel = new JPanel (new FlowLayout (FlowLayout.LEFT, 5, 5))
{
public Dimension getPreferredSize()
{
Dimension ps = super.getPreferredSize();
ps.width = 0;
return ps;
}
};
frame.add (new JScrollPane (panel));
frame.setSize (600, 500);
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo (null);
SwingUtilities.invokeAndWait (new Runnable()
{
public void run()
{
frame.setVisible (true);
}
});
// Load dialog
final JDialog load = new JDialog (frame);
JPanel panel2 = new JPanel (new BorderLayout());
panel2.setBorder (BorderFactory.createEmptyBorder (15, 15, 15, 15));
load.add (panel2);
final JProgressBar progressBar = new JProgressBar (0, 100);
panel2.add (progressBar);
load.setModal (false);
load.pack();
load.setLocationRelativeTo (frame);
SwingUtilities.invokeAndWait (new Runnable()
{
public void run()
{
load.setVisible (true);
}
});
// Heavy task (takes approx. 10 seconds + some time on buttons creation)
for (int i = 0; i < 100; i++)
{
Thread.sleep (100);
final JButton button = new JButton ("Button" + i);
final int finalI = i;
// Updating panel and progress in EDT
SwingUtilities.invokeLater (new Runnable()
{
public void run()
{
panel.add (button);
button.revalidate();
progressBar.setValue (finalI);
}
});
}
}
당신이 볼 수 있듯이 :
여기에 "무거운 같은"인터페이스로드의 작은 예입니다.
또한 주 스레드는 EDT 스레드가 아니므로 즉시 무언가를 수행 할 수 있습니다.
경우에 따라 인터페이스의로드 된 부분을 바로 표시 할 필요가 없으므로 "무거운"작업이 끝나면 추가 할 수 있습니다. 그러면 로딩 시간이 절약되고 초기화 코드가 훨씬 간단 해집니다.
간단한 EDT에 대한 설명과 내가 대답했다
...
...그것은 Swing L & F와 많은 Swing 기반 응용 프로그램에서 3 년 근무한 후에 발견 한 무언가였습니다. 나는 많은 스윙 소스를 파고 널리 알려지지 않은 흥미로운 것들을 많이 발견했다.
아시다시피 - 인터페이스 업데이트 (스윙에서의 EDT)에 대한 단일 스레드의 전체 아이디어는 스레드 내에서 하나의 큐에 각각 별도의 구성 요소를 시각 업데이트 (및 이벤트)을 유지하고 그들에게 하나를 수행에 관한 것입니다 . 단일 프레임 안의 모든 구성 요소는 단일 이미지에 그려지기 때문에 페인트 문제를 피하기 위해 주로 필요합니다. 페인팅 순서가 엄격하므로 한 구성 요소가 최종 이미지에서 다른 구성 요소를 덮어 쓰지 않습니다. 페인팅 순서는 다른 컨테이너 안에 일부 구성 요소 또는 컨테이너를 추가하여 만든 구성 요소 트리에 따라 달라집니다 (Swing에서 응용 프로그램 인터페이스를 만들 때 수행하는 기본 작업).
요약하면 ED30 내에서 시각적 인 업데이트 (이를 일으킬 수있는 방법/작업)를 모두 유지해야합니다. 기타 이 EDT 외부에서 수행 될 수 있습니다. 예를 들어 EDT 외부에서 애플리케이션 인터페이스를 준비 할 수 있습니다 (예 : 이미 표시된 컨테이너 내부에서 구성 요소를 추가/제거/이동하지 않는 경우).
매우 드문 경우에도 여전히 내부 문제가있을 수 있습니다.
http://www.velocityreviews.com/forums/t707173-why-does-jdk-1-6-recommend-creating-swing-components-on-the-edt.html
은 짧게 : 오래 전에 여기 그 질문의 좋은 논의가 있었다 6 JDK 버전 일에도 구성 요소의 생성이 수 문제를 방지하기 위해 EDT 내부에서 수행되어야한다 스윙 문서에 명시된 때문이다. 구성 요소가 생성되는 동안 발생하는 이벤트로 인해 인터페이스가 많이 생성되는 특정 경우에 나타날 수 있습니다.
어쨌든 로더/응용 프로그램이 멈추지 않도록 EDT 외부에 인터페이스를 만들 수 있습니다. 응용 프로그램이 인터페이스 작성 시간에 걸리는 지 여부가 중요하지 않은 다른 경우에는 EDT를 사용해야합니다. 그리고 모든 것이 당신의 사건에 달려 있기 때문에 더 구체적으로 말할 수는 없습니다 ...
는 [시작 화면]의 사용을 고려 (http://docs.oracle.com/javase/tutorial/uiswing/misc/splashscreen.html)는 시동을위한 경우 대신 귀하의 응용 프로그램 – Robin