Jtable不刷新/更新数据
我有JTable
/ JScrollPane
的问题。 我的数据表没有刷新/更新。 我正在使用DefultTableModel
并根据代码一切正常,我没有任何错误。 此外,我有一个分页表,这就是为什么我使用动作监听器和按钮“prev”和“next”。 我从其他函数传递到函数,该函数在JTable
类中编码。 问题是我填充了包含表数据的数组,但表不会更新/刷新它。 这是我的代码。 谢谢你。
BIG EDIT旧代码已被删除。 我添加了新的代码,可以帮助你们/女孩了解我的问题。 希望这会有所帮助。 问候。
这里首先是显示gui的类:
import javax.swing.*; public class Glavni { public static void main(String[] args) { // TODO Auto-generated method stub SwingUtilities.invokeLater(new Runnable() { public void run() { gui Scanner = new gui(); Scanner.setVisible(true); } }); } }
第二个是将String传递给包含jtable的gui类的类
public class passDatatoTable { public void passData(){ String str1,str2,str3,str4; gui SendStringsToGUI = new gui(); for (int i =0;i<=10;i++){ str1="Column 1 of row: "+i; str2="Column 2 of row: "+i; str3="Column 3 of row: "+i; str4="Column 4 of row: "+i; SendStringsToGUI.WriteMonitorData(str1, str2, str3, str4); } } }
接下来是gui(contructor)的声明:
import javax.swing.*; import javax.swing.table.DefaultTableModel; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class gui extends JFrame implements ActionListener { private static final long serialVersionUID = 1L; String[][] data = new String[100][4]; String[] columnNames = new String[]{ "IP", "PC_NAME", "ttl", "db" }; DefaultTableModel model = new DefaultTableModel(data,columnNames); JTable table = new JTable(model); JScrollPane scrollPane = new JScrollPane(table); int i=0; public void WriteMonitorData (String IP, String PC_NAME, String ttl, String gw) { System.out.println(IP);//just for testing (check if data was passed) model.setValueAt(IP, i, 0); model.setValueAt(PC_NAME, i, 1); model.setValueAt(ttl, i, 2); model.setValueAt(gw, i, 3); i++; model.fireTableDataChanged(); table.repaint(); scrollPane.repaint(); } gui(){ JButton addData= new JButton("Add Data"); JButton next = new JButton("next"); JButton prev = new JButton("prev"); addData.addActionListener(this); next.addActionListener(this); prev.addActionListener(this); JPanel panel = new JPanel(new BorderLayout()); JPanel buttonPanel = new JPanel(); buttonPanel.add(addData); buttonPanel.add(prev); buttonPanel.add(next); panel.add(buttonPanel, BorderLayout.SOUTH); panel.add(table.getTableHeader(), BorderLayout.PAGE_START); panel.add(scrollPane, BorderLayout.CENTER); getContentPane().add(panel); }
这是actionListeners:
public void actionPerformed(ActionEvent e) { if ("Add Data".equals(e.getActionCommand())){ passDatatoTable passSomeData = new passDatatoTable(); passSomeData.passData(); } if ("next".equals(e.getActionCommand())) { Rectangle rect = scrollPane.getVisibleRect(); JScrollBar bar = scrollPane.getVerticalScrollBar(); int blockIncr = scrollPane.getViewport().getViewRect().height; bar.setValue(bar.getValue() + blockIncr); scrollPane.scrollRectToVisible(rect); } if ("prev".equals(e.getActionCommand())) { Rectangle rect = scrollPane.getVisibleRect(); JScrollBar bar = scrollPane.getVerticalScrollBar(); int blockIncr = scrollPane.getViewport().getViewRect().height; bar.setValue(bar.getValue() - blockIncr); scrollPane.scrollRectToVisible(rect); } }
你的第一个片段显示了这个:
JTable table = new JTable(model);
但你的gui()
构造函数显示:
JTable table = new JTable(data, columnNames);
你启动表两次。 一旦使用TableModel
( JTable(TableModel tm)
),下一个使用JTable(int rows,int cols)
这不好,在构造函数中启动一次JTable
:
gui() { DefaultTableModel model = new DefaultTableModel(data,columnNames); JTable table = new JTable(model); JScrollPane scrollPane = new JScrollPane(table); JButton next = new JButton("next"); JButton prev = new JButton("prev"); next.addActionListener(this); prev.addActionListener(this); JPanel panel = new JPanel(new BorderLayout()); JPanel buttonPanel = new JPanel(); buttonPanel.add(prev); buttonPanel.add(next); panel.add(buttonPanel, BorderLayout.SOUTH); panel.add(table.getTableHeader(), BorderLayout.PAGE_START); panel.add(scrollPane, BorderLayout.CENTER); getContentPane().add(panel); }
更新:
这是一个示例,它有一个线程,在UI可见后将启动2.5秒,并更改JTable
的值:
import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.*; import javax.swing.table.DefaultTableModel; public class Test extends JFrame { public static void main(String[] args) throws Exception { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new Test().createAndShowUI(); } }); } private void createAndShowUI() { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); initComponents(frame); frame.pack(); frame.setVisible(true); new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(2500); } catch (InterruptedException ex) { Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); } SwingUtilities.invokeLater(new Runnable() { @Override public void run() { model.setValueAt("hello", 0, 0); } }); } }).start(); } static DefaultTableModel model; private void initComponents(JFrame frame) { String data[][] = { {"1", "2", "3"}, {"4", "5", "6"}, {"7", "8", "9"}, {"10", "11", "12"} }; String col[] = {"Col 1", "Col 2", "Col 3"}; model = new DefaultTableModel(data, col); JTable table = new JTable(model); frame.getContentPane().add(new JScrollPane(table)); } }
根据我对注释和问题的理解,您首先通过在构造函数中将数据作为数组传递来创建DefaultTableModel
String[][] data = new String[100][4]; String[] columnNames = new String[]{ "IP", "PC_NAME", "ttl", "db"}; DefaultTableModel model = new DefaultTableModel(data,columnNames);
并尝试通过调整这些数组来修改表。 这将永远不会产生任何影响,因为DefaultTableModel
不使用这些数组。 这可以在该类的源代码中看到
public DefaultTableModel(Object[][] data, Object[] columnNames) { setDataVector(data, columnNames); }
最终归结为
protected static Vector convertToVector(Object[][] anArray) { if (anArray == null) { return null; } Vector v = new Vector (anArray.length); for (Object[] o : anArray) { v.addElement(convertToVector(o)); } return v; }
因此,数组的所有元素都被复制到内部Vector
并且不再使用该数组。
解决方案:不要更新arrays,而是更新DefaultTableModel
。 该类提供了向/从中添加/删除数据所需的所有API。