计时器操作仅在线程完成后执行

时间:2016-06-28 08:35:22

标签: java swing timer

enter image description here我有一个名为SpyBiteDemo的swing GUI,它将调用另一个类(Parser)并进行一些计算,并在此GUI(SpyBiteDemo)中的jtable中显示一些数据。我有一个jbutton1,我想点击它来显示我的计时器开始像1,2,3,4,5,......秒

我的计时器正在正常运行但是它没有显示值,除非它完成了填充jtable的所有程序,这意味着它检测到的动作是我在jtable出现后执行动作。

我是一个关于事件监听器的Java的完全新手,我已经搜索了计时器,计时器任务,计划,一切,并且无法理解什么是错误。我也尝试了(真实)并且没有解决它。我也尝试了1000,0的持续时间,一切都没有影响。

我尝试使用动作命令,睡眠线程,它没有帮助。我做了什么:

public class SpyBiteDemo extends javax.swing.JFrame {

    /**
     * Creates new form SpyBiteDemo
     */
    private long startTime;
    Timer timer = new Timer(0, new TimerListener());

    private class TimerListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent aEvt) {

            long time = (System.currentTimeMillis() - startTime) / 1000;
            label3.setText(time + " seconds");

        }
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
        // TODO add your handling code here:
        jButton1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                timer.start();
            }
        });
        startTime = evt.getWhen();
        String SeedUrl = jTextField1.getText();
        Parser P = new Parser(this);
        jTable2.setVisible(true);
    }
}

只有在我的jframe上填充jtable后才开始显示label3值。我希望定时器从我点击按钮时开始。

使用trashgod的链接我已经想出了这个可以在你的机器上运行的例子,这个工作非常完美,除了当程序结束时,它不会停止计时器,因为我不知道在哪里做,我知道我应该在addPropertyChangeListener中做,但是我没有定时器值。

    /*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package javaapplication7;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingWorker;
import javax.swing.Timer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

/**
 * @see http://stackoverflow.com/a/25526869/230513
 */
public class DisplayLog {

    private static final String NAME = "C:\\wamp\\bin\\mysql\\mysql5.6.17\\bin\\scosche.sql";

    private static class LogWorker extends SwingWorker<TableModel, String> {

        private final File file;
        private final DefaultTableModel model;

        private LogWorker(File file, DefaultTableModel model) {
            this.file = file;
            this.model = model;
            model.setColumnIdentifiers(new Object[]{file.getAbsolutePath()});
        }

        @Override
        protected TableModel doInBackground() throws Exception {
            BufferedReader br = new BufferedReader(new FileReader(file));
            String s;
            while ((s = br.readLine()) != null) {
                publish(s);
            }
            return model;
        }

        @Override
        protected void process(List<String> chunks) {
            for (String s : chunks) {
                model.addRow(new Object[]{s});
            }
        }

        @Override
    protected void done() {}

    }

    private void display() {
        JFrame f = new JFrame("DisplayLog");
        JLabel m=new JLabel("time");
        JButton jb=new JButton("run");
        f.add(jb,BorderLayout.BEFORE_FIRST_LINE);
                f.add(m, BorderLayout.SOUTH);
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                DefaultTableModel model = new DefaultTableModel();
                JTable table = new JTable(model);
                JProgressBar jpb = new JProgressBar();
                f.add(jpb, BorderLayout.NORTH);
                f.add(new JScrollPane(table));
                f.pack();
                f.setLocationRelativeTo(null);
                f.setVisible(true);
        jb.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                LogWorker lw = new LogWorker(new File(NAME), model);
                lw.addPropertyChangeListener((PropertyChangeEvent ev) -> {
                    SwingWorker.StateValue s = (SwingWorker.StateValue) ev.getNewValue();
                    jpb.setIndeterminate(s.equals(SwingWorker.StateValue.STARTED));
                });
                lw.execute();
                int timeDelay = 0;
                ActionListener time;
                time = new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        m.setText(System.currentTimeMillis() / 1000 + "seconds");

                    }

                };
                Timer timer=new Timer(timeDelay, time);
                        timer.start();
                if(lw.isDone())
                    timer.stop();
            }
        });
    }
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            new DisplayLog().display();
        });
    }
}

1 个答案:

答案 0 :(得分:1)

看起来构成您的表的行来自网络,具有可变的,不确定的延迟。如图所示here,您可以在SwingWorker的背景中将数据加载到TableModel。如图here所示,您可以按照对应用程序有意义的方式计算中间进度,并将其显示在PropertyChangeListener中。