Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

java - Dynamically adding rows to JTable - Why do they appear at once?

In the example, I'm seeking to add a table to my GUI and then dynamically add rows to it (to show the progress). What I don't understand is why all the rows are appearing at once. I mean, the the table's changing, isn't it? Can someone please give me an explanation?

import java.awt.Component;

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

        DefaultTableModel model = new DefaultTableModel(
          new String[] { "Column 1", "Column 2" }, 0);
        JTable table = new JTable(model);

        gui.add(table);
        gui.validate();

        for (int i = 0; i < 10; i++) {
          System.out.println("Row " + i);
          model
            .addRow(new String[] { "Row", String.valueOf(i) });
          // model.fireTableDataChanged();

          try {
            Thread.sleep(250);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }

        }
      }
    });
  }
}

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

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

    JPanel cp = new JPanel();
    cp.setBorder(new EmptyBorder(10, 10, 10, 10));
    setContentPane(cp);
  }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Reiterating Kleopatra : Don't Sleep the EDT

You can instead use a javax.swing.Timer as seen in this answer

enter image description here


EDIT

I didn't want to mess with your code too much (just because it looks weird to me) but I changed it somewhat to add the Timer

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;

public class Main {

    static JTable table;
    static GUI gui;
    static Processor p = null;

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

                p = new Processor() {

                    @Override
                    public void execute() {
                        final JTable table = new JTable(p.getTableModel());
                        final JScrollPane scrollPane = new JScrollPane(table);
                        gui.getContentPane().add(scrollPane, BorderLayout.CENTER);
                        gui.setLocationRelativeTo(null);
                        gui.setVisible(true);

                        Timer timer = new Timer(100, new ActionListener(){
                            public void actionPerformed(ActionEvent e) {
                                p.processRow();
                                table.scrollRectToVisible(table.getCellRect(table.getRowCount() - 1, 0, true));
                            }
                        });
                        timer.start();
                    }
                };
                p.execute();
            }
        });
    }
}

class GUI extends JFrame {

    private static final long serialVersionUID = 1L;

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

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

        setContentPane(contentPane);
    }
}

interface Callback {

    void execute();
}

abstract class Processor implements Callback {

    private final String[] cols = {"COL", "COL", "COL", "COL", "COL"};
    private DefaultTableModel tableModel;
    int numRows;
    int numCols;
    int a, b, c, d, e;

    Processor() {
        a = 1; b = 2; c = 3; d = 4; e = 4;
        numRows = 1000;
        tableModel = new DefaultTableModel(cols, numCols);
    }

    public DefaultTableModel getTableModel() {
        return tableModel;
    }

    public void processRow() {
        tableModel.addRow(new Object[]{a, b, c, d, e});
        a++; b++; c++; d++; e++;
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...