1

enter image description hereI have a swing GUI named SpyBiteDemo, it will call another class(Parser) and do some calculations and show some data in a jtable inside this GUI(SpyBiteDemo). I have a jbutton1 and I want to when click on it to show my timer to begin like 1,2,3,4,5,....seconds

what happens is my timer is running correctly however it does not show value unless it is done with all the program that is filling the jtable which means the action it is detecting is I perform the action after jtable appears.

I am a complete newbie on Java for event listeners and I have searched timer, timer task, schedule, everything and could not understand what's wrong.I also tried while(true) and did not fix it.I also tried duration of 1000,0,everything no affects.

I tried to use action command,sleeping the thread, it did not help.here is what I did:

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);
    }
}

it will start showing label3 value only after it is filling the jtable on my jframe.I want the timer to start from when I am clicking the button.

with trashgod's links I had come up with this example which is comepletely runnable on your machine, this works perfect except that when I the program finishes, it does not stop the timer since I don't know where to do it, I know I should do it in addPropertyChangeListener, however I do not have timer value.

    /*
 * 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();
        });
    }
}
Nickool
  • 3,662
  • 10
  • 42
  • 72
  • @JonnyHenly sure, I just indented what do you mean example? should I insert screenshots? – Nickool Jun 28 '16 at 08:47
  • 1
    Thank you for fixing the indentation. A [mcve] basically means to provide enough code so that, if we were to compile and run it, then we would see the exact same results as you. – Jonny Henly Jun 28 '16 at 08:52
  • Jonny it is 2 AM and I am tired, I had been working on it from 8PM. my brain is not working anymore. I am sending you the screenshot – Nickool Jun 28 '16 at 08:53
  • A screenshot helps, but without all of the necessary code we will not be able to reproduce your dilemma or provide a detailed answer. – Jonny Henly Jun 28 '16 at 08:55
  • My program is a lot, I am not able to send all of it. I will try to make a unit test tomorrow and update here by that time. – Nickool Jun 28 '16 at 08:56
  • *"My program is a lot, I am not able to send all of it."* Nobody asked you to post your entire codes. When people give you a link, follow it and read it. *"it is 2 AM and I am tired.."* Then you should not be posting questions on SO. Get some sleep, manage your time better, and when you're fresh enough to follow and read links, and prepare an MCVE, ***then*** post a question. – Andrew Thompson Jun 28 '16 at 13:24
  • @AndrewThompson I apologize for inconveniences, I will make sure to post another answer and explain how I solved with trashgod's answer here. – Nickool Jun 28 '16 at 16:32
  • @AndrewThompson I guess now it is more understandable. – Nickool Jun 28 '16 at 18:39

1 Answers1

1

It looks like the rows that comprise your table come from the network with variable, indeterminate latency. As shown here, you can load data into your TableModel in the background of a SwingWorker. As shown here, you can calculate intermediate progress in a way that makes sense for your application and display it in a PropertyChangeListener.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Thank you so much for this!!! The application will become responsive only when the long task is finished. I have a thread and it is busy with calculations and does not take care of the timer. – Nickool Jun 28 '16 at 16:30
  • I had done the same with help of your example and edited the question. now wondering how to do the stop however I think 90% I am done now.... – Nickool Jun 28 '16 at 18:38
  • @Nickool: Check `isCancelled()` and invoke `cancel()`, for [example](http://stackoverflow.com/a/20603012/230513). – trashgod Jun 28 '16 at 19:37
  • thank you suppose that I invoked cancel(), how to call timer.stop it is not defined in that scope? – Nickool Jun 28 '16 at 19:46
  • @Nickool: call `stop()` when `s.equals(SwingWorker.StateValue.DONE)`; you'll have move the timer up a little. – trashgod Jun 28 '16 at 20:10