JTable数据实时更新


Jtable中一般使用 AbstractTableModel 和DefaultTableModel两个数据模型来管理需要显示的数据。自定义数据模型只需继承AbstractTableModel 。此时需要实现三个方法:

public int getColumnCount( ) //设定行数
public int getRowCount( )       //设定列数

                public Object getValueAt(int row, int col)//设定指定位置的值

        我为了使table动态更新数据,想尽了各种办法,查了各种资料,比较统一 的方法有两种:

        1、更新数据模型,然后调用JTable的validate( ) 和updateUI( )方法。

        2、更新数据模型,((AbstractTableModel)table.getModel()).fireTableDataChanged();

        初始版本,在外部文件中修改数据,表格不能更新:

[java]  view plain  copy
 
  1. import java.awt.Dimension;  
  2. import java.io.File;  
  3. import java.io.FileReader;  
  4. import java.util.ArrayList;  
  5. import java.util.List;  
  6. import javax.swing.JFrame;  
  7. import javax.swing.JPanel;  
  8. import javax.swing.JScrollPane;  
  9. import javax.swing.JTable;  
  10. import javax.swing.table.AbstractTableModel;  
  11. import javax.swing.table.TableModel;  
  12.   
  13. public class Test extends JPanel implements Runnable {  
  14.   
  15.     TableModel dataModel;  
  16.     JScrollPane scrollpane;  
  17.     JTable table;  
  18.       
  19.     public Test() {  
  20.         dataModel = getTableModel();  
  21.         table = new JTable(dataModel);  
  22.         scrollpane = new JScrollPane(table);  
  23.         this.add(scrollpane);  
  24.     }  
  25.   
  26.     //读取外部文件,每一行当做一条字符串存入List中  
  27.     public List<String> getData() {  
  28.         FileReader fr;  
  29.         File file = new File(  
  30.                 "E:/my.txt");  
  31.         int b;  
  32.         StringBuffer sb = new StringBuffer();  
  33.         List<String> s = new ArrayList<String>();  
  34.         try {  
  35.             fr = new FileReader(file);  
  36.             while ((b = fr.read()) != -1) {  
  37.                 if (b != '\r') {  
  38.                     sb.append((char) b);  
  39.                 }  
  40.                 if (b == '\n') {  
  41.                     s.add(sb.toString());  
  42.                     sb = new StringBuffer();  
  43.                 }  
  44.             }  
  45.             fr.close();  
  46.         } catch (Exception e) {  
  47.             e.printStackTrace();  
  48.         }  
  49.         return s;  
  50.     }  
  51.       
  52.     //使用public List<String> getData() 方法得到的List构建数据模型  
  53.     //此处使用的外部文件中,每一行的字符串用空格分成四个部分  
  54.     //例如,其中一行为:2013-03-18 11:50:55   传感器1    报警,对应表格的一行  
  55.     public AbstractTableModel getTableModel() {  
  56.           
  57.         return new AbstractTableModel() {  
  58.               
  59.             List<String> list=getData();  
  60.             public int getColumnCount() {  
  61.                 return 4;  
  62.             }  
  63.             public int getRowCount() {  
  64.                 return list.size();  
  65.             }  
  66.             public Object getValueAt(int row, int col) {  
  67.                 switch (col) {  
  68.                 case (0): {  
  69.                     return row + 1;  
  70.                 }  
  71.                 case (1): {  
  72.                     return list.get(row).split(" ", 0)[0];  
  73.                 }  
  74.                 case (2): {  
  75.                     return list.get(row).split(" ", 0)[1];  
  76.                 }  
  77.                 default:  
  78.                     return list.get(row).split(" ", 0)[2];  
  79.                 }  
  80.             }  
  81.         };  
  82.     }  
  83.       
  84.     public void run() {  
  85.         while (true) {  
  86.             //每隔1秒钟更新JTable  
  87.             table.validate();  
  88.             <span style="color:#ff0000;">table.updateUI();  
  89. </span>         try {  
  90.                 Thread.sleep(1000);  
  91.             } catch (InterruptedException e) {  
  92.                 e.printStackTrace();  
  93.             }  
  94.         }  
  95.     }  
  96.     public static void main(String[] g) {  
  97.         JFrame frame = new JFrame();  
  98.         Test t = new Test();  
  99.         frame.add(t);  
  100.         frame.setSize(new Dimension(400, 400));  
  101.         frame.setVisible(true);  
  102.         new Thread(t).start();  
  103.     }  
  104. }  


 修改版本,实时更新:

 

 

[java]  view plain  copy
 
  1. import java.awt.Dimension;  
  2. import java.io.File;  
  3. import java.io.FileReader;  
  4. import java.util.ArrayList;  
  5. import java.util.List;  
  6. import javax.swing.JFrame;  
  7. import javax.swing.JPanel;  
  8. import javax.swing.JScrollPane;  
  9. import javax.swing.JTable;  
  10. import javax.swing.table.AbstractTableModel;  
  11. import javax.swing.table.TableModel;  
  12.   
  13. public class Test extends JPanel implements Runnable {  
  14.   
  15.     TableModel dataModel;  
  16.     JScrollPane scrollpane;  
  17.     JTable table;  
  18.       
  19.     public Test() {  
  20.         dataModel = getTableModel();  
  21.         table = new JTable(dataModel);  
  22.         scrollpane = new JScrollPane(table);  
  23.         this.add(scrollpane);  
  24.     }  
  25.   
  26.     //读取外部文件,每一行当做一条字符串存入List中  
  27.     public List<String> getData() {  
  28.         FileReader fr;  
  29.         File file = new File(  
  30.                 "E:/my.txt");  
  31.         int b;  
  32.         StringBuffer sb = new StringBuffer();  
  33.         List<String> s = new ArrayList<String>();  
  34.         try {  
  35.             fr = new FileReader(file);  
  36.             while ((b = fr.read()) != -1) {  
  37.                 if (b != '\r') {  
  38.                     sb.append((char) b);  
  39.                 }  
  40.                 if (b == '\n') {  
  41.                     s.add(sb.toString());  
  42.                     sb = new StringBuffer();  
  43.                 }  
  44.             }  
  45.             fr.close();  
  46.         } catch (Exception e) {  
  47.             e.printStackTrace();  
  48.         }  
  49.         return s;  
  50.     }  
  51.       
  52.     //使用public List<String> getData() 方法得到的List构建数据模型  
  53.     //此处使用的外部文件中,每一行的字符串用空格分成四个部分  
  54.     //例如,其中一行为:2013-03-18 11:50:55   传感器1    报警,对应表格的一行  
  55.     public AbstractTableModel getTableModel() {  
  56.         return new AbstractTableModel() {  
  57.             public int getColumnCount() {  
  58.                 return 4;  
  59.             }  
  60.             public int getRowCount() {  
  61.                 return getData().size();  
  62.             }  
  63.             public Object getValueAt(int row, int col) {  
  64.                 switch (col) {  
  65.                 case (0): {  
  66.                     return row + 1;  
  67.                 }  
  68.                 case (1): {  
  69.                     return getData().get(row).split(" ", 0)[0];  
  70.                 }  
  71.                 case (2): {  
  72.                     return getData().get(row).split(" ", 0)[1];  
  73.                 }  
  74.                 default:  
  75.                     return getData().get(row).split(" ", 0)[2];  
  76.                 }  
  77.             }  
  78.         };  
  79.     }  
  80.       
  81.     public void run() {  
  82.         while (true) {  
  83.             //每隔1秒钟更新JTable  
  84.             table.validate();  
  85.             table.updateUI();  
  86.             try {  
  87.                 Thread.sleep(1000);  
  88.             } catch (InterruptedException e) {  
  89.                 e.printStackTrace();  
  90.             }  
  91.         }  
  92.     }  
  93.     public static void main(String[] g) {  
  94.         JFrame frame = new JFrame();  
  95.         Test t = new Test();  
  96.         frame.add(t);  
  97.         frame.setSize(new Dimension(400, 400));  
  98.         frame.setVisible(true);  
  99.         new Thread(t).start();  
  100.     }  
  101. }  


区别是public AbstractTableModel getTableModel()方法不同

 

 

仔细研究后发现,JTable在调用validate( ) 和updateUI( )方法时,通过 public Object getValueAt(int row, int col)方法去取得指定位置的值。

前一种情况下虽然调用了该方法,但是外部文件中数据变化并未反映在List<String> list中,list只在实例化AbstractTableModel时得到值,

以后并未更新。

而后一种,表格的值是通过调用getData( )方法取得,每一次都是在外部文件中读取。

因此,更新数据模型就能使JTable更新,前提是数据模型的值确实更新了。

 

前面的实现中用了线程来动态更新,swing中更好的办法是用户Timer:

[java]  view plain  copy
 
  1. import java.awt.Dimension;  
  2. import java.awt.event.ActionEvent;  
  3. import java.awt.event.ActionListener;  
  4. import java.io.File;  
  5. import java.io.FileReader;  
  6. import java.util.ArrayList;  
  7. import java.util.List;  
  8.   
  9. import javax.swing.JFrame;  
  10. import javax.swing.JPanel;  
  11. import javax.swing.JScrollPane;  
  12. import javax.swing.JTable;  
  13. import javax.swing.Timer;  
  14. import javax.swing.table.AbstractTableModel;  
  15. import javax.swing.table.TableModel;  
  16.   
  17. public class Test extends JPanel  {  
  18.   
  19.     TableModel dataModel;  
  20.     JScrollPane scrollpane;  
  21.     JTable table;  
  22.     Timer timer;  
  23.       
  24.     public Test() {  
  25.         dataModel = getTableModel();  
  26.         table = new JTable(dataModel);  
  27.         scrollpane = new JScrollPane(table);  
  28.           
  29.         timer=new Timer(1000,new ActionListener() {  
  30.             public void actionPerformed(ActionEvent evt) {  
  31.                 table.validate();  
  32.                 table.updateUI();  
  33.             }  
  34.         });  
  35.         timer.start();  
  36.         this.add(scrollpane);  
  37.     }  
  38.   
  39.     //读取外部文件,每一行当做一条字符串存入List中  
  40.     public List<String> getData() {  
  41.         FileReader fr;  
  42.         File file = new File(  
  43.                 "E:/my.txt");  
  44.         int b;  
  45.         StringBuffer sb = new StringBuffer();  
  46.         List<String> s = new ArrayList<String>();  
  47.         try {  
  48.             fr = new FileReader(file);  
  49.             while ((b = fr.read()) != -1) {  
  50.                 if (b != '\r') {  
  51.                     sb.append((char) b);  
  52.                 }  
  53.                 if (b == '\n') {  
  54.                     s.add(sb.toString());  
  55.                     sb = new StringBuffer();  
  56.                 }  
  57.             }  
  58.             fr.close();  
  59.         } catch (Exception e) {  
  60.             e.printStackTrace();  
  61.         }  
  62.         return s;  
  63.     }  
  64.       
  65.     //使用public List<String> getData() 方法得到的List构建数据模型  
  66.     //此处使用的外部文件中,每一行的字符串用空格分成四个部分  
  67.     //例如,其中一行为:2013-03-18 11:50:55   传感器1    报警,对应表格的一行  
  68.     public AbstractTableModel getTableModel() {  
  69.           
  70.         return new AbstractTableModel() {  
  71.             public int getColumnCount() {  
  72.                 return 4;  
  73.             }  
  74.             public int getRowCount() {  
  75.                 return getData().size();  
  76.             }  
  77.             public Object getValueAt(int row, int col) {  
  78.                 switch (col) {  
  79.                 case (0): {  
  80.                     return row + 1;  
  81.                 }  
  82.                 case (1): {  
  83.                     return getData().get(row).split(" ", 0)[0];  
  84.                 }  
  85.                 case (2): {  
  86.                     return getData().get(row).split(" ", 0)[1];  
  87.                 }  
  88.                 default:  
  89.                     return getData().get(row).split(" ", 0)[2];  
  90.                 }  
  91.             }  
  92.         };  
  93.     }  
  94.       
  95.     public static void main(String[] g) {  
  96.         JFrame frame = new JFrame();  
  97.         Test t = new Test();  
  98.         frame.add(t);  
  99.         frame.setSize(new Dimension(400, 400));  
  100.         frame.setVisible(true);  
  101.         //t.timer.start();  
  102.           
  103.     }  
  104. }  


效果一样 。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM