Java - 如何制作“runnable”JTable?

时间:2010-02-22 20:30:14

标签: java multithreading jtable

我在创建JTable时遇到问题,它会向每一秒显示一些文本。 我制作MainView,放置JTable并使用Class“TableHandler(JTable table)实现Runnable”,它应该在一段时间内向JTable添加一些文本... 这是run方法:

public void run() {
    for (int i=0; i<5; i++) {
        table.setValueAt("text", i, i);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }
}

问题是,在Jtable填充数据之前,MainView不会“显示”,因此用户看不到填充: - (

编辑:更多代码

public MyView(SingleFrameApplication app) {
    super(app);

    initComponents();
    // log of GUI stuff here
   TableHandler th = new TableHandler(myTable);
   th.createTable(); // just loads data
   Timer t = new Timer(100,new ActionListener() {
   public void actionPerformed(ActionEvent e) {
       th.run();
      }
   });
   t.start();

6 个答案:

答案 0 :(得分:3)

如果您正在使用Swing并希望按时间间隔执行操作,则应使用摇摆计时器,如tutorial中所述。

将你的循环转换成一系列对actionPerformed的调用,你得到:

    new Timer ( 1000, new ActionListener () {
        int i = 0; // moved out of loop 

        @Override
        public void actionPerformed ( ActionEvent event ) {
            if ( i < 5 ) {
                i++;

                table.setValueAt ( "text", i, i );

            } else {
                // stop the timer firing events when the loop end 
                // condition is reached
                ( ( Timer ) event.getSource() ).setRepeats ( false );
            }
        }
    } ).start();

答案 1 :(得分:2)

您需要从AWT线程更新:

public void run() {
    for (int i=0; i<5; i++) {
        final int x = i;
        SwingUtilities.invokeLater( new Runnable() {
          public void run() {
            table.setValueAt("text", x, x);
           }});
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }
}

请参阅http://java.sun.com/javase/6/docs/api/javax/swing/SwingUtilities.html#invokeLater(java.lang.Runnable)

答案 2 :(得分:1)

您所描述的行为最常可能出现的问题是您没有使用单独的线程来启动run方法。如果直接调用run方法,则在主线程再次可用之前屏幕不会更新,直到run方法完成后才会发生。

验证您是否在代码中的任何位置调用run(),因为应该在线程中处理。

编辑:启动课程的代码应如下所示:

new Thread(new TableHandler(table)).start();

答案 3 :(得分:0)

尝试在setValueAt()调用后调用repaint。最好用SwingUtilities.invokeLater包裹。

答案 4 :(得分:0)

如果您在一个帖子中运行它,则必须使用SwingUtilities.invokeLater。

这只会将请求排队到您的绘图例程,因此您需要确保通过暂停来调用它们。看起来应该是这样的:

in your main--or somewhere equivilent:
    new myThread
    myThread.start()

myThread.run()
   new myRoutine();
   while(activelyUpdating)
       invokeLater(myRoutine);
       sleep(something reasonable, like 1000 for updates every second);


myRoutine
    do all your drawing crap
    return (do not loop here, that's done in the thread.  Just return)

有一种方法让你的睡眠等待,直到invokeLater队列为空,但请确保你也睡不着,否则AWT线程(线程“myRoutine”将运行)永远不会有机会运行invokeLater线程将排队。

答案 5 :(得分:-3)

根据你的评论。

调用start而非run作为mmyers点,使用前者是正确的。

所以它应该是:

Thread t = new Thread( this.table ); // or new Thread( this )

t.start(); // call start on the read 

而不是

this.table.run();

t.run();