Timer in java using Eclipse

2019-02-26 11:41发布

问题:

I'm trying to do a little program in Java using Eclipse, and I'm a little bit lost.

Could anybody explain me (in a "for dummies way") what do I have to do for repaint a form using a timer?

I'm trying to do something as simple as a clock. I need a timer to repaint it every second.

Something like this:

private void activateTimer()
{
    ActionListener myAction;
    myAction = new ActionListener () 
    { 
        public void actionPerformed(ActionEvent e) 
        { 
           whatever.redraw();
         } 

    };
    myTimer = new Timer(1000, myAction);
    myTimer.start();
}

When the action must be performed, I receive the error:

*Exception in thread "AWT-EventQueue-0" org.eclipse.swt.SWTException: Invalid thread access*

This is the full exception I receive:

Exception in thread "AWT-EventQueue-0" org.eclipse.swt.SWTException: Invalid thread access
    at org.eclipse.swt.SWT.error(SWT.java:4282)
    at org.eclipse.swt.SWT.error(SWT.java:4197)
    at org.eclipse.swt.SWT.error(SWT.java:4168)
    at org.eclipse.swt.widgets.Widget.error(Widget.java:468)
    at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:359)
    at org.eclipse.swt.widgets.Control.redraw(Control.java:2327)
    at default.myTimer$1.actionPerformed(myTimer.java:97)
    at javax.swing.Timer.fireActionPerformed(Unknown Source)
    at javax.swing.Timer$DoPostEvent.run(Unknown Source)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$000(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

Any idea or any sample about refreshing a screen every second?

I've followed the instructions in one of the answers but I'm still receiving the same error.

回答1:

you have to split that to the separete methods, better would be using javax.swing.Action instead of ActionListener

private void activateTimer(){
    myTimer = new Timer(1000, myAction);
    myTimer.start();
}

private Action myAction = new AbstractAction() {

    private static final long serialVersionUID = 1L;

    @Override
    public void actionPerformed(ActionEvent e) {
          whatever.redraw();
    }
};


回答2:

Why not use the timer functionality that is built into the SWT Display class?

private void activateTimer(final Display display)
{
    display.timerExec(
        1000,
        new Runnable() {
            public void run() {
                whatever.redraw();
                // If you want it to repeat:
                display.timerExec(1000, this);
            }
        });
}


回答3:

This page may be useful.

If you use SWT, do it in SWT way :)

EDIT:

The problem is widget should be updated by eclipse's thread. Try this code.

Job job = new Job("My Job") {
@Override
protected IStatus run(IProgressMonitor monitor) {
    Display.getDefault().asyncExec(new Runnable() {
        @Override
        public void run() {
            while(true)
            {
                Thread.sleep(1000);
                whatever.redraw();
            }
        }
    });
    return Status.OK_STATUS;
}
};
job.schedule();