Медленная отрисовка модальных диалогов после установки центра экрана в Java Swing.JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Медленная отрисовка модальных диалогов после установки центра экрана в Java Swing.

Сообщение Anonymous »

Я работаю над Java-приложением, которое позволяет пользователям детализировать элементы в диалоговом окне, выводить одно модальное диалоговое окно поверх другого и размещать его по центру экрана.
Если я быстро углубляюсь, нажимая Enter, к тому времени, когда я доберусь до третьего диалогового окна, отрисовка диалогового окна займет целую вечность, иногда секунду или больше.
Нарушающий код, похоже, центрирование экрана, что я делаю следующим образом:

Код: Выделить всё

setLocationRelativeTo(null);
Если я закомментирую эту строку, диалоговые окна отрисуются мгновенно. Это также произойдет мгновенно, если я задам местоположение следующим образом:

Код: Выделить всё

setLocation(300,400);
Что происходит? Есть ли способ обойти эту задержку?
Ниже приведен пример кода. Примечание. Я записываю момент нажатия Enter, а также время между нажатием этой клавиши и моментом отображения следующего диалогового окна (и его JTextField получает фокус). Интересно, что в выводе консоли вы можете увидеть задержку между обнаружениями нажатия клавиш, но не время, необходимое для отображения или получения фокуса.
Код:

Код: Выделить всё

import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class DialogTestFrame1 extends JFrame {

public DialogTestFrame1() {
super("Screen Center Demo");
setSize(400, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// Create a JPanel with a JTextField in it
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JTextField textField = new JTextField(20);
final DialogTestFrame1 frame = this;
textField.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent evt) {
if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
long start = System.currentTimeMillis();
System.out.println(toTOD(start) + " Enter key pressed");
evt.consume();
DialogTestDialog1 d = new DialogTestDialog1(frame);
showDialog(d, 1, start);
}
}
});
panel.add(textField);
add(panel);

// Center the dialog
setLocationRelativeTo(null);
}

public class DialogTestDialog1 extends JDialog {

public DialogTestDialog1(Frame parent) {
super(parent, true);
}
}

public class DialogTestDialog2 extends JDialog {

public DialogTestDialog2(JDialog parent) {
super(parent, true);
}
}

public class DialogTestDialog3 extends JDialog {

public DialogTestDialog3(JDialog parent) {
super(parent, true);
}
}

public void showDialog(JDialog dlg, int level, long start) {
// Create a 400x200 dialog
dlg.setSize(900, 500);
dlg.setTitle("Level " + level);

// Create JPanel and text field
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JTextField textField = new JTextField(20);

// Create JButton and add textfield
// Listen for Escape and Enter
textField.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent evt) {
long start = System.currentTimeMillis();
if (evt.getKeyCode() == KeyEvent.VK_ESCAPE) {
dlg.dispose();
} else if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
System.out.println(toTOD(start) + " Enter key pressed");
switch (level) {
case 1 -> {
evt.consume();
DialogTestDialog2 d = new DialogTestDialog2(dlg);
showDialog(d, 2, start);
}
case 2 -> {
evt.consume();
DialogTestDialog3 d = new DialogTestDialog3(dlg);
showDialog(d, 3, start);
}
case 3 -> {
}
}
}
}
});

// Listen for when it gets focus
textField.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
System.out.printf(toTOD(System.currentTimeMillis()) + "  Dialog %d focus gained in %d milliseconds\n", level, (System.currentTimeMillis() - start));
}
});
panel.add(textField);
dlg.add(panel);

// Listen for dialog opening/showing
dlg.addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent e) {
System.out.printf("Dialog %d opened in %d milliseconds\n", level, (System.currentTimeMillis() - start));
}
});
dlg.addComponentListener(new ComponentAdapter() {
@Override
public void componentShown(ComponentEvent e) {
System.out.printf("Dialog %d shown in %d milliseconds\n", level, (System.currentTimeMillis() - start));
}
});

// Set to screen centert
dlg.setLocationRelativeTo(null);
dlg.setVisible(true);
}

public static void main(String[] args) {
(new DialogTestFrame1()).setVisible(true);
}

public static String toTOD(long milliseconds) {
Instant instant = Instant.ofEpochMilli(milliseconds);
ZoneId zoneId = ZoneId.systemDefault();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss:SSS a", Locale.US);
return instant.atZone(zoneId).format(formatter);
}
}
И вывод на консоль:

Код: Выделить всё

10:41:54:260 AM Enter key pressed
Dialog 1 shown in 248 milliseconds
Dialog 1 opened in 250 milliseconds
10:41:54:514 AM Dialog 1 focus gained in 254 milliseconds
10:41:56:607 AM Enter key pressed
Dialog 2 shown in 52 milliseconds
Dialog 2 opened in 53 milliseconds
10:41:56:664 AM Dialog 2 focus gained in 57 milliseconds
10:41:56:665 AM Enter key pressed
Dialog 3 shown in 55 milliseconds
Dialog 3 opened in 56 milliseconds
10:41:56:724 AM Dialog 3 focus gained in 59 milliseconds
Еще одно примечание: эти выходные данные взяты из JDK 21 на MacBook Pro с Tahoe 26.3. Я также видел такое поведение на мини-ПК с Win11. Но запуск этого конкретного примера (отрывка из более крупного проекта) на ПК не вызывает задержку. Другая ОС? Или разрешение экрана?


Подробнее здесь: https://stackoverflow.com/questions/798 ... -in-java-s
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»