且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

动态地向JTable添加行 - 为什么它们一次出现?

更新时间:2023-12-04 09:56:22

As由kleopatra和peeskillet指出,我最初的例子遭遇了一个愚蠢的错误。值得注意的是,peeskillet和我正在采用不同的方法。在我的示例中,列旨在表示可能花费未知时间且实际上可能失败的连接尝试(或多或少)(在这种情况下,只有在这种情况下,下一列才会起作用等等) )。因此,对我来说一次添加行是没有意义的(这可能是因为我的例子对peeskillet来说看起来很奇怪)。我已经使用SwingWorker解决了这个任务。正如kleopatra所指出的,还有另一个错误,现在已经修复了。这是我的代码:

As pointed out by kleopatra and peeskillet, my initial example suffered from a stupid mistake. It's worth noting that peeskillet and I were following different approaches, though. In my example, the columns meant to represent connection attempts (more or less) that can take an unknown amount of time and that can actually fail (in that case, and only in that case, the next column would come into play and so on). Therefore, it wouldn't have made sense for me to add the rows at once (which was probably what made my example look weird to peeskillet). I've solved the task using a SwingWorker. As pointed out by kleopatra, there was a another mistake, which is now fixed. Here's my code:

package SwingWorkerExampleCopy;

import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import java.awt.BorderLayout;

public class SwingWorkerExampleCopy {
  public static void main(String[] args) {
    // Show GUI
    java.awt.EventQueue.invokeLater(new Runnable() {
      @Override
      public void run() {
        GUI gui = new GUI();

        DefaultTableModel tableModel = new DefaultTableModel();

        // Use a SwingWorker
        Worker worker = new Worker(tableModel);
        worker.execute();

        JTable table = new JTable(tableModel);
        table.setEnabled(false);
        // table.setTableHeader(null);

        JScrollPane scrollPane = new JScrollPane(table);
        gui.getContentPane()
          .add(scrollPane, BorderLayout.CENTER);

      }
    });
  }
}

class GUI extends JFrame {
  private static final long serialVersionUID = 1L;

  public GUI() {
    setTitle("GUI");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 350, 400);
    setLocationRelativeTo(null);
    setVisible(true);

    JPanel contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(10, 10, 10, 10));
    contentPane.setLayout(new BorderLayout(0, 0));

    setContentPane(contentPane);
  }
}

class Worker extends SwingWorker<DefaultTableModel, Object[]> {

  private final static int  numRows = 10;
  private final static int  numCols = 10;

  private DefaultTableModel model;

  Worker(DefaultTableModel model) {
    this.model = model;
    model.setColumnCount(numCols);
  }

  @Override
  protected DefaultTableModel doInBackground() throws Exception {
    // Add row
    for (int row = 0; row < numRows; row++) {
      // Build columns
      for (int col = 0; col < numCols; col++) {
        if (col == 0) {
          publish(new Object[] { new String("Row " + row), row,
            col });
        } else {
          // Simulate a slow source
          Thread
            .sleep(new Random().nextInt((250 - 50) + 1) + 50);

          Boolean isSuccessful = false;

          // Simulate a return value
          if (new Random().nextBoolean()) {
            isSuccessful = true;
          }

          publish(new Object[] {
            new String((isSuccessful == true ? "x" : "o")), row,
            col });

          if (isSuccessful == true) {
            break;
          }
        }
      }
    }

    return model;
  }

  @Override
  protected void process(List<Object[]> chunks) {
    for (Object[] chunk : chunks) {
      // chunk[0]: cell value
      // chunk[1]: number
      // chunk[2]: column
      if ((int) chunk[2] == 0) {
        Object[] row = new Object[numCols];
        row[0] = (Object) chunk[0];
        model.addRow(row);
      } else {
        model.setValueAt((Object) chunk[0], (int) chunk[1],
          (int) chunk[2]);
      }
    }
  }
}