EDT местоположение с несколькими окнами JFrame
У меня есть Swing JFrame. Если я создам новый JFrame в новом потоке во время выполнения программы, где будет EDT? В текущем потоке последнего окна JFrame или в первом окне.
РЕДАКТИРОВАТЬ: Спасибо за ваши ответы.
Я понимаю их, и я в порядке с ними. Я знаю, что мы не должны создавать объект свинга в другом месте, где есть EDT, но я столкнулся с проблемой.
Я объясняю; Я разработал JAVA-приложение для создания и распаковки архива, как winrar. Вы можете создать несколько архивов одновременно с многопоточностью. А недавно я хотел добавлять информацию о статусе при создании архива в виде JprogressBar в новый JFrame при каждом создании. Но моя проблема заключается в создании связи в новом фрейме состояния и в потоке, который создает архив. Вот почему я создаю JFrame в ветке архива для обновления индикатора выполнения в настоящее время.
Но, как я мог бы прочитать в источниках информации о дайверах и в ваших ответах / комментариях, это противоречит Java-производительности и производительности; Я не могу создать объект свинга в другом месте, что EDT.
Но как мне решить мою проблему?
3 ответа
EDT - поток диспетчеризации событий - отделен от любого конкретного компонента GUI, такого как JFrame.
Как правило, вы должны создавать все компоненты GUI в EDT, но это не означает, что они владеют EDT, а также EDT не владеет компонентами.
Чтобы создать два JFrames, оба на EDT, вы можете сделать следующее:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame1 = new JFrame("Frame 1");
frame1.getContentPane().add(new JLabel("Hello in frame 1"));
frame1.pack();
frame1.setLocation(100, 100);
frame1.setVisible(true);
}
});
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame2 = new JFrame("Frame 2");
frame2.getContentPane().add(new JLabel("Hello in frame 2"));
frame2.pack();
frame2.setLocation(200, 200);
frame2.setVisible(true);
}
});
}
Поток отправки событий исправлен. Он не переназначается только потому, что вы создали объект Swing в другом потоке (что вам никогда не следует делать).
Это должно быть очень просто, если все события все выполнены в текущем EDT, то EDT не существует, можно указать другую очередь,
- от слушателей свинга,
- набрав код, завернутый в
invokeLater / invokeAndWait
, - но самым безопасным (и лучшим для меня) будет javax.swing.Action
выход
run:
Time at : 19:35:21
There isn't Live EventQueue.isDispatchThread, why any reason for that
There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that
Time at : 19:35:21
Calling from EventQueue.isDispatchThread
Calling from SwingUtilities.isEventDispatchThread
Time at : 19:35:21
Calling from EventQueue.isDispatchThread
Calling from SwingUtilities.isEventDispatchThread
Time at : 19:35:51
There isn't Live EventQueue.isDispatchThread, why any reason for that
There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that
Time at : 19:36:21
There isn't Live EventQueue.isDispatchThread, why any reason for that
There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that
Time at : 19:36:51
There isn't Live EventQueue.isDispatchThread, why any reason for that
There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that
Time at : 19:37:21
There isn't Live EventQueue.isDispatchThread, why any reason for that
There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that
BUILD SUCCESSFUL (total time: 2 minutes 17 seconds)
из кода:
import java.awt.EventQueue;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.*;
import javax.swing.*;
public class IsThereEDT {
private ScheduledExecutorService scheduler;
private AccurateScheduledRunnable periodic;
private ScheduledFuture<?> periodicMonitor;
private int taskPeriod = 30;
private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
private Date dateRun;
public IsThereEDT() {
scheduler = Executors.newSingleThreadScheduledExecutor();
periodic = new AccurateScheduledRunnable() {
private final int ALLOWED_TARDINESS = 200;
private int countRun = 0;
private int countCalled = 0;
@Override
public void run() {
countCalled++;
if (this.getExecutionTime() < ALLOWED_TARDINESS) {
countRun++;
isThereReallyEDT(); // non on EDT
}
}
};
periodicMonitor = scheduler.scheduleAtFixedRate(periodic, 0, taskPeriod, TimeUnit.SECONDS);
periodic.setThreadMonitor(periodicMonitor);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
isThereReallyEDT();
JFrame frame1 = new JFrame("Frame 1");
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.getContentPane().add(new JLabel("Hello in frame 1"));
frame1.pack();
frame1.setLocation(100, 100);
frame1.setVisible(true);
}
});
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame2 = new JFrame("Frame 2");
frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame2.getContentPane().add(new JLabel("Hello in frame 2"));
frame2.pack();
frame2.setLocation(200, 200);
frame2.setVisible(true);
isThereReallyEDT();
}
});
}
private void isThereReallyEDT() {
dateRun = new java.util.Date();
System.out.println(" Time at : " + sdf.format(dateRun));
if (EventQueue.isDispatchThread()) {
System.out.println("Calling from EventQueue.isDispatchThread");
} else {
System.out.println("There isn't Live EventQueue.isDispatchThread, why any reason for that ");
}
if (SwingUtilities.isEventDispatchThread()) {
System.out.println("Calling from SwingUtilities.isEventDispatchThread");
} else {
System.out.println("There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that ");
}
System.out.println();
}
public static void main(String[] args) {
IsThereEDT isdt = new IsThereEDT();
}
}
abstract class AccurateScheduledRunnable implements Runnable {
private ScheduledFuture<?> thisThreadsMonitor;
public void setThreadMonitor(ScheduledFuture<?> monitor) {
this.thisThreadsMonitor = monitor;
}
protected long getExecutionTime() {
long delay = -1 * thisThreadsMonitor.getDelay(TimeUnit.MILLISECONDS);
return delay;
}
}