Java swingworker()进程()没有被调用

时间:2014-08-19 08:59:37

标签: java eclipse swing swingworker windowbuilder

我正在使用swingworker()来创建发布结果的后台线程,并且应该通过process()更新GUI。但是process()永远不会被调用:

public class comm {
    protected Shell shldPrinter;
    private Text v1time;
    private static Text cTemp1;
    static boolean control1 = false; 

    /**
     * Launch the application.
     * @param args
     */
    public static void main(String[] args) {

        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                 try {
                    new comm();  //create the user interface named window
                    //window.open();             //invoke open() function
                } catch (Exception e) {
                    e.printStackTrace();
                }
             }
          });
    }

    /**
     * Open the window.
     */
    public comm() {
        this.open();
    }
    public void open() {
        Display display = Display.getDefault();
        createContents();
        shldPrinter.open();
        shldPrinter.layout();
        while (!shldPrinter.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }

    private void start() {
        SwingWorker<Boolean,String> worker = new SwingWorker<Boolean,String> () {
            //@Override
            protected Boolean doInBackground() throws Exception {
                   while(control1) {
                       curtemp1++;
                       publish(Double.toString(curtemp1));
                       System.out.println(curtemp1);
                       try {
                           Thread.sleep(500);  // milliseconds
                        } catch (InterruptedException ex) {}
                   }

                return true;
            }

            protected void process(List<String> chunks) {
                cTemp1.setText("chunks.get(chunks.size()-1)");
            }

        };
        worker.execute();
    }

    /**
     * Create contents of the window.
     */
    protected void createContents() {
        shldPrinter = new Shell();
        shldPrinter.setSize(490, 299);
        shldPrinter.setText("Robogel Temp Control");

        final Button btnCln1 = new Button(shldPrinter, SWT.CHECK);
        btnCln1.addSelectionListener(new SelectionAdapter() {
            @Override

            public void widgetSelected(SelectionEvent e) {
                control1 = btnCln1.getSelection();
                if(control1)
                    start();
            }
        });
        btnCln1.setBounds(22, 51, 69, 16);
        btnCln1.setText("Valve 1");

        //create text box for valve 1 timing
        v1time = new Text(shldPrinter, SWT.BORDER | SWT.CENTER);
        v1time.addFocusListener(new FocusAdapter() {
            @Override
            //when cursor moves away from text box
            public void focusLost(FocusEvent e) {
                reftemp1 = Double.parseDouble(v1time.getText()); // get time in ascii format and convert it into int
            }
        });
        v1time.setText("25");
        v1time.setBounds(97, 49, 51, 21);

        cTemp1 = new Text(shldPrinter, SWT.BORDER | SWT.CENTER);
        cTemp1.setEditable(false);
        cTemp1.setText(Double.toString(curtemp1));
        cTemp1.setBounds(203, 49, 51, 21);
    }
}

当GUI关闭时,会出现以下错误:

Exception in thread "AWT-EventQueue-0" org.eclipse.swt.SWTException: Widget is disposed
at org.eclipse.swt.SWT.error(SWT.java:4397)
at org.eclipse.swt.SWT.error(SWT.java:4312)
at org.eclipse.swt.SWT.error(SWT.java:4283)
at org.eclipse.swt.widgets.Widget.error(Widget.java:472)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:344)
at org.eclipse.swt.widgets.Text.setText(Text.java:2240)
at comm$2.process(comm.java:172)
at javax.swing.SwingWorker$3.run(Unknown Source)
at sun.swing.AccumulativeRunnable.run(Unknown Source)
at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.run(Unknown Source)
at sun.swing.AccumulativeRunnable.run(Unknown Source)
at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.actionPerformed(Unknown Source)
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$200(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)

我已经阅读了很多论坛,但没有任何帮助。尝试过调用done(),但即使这样也不会被调用。

2 个答案:

答案 0 :(得分:1)

混合Swing EDT和SWT线程。这将导致异常,因为SWT会检查每次调用是否在SWT线程中进行。从您的代码中删除:Swing

javax.swing.SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
         try {
            new comm();  //create the user interface named window
            //window.open();             //invoke open() function
        } catch (Exception e) {
            e.printStackTrace();
        }
     }
  });

你只需要在秋千环境中使用它,因为swing会启动EDT。在SWT中,创建Display的线程将是EDT。新版本:

  new comm();  //create the user interface named window

现在要在后台执行一些东西,你可以使用通常的java机制(并发等),但是不要使用Swing的东西,它只会让你变得非常复杂。重要的是,在后台工作完成后,您使用Display#asyncExec同步回SWT EDT这里是example

我建议在没有任何摆码的情况下重写你的例子,并在新问题中重新发布任何问题。 (非常奇怪的事情正在发生,从我的角度来看很难说出问题是什么。)

答案 1 :(得分:0)

仅在SwingWorker#process()方法完成时才调用

doInBackground。我看到,control1永远不会false,所以doInBackground永远不会完成。尽量使用javax.swing.Timer代替SwingWorker

来实现这些目的
Timer = new Timer(500, new ActionListener() {
    long curtemp1 = 0;
    @Override
    public void actionPerfomed(ActionEvent e) {
        cTemp1.setText(String.valueOf(curtemp1));
        curtemp1++;
    }
});