Медленное Swing GUI время запуска - PullRequest
0 голосов
/ 01 октября 2019

Я изучаю Swing с Java и очень рано столкнулся с проблемой отображения моих компонентов в окне. Если я использую следующий код:

import javax.swing.*;

public class win extends JFrame {

    public static void main(String[] args) {

        new win();
    }

    public win(){

        this.setTitle("WIN");
        this.setSize(200,200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JLabel l = new JLabel("Label");

        this.add(l);

        this.setVisible(true);
    }
}

, мой ярлык не будет отображаться, пока я не изменю размер окна. Я искал другие вопросы, и некоторые из них предположили, что недостатком упаковки, повторной проверки, проверки и / или перекраски были виновники. Если я добавлю пакет к тому же коду:

import javax.swing.*;

public class win extends JFrame {

    public static void main(String[] args) {

        new win();
    }

    public win(){

        this.setTitle("WIN");
        this.setSize(200,200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JLabel l = new JLabel("Label");

        this.add(l);

        this.pack();

        this.setVisible(true);
    }
}

Мое окно займет около 10 секунд, чтобы отобразить

ОБНОВЛЕНИЕ:

Добавление моего кода в EDT, как предложено Frakcoolне работает.

Этот код также отображается после 10-секундной задержки. Я не думаю, что проблема в том, что мой компьютер работает медленно, это четырехъядерный 32-гигабайтный ОЗУ, работающий на High Sierra. В настоящее время я запускаю эти программы на Java 8.

ИСПОЛЬЗОВАНИЕ EDT:

Все считают, что неиспользование EDT является виновником, однако я пробовал его, и, похоже, это не так. проблема. Если с этим кодом что-то не так, EDT не является решением:

import javax.swing.*;


public class Window extends JFrame {

    public static void main(String[] args) throws Exception {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Window();
            }
        });

    }

    public Window(){

        this.setTitle("WINDOW");

        JLabel l = new JLabel("Label");

        this.add(l);

        this.pack();

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.setVisible(true);
    }
}

Я все еще получаю 10-секундный запуск только для этой метки, и то же самое с другими компонентами Swing.

ОБНОВЛЕНИЕ:

Проблема определенно не в коде (с или без EDT), так как я могу запустить этот код без задержки как в другой системе OSX (Mojave), так ина Ubuntu через Virtualbox на проблемной машине (High Sierra). Проблема должна быть связана с High Sierra или некоторыми настройками, установленными в моей персональной системе или на JVM

1 Ответ

0 голосов
/ 02 октября 2019

Все операции рисования в Swing должны выполняться в так называемой нити диспетчеризации событий (EDT). Передача экземпляра java.lang.Runnable с помощью метода run(), вызывающего эти операции рисования, в метод SwingUtilities.invokeLater() гарантирует выполнение этого кода в EDT. В противном случае проблемы возникнут в какой-то момент, например, так называемый «серый прямоугольник»: пользовательский интерфейс приложения кажется запаздывающим или даже ощущается как «замороженный». См. [[https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html]]

. Я бы изменил ваш код на это:

import javax.swing.*;

public class Win extends JFrame {

    Win() {
        super("WIN");
        setSize(200, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void main(String args[]) throws Exception {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new Win();
            JComponent label = new JLabel("Label");
            frame.getContentPane().add(label);
            frame.setVisible(true);
        });
    }
}
...