代码之家  ›  专栏  ›  技术社区  ›  D.Schall

GUI的新线程

  •  1
  • D.Schall  · 技术社区  · 6 年前

    我想用一个start按钮在Caller类中启动一个无休止的循环,并用gui类中的stop按钮停止它。我的问题是,我想我需要一个新的线程来实现无休止的循环。我不知道如何在代码中实现它。请给我一些专家提示。我希望清楚我想知道什么,我的问题是什么。

    我的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();
            }           
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   c0der    6 年前

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

    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 ,阻止它)
    -您可以从 摇摆工人 (从中获取信息并在gui中使用)
    请注意 摇摆工人 只能运行一次,因此不能“重启”。正如代码所示,您必须创建新实例。