Нет проблем с зависанием GUI, хотя мы обновляем GUI компоненты из другого потока - PullRequest
0 голосов
/ 13 февраля 2020

В рамках изучения SwingWorker на Java swing я создал простую программу, в которой другой поток (отличный от EDT) выполняет некоторую фоновую задачу, и после этого поток обновляет компонент GUI (JTextArea).

Как я понимаю, если мы попытаемся обновить GUI компоненты из внешнего потока, отличного от EDT, пользовательский интерфейс может зависнуть. Но этого не происходит. Я действительно хотел бы создать эту ситуацию (Freeze UI), чтобы лучше ее понять. Ниже мой код, который я попробовал. Может ли кто-нибудь помочь мне сказать, что мне нужно сделать с моим кодом, чтобы пользовательский интерфейс зависал.

Приложение. java

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class App {

    public static void main(String[] args) {


        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new MainFrame();
            }
        }); 

    }

}

MainFrame. java

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class MainFrame extends JFrame implements ActionListener {

    private JButton btn,btn2;
    private JTextArea txtArea;

    public MainFrame() {
        super("Hello World");

        setLayout(new BorderLayout());
        btn = new JButton("Click Me!");
        btn2 = new JButton("Click Me New!");
        txtArea = new JTextArea();
        btn.addActionListener(this);


        add(txtArea,BorderLayout.CENTER);
        add(btn,BorderLayout.SOUTH);
        add(btn2,BorderLayout.NORTH);

        setSize(600,800);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {

        MyTestThread extThr = new MyTestThread();
        extThr.setBtnRef(txtArea);
        extThr.start();
    }

}

MyTestThread. java

import javax.swing.JTextArea;

public class MyTestThread extends Thread {

    private int i = 0;
    private JTextArea txtAreaRef;

    public void setBtnRef(JTextArea ta) {
        this.txtAreaRef = ta;
    }

    public void run() {

        while (i < 500000) {

            try {
                txtAreaRef.append("test"+i+"\n");
                i=i+1;
                sleep(2000);
            } catch (InterruptedException e) {System.out.println(e.getMessage());
                e.printStackTrace();
            }
        }

    }

}

1 Ответ

0 голосов
/ 13 февраля 2020

Я понятия не имею, откуда вы получили эту информацию, но вызов GUI обновлений вне EDT не приводит к зависанию интерфейса.

Если вы хотите произвести остановку, попробуйте сделать бесконечное l oop внутри EDT, вот так.

Это приведет к постоянному зависанию пользовательского интерфейса.

    public void actionPerformed(ActionEvent e) {

            //MyTestThread extThr = new MyTestThread();
            //extThr.setBtnRef(txtArea);
            //extThr.start();

            while(true) {}
    }
...