【问题标题】:New Thread out of GUIGUI 中的新线程
【发布时间】:2018-05-11 12:40:02
【问题描述】:

我想用开始按钮在我的 Caller 类中开始一个无限循环,并在我的 gui 类中用停止按钮停止它。我的问题是我认为我需要一个用于无限循环的新线程。而且我不知道如何在我的代码中实现它。请给我一些专家提示。我希望清楚我想知道什么以及我的问题是什么。

我的 GUI 类:

public class GUI implements ActionListener {

JFrame frame;
JPanel panel;
JButton numberBtn;
JLabel actNumberLabel;
JLabel entryNumber;
JButton startBtn;
JButton stopBtn;
static GUI ui;
private boolean run = false;

private String adminTelNumber = "006123456";
private JTextField textEntryNumber;

public GUI() {
    frame = new JFrame("Caller GUI");
    frame.getContentPane().setLayout(null);
    frame.setPreferredSize(new Dimension(400,300));
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel panel_1 = new JPanel();
    panel_1.setBounds(0, 0, 434, 70);
    frame.getContentPane().add(panel_1);
    panel_1.setLayout(null);

    startBtn = new JButton("Start");
    startBtn.setBounds(274, 11, 89, 23);
    startBtn.addActionListener(this);
    panel_1.add(startBtn);

    stopBtn = new JButton("Stop");
    stopBtn.setBounds(274, 36, 89, 23);
    stopBtn.addActionListener(this);
    panel_1.add(stopBtn);

    JPanel panel_2 = new JPanel();
    panel_2.setBounds(0, 70, 434, 120);
    frame.getContentPane().add(panel_2);
    panel_2.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));

    JPanel panel_3 = new JPanel();
    panel_3.setBounds(0, 190, 434, 71);
    frame.getContentPane().add(panel_3);
    panel_3.setLayout(null);

    JLabel entryNumber = new JLabel("Telefonnummer eingeben:");
    entryNumber.setBounds(10, 11, 183, 14);
    panel_3.add(entryNumber);

    textEntryNumber = new JTextField();
    textEntryNumber.setBounds(10, 25, 112, 20);
    panel_3.add(textEntryNumber);
    textEntryNumber.setColumns(10);

    numberBtn = new JButton("Übernehmen");
    numberBtn.setBounds(132, 24, 107, 23);
    numberBtn.addActionListener(this);
    panel_3.add(numberBtn);

    actNumberLabel = new JLabel("Derzeitige Signalisierung auf: " + adminTelNumber);
    actNumberLabel.setBounds(10, 46, 369, 14);
    panel_3.add(actNumberLabel);

    frame.pack();
    frame.setVisible(true);
}

@Override
public synchronized void actionPerformed(ActionEvent e) {
    if(e.getSource() == numberBtn){
        adminTelNumber = textEntryNumber.getText();
        actNumberLabel.setText("Derzeitige Signalisierung auf: " + adminTelNumber);
        textEntryNumber.setText("");
    }   
    if(e.getSource() == startBtn) {
        run = true;
        Caller.call(ui, 90000, 45);
    }
    if(e.getSource() == stopBtn) {
        run = false;
    }
}

public synchronized String getAdminTelNumber() {
    return adminTelNumber;
}

public synchronized boolean getRun() {
    return run;
}

public static void main(String[] args) {

    try {
        ui = new GUI();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
}

还有我的无限循环课:

public class Caller {

static String number = null;

public static void call(GUI ui, int sleepTime, int standardLeadTime) {
    ArrayList<Integer> alarmTaskIdList = new ArrayList<Integer>();
    ArrayList<Integer> doneTasksList = new ArrayList<Integer>();
    ArrayList<Integer> doneAlarmTasksList = new ArrayList<Integer>();
    ArrayList<Integer> taskIdList = new ArrayList<Integer>();

    while (ui.getRun()) {

        doneTasksList = wakeUpCall(taskIdList, doneTasksList, standardLeadTime);
        doneAlarmTasksList = alarmCall(alarmTaskIdList, doneAlarmTasksList, ui);

        try {
            Thread.sleep(sleepTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }           
    }
}

【问题讨论】:

标签: java multithreading swing user-interface


【解决方案1】:

对于长时间运行的任务,请使用SwingWorker,如下所示(注意 cmets):

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; 
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingWorker;

public class GUI implements ActionListener {

    private JButton startBtn, stopBtn;
    private Caller caller;

    public GUI() {

        JFrame frame = new JFrame("Caller GUI");
        frame.setPreferredSize(new Dimension(400,300));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel_1 = new JPanel();
        startBtn = new JButton("Start");
        startBtn.addActionListener(this);
        panel_1.add(startBtn);

        stopBtn = new JButton("Stop");
        stopBtn.addActionListener(this);
        stopBtn.setEnabled(false);
        panel_1.add(stopBtn);
        frame.add(panel_1);
        frame.pack();
        frame.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        if(e.getSource() == startBtn) {
            caller = new Caller(); //create swing worker 
            caller.execute(); // run it 
            stopBtn.setEnabled(true); //disable, enable buttons 
            startBtn.setEnabled(false);
        }
        if(e.getSource() == stopBtn) {
            caller.stop();
            stopBtn.setEnabled(false);
            startBtn.setEnabled(true);
        }
    }

    public static void main(String[] args) {

        new GUI();
    }
}

class Caller extends SwingWorker<Void, Void>{

    private int counter = 0;
    private boolean isStoped = false;

    void stop() {isStoped = true; }

    @Override
    protected Void doInBackground() throws Exception {

        while (! isStoped ) {
            System.out.println(counter ++); //just print values 
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {   e.printStackTrace(); }
        }
        return null;
    }
}

使用SwingWorker 的主要好处是:
-您的 gui 仍然响应(EDT 上的长时间运行的任务,阻止它)
-您可以从SwingWorker 获得中间结果(从中获取信息并在您的 gui 中使用它)
请注意,SwingWorker 的每个实例只能运行一次,因此不能“重新启动”。如代码所示,您必须创建新实例。

【讨论】:

  • 还有一个问题...如何从 gui 获取数据?例如,Swingworker 当前正在运行一个想要从 gui 访问新更改的请求。在我的示例中,您可以更改 adminTelNumber,并且正在运行的线程应该访问当前号码。
  • 您可以简单地在Caller 中使用setter 并使用它:caller.setadminTelNumber(287234); 如需更多帮助/问题,请使用新帖子,并在此处发表评论(因此会收到一条消息并与之相关)
猜你喜欢
  • 2017-02-27
  • 2013-07-12
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-29
相关资源
最近更新 更多