加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

解决快速刷新JTable时的AWT-EventQueue-0"中ArrayIndexOutOfBoundsException异常,并且流畅显示刷新数

(2011-09-16 12:27:14)
标签:

java

swing

jtable

分类: Swing

     利用类似双缓冲的原理,使用两个JTable,两个相应的DefaultTableModel,在同一时间一个table用于显示数据,一个table用于刷新数据,因此解决了在快速向JTable刷新数据的时候报AWT-EventQueue-0"中ArrayIndexOutOfBoundsException的问题,并且当快速刷新JTable时,可以流畅的显示数据(即闪烁不那么明显),当记住刷新前滚动条的位置刷新后滚动条任然处于刷新前的位置。

   相关代码:

 

JTable和DefaultTableModel的声明:

 

   //两个JTable,用于流畅显示向Table中快速刷新的数据

    private JTable[]  dataTable = new JTable[2];

    //两个DefaultTableModel,tableModel[0]对应dataTable[0]

    //tableModel[1]对应dataTable[1],用于流畅显示向Table中快速刷新的数据

    private DefaultTableModel[] tableModel = new DefaultTableModel[2] ;

    private int tableIndex = 0; //记录当前显示的table下标

    private Vector<String> columnIdentifier ;//行标题

    private JScrollPane scrollPane;

 
JTable和DefaultTableModel的定义:

dataTable[0] = new StyleTable();

       dataTable[1] = new StyleTable();

       tableModel[0] = new DefaultTableModel(

              new Object[][] {

                     {"1","XXXXX", "XXXXX", "XXXXX", "通过WebService拿不到数据",

                         new SimpleDateFormat("yyyy-MM-dd mm:HH:ss").format(new Date())}

                  },

              new String[] {"序号","数据名称", "数据编码", "所属实体", "数据值", "采集时间"}

       );

       tableModel[1] = new DefaultTableModel(

              new Object[][] {

                     {"1","XXXXX", "XXXXX", "XXXXX", "通过WebService拿不到数据",

                         new SimpleDateFormat("yyyy-MM-dd mm:HH:ss").format(new Date())}

                  },

              new String[] {"序号","数据名称", "数据编码", "所属实体", "数据值", "采集时间"}

       );

       dataTable[0].setModel(tableModel[0]); 

       dataTable[1].setModel(tableModel[1]);

      

       scrollPane.getViewport().add(dataTable[0]);

      

       columnIdentifier =  new Vector<String>();

       columnIdentifier.add("序号");

       columnIdentifier.add("数据名称");

       columnIdentifier.add("数据编码");

       columnIdentifier.add("所属实体");

       columnIdentifier.add("数据值");

       columnIdentifier.add("采集时间");

 

用于读取数据以及刷新JTable的内部线程类:

 

     //读数据线程,把数据读取上来之后,放入table

      //@author Shen Jiaxi

    @SuppressWarnings("unused")

    private class ReadDataThread extends Thread{

       boolean isFinish = false;

      

       long flashTime = 1000;//刷新数据的周期 1s

      

       //用于记录上次水平和垂直的滚动条的位置

       int scrollbarLastPositon_X ;

       int scrollbarLastPositon_Y;

      

       long start ;

      

       public void run(){

          

           Vector<Vector<String>> dataVector;

           while( true ){

             

              start = System.currentTimeMillis();

             

              if( isFinish ){

                  return;

              }

             

              //用于让另外一个表格来装载最新的数据,之前的表格任然显示之前的数据,

             //待装载最新数据的表格完成一系列耗时的动作后,再由之前的显示旧内容的表格切换到该显示最新内

             //容的表格,这样就比较流畅了

              tableIndex +=1;

             

              ReadData.readAllData();

              Vector<Vector<String>>  data_Vector =

                          ReadData.data_SortByEntity_HashMap.get(selectedEntityName);

              tableModel[tableIndex%2].setDataVector(data_Vector, columnIdentifier);

              TableUtils.fitTableColumns(dataTable[tableIndex%2]);

            

             if( isFinish ){

                  return;

              }

              //table有足够的时间刷新界面

              try {

                  Thread.sleep(500);

              } catch (InterruptedException e) {

                  // TODO Auto-generated catch block

                  e.printStackTrace();

                  return;

              }

             

              //记录上次的水平和垂直的滚动条的位置

              JScrollBar scrollbar_X = scrollPane.getHorizontalScrollBar();

              JScrollBar scrollbar_Y = scrollPane.getVerticalScrollBar();

              scrollbarLastPositon_X = scrollbar_X.getValue();

              scrollbarLastPositon_Y = scrollbar_Y.getValue();

             

              //显示另一个table的内容

              scrollPane.getViewport().add(dataTable[tableIndex%2]);

 

              //将水平和垂直滚动条设置到上次的位置

              scrollbar_X.setValue(scrollbarLastPositon_X);

              scrollbar_Y.setValue(scrollbarLastPositon_Y);

   

              if( isFinish ){

                  return;

              }

             

              long timeRemained =flashTime - (System.currentTimeMillis() - start);

             

              System.out.println("flashTime = "+flashTime);

              System.out.println("timeUsed = "+(System.currentTimeMillis() - start));

              System.out.println("timeRemained = "+timeRemained);

              System.out.println();

             

              if(  timeRemained > 0 ){

                  try {

                     Thread.sleep(timeRemained);

                  } catch (InterruptedException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

                     return;

                  }

              }

             

           }

       }

    }

 

 

 

完整的程序代码:

 

package edu.scut.es.Monitor;

 

import javax.swing.JPanel;

import javax.swing.JLabel;

import javax.swing.JComboBox;

import javax.swing.JScrollBar;

import javax.swing.JScrollPane;

import java.awt.BorderLayout;

import java.awt.Dimension;

import java.awt.FlowLayout;

import javax.swing.border.TitledBorder;

import java.awt.Font;

import javax.swing.JTable;

import javax.swing.table.DefaultTableModel;

import javax.swing.UIManager;

import java.awt.Color;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Vector;

import javax.swing.DefaultComboBoxModel;

 

public class DataCollectingCondition extends JPanel implements ActionListener {

        

         private static final long serialVersionUID = 3721614984672541469L;

         //两个JTable,用于流畅显示向Table中快速刷新的数据

         private JTable[]  dataTable = new JTable[2];

         //两个DefaultTableModel,tableModel[0]对应dataTable[0],

         //tableModel[1]对应dataTable[1],,用于流畅显示向Table中快速刷新的数据

         private DefaultTableModel[] tableModel = new DefaultTableModel[2] ;

         private int tableIndex = 0; //记录当前显示的table下标

         private Vector<String> columnIdentifier ;//行标题

         private JScrollPane scrollPane;

         private JComboBox comboBox_entityName ;

         private ReadDataThread readDataThread;

         private String selectedEntityName = "全部实体";

        

        

        

         public DataCollectingCondition() {

        

                   initGUI();

                  

                   //读数据线程

               //startReadDataThread();

         }

        

        //初始化用户界面

         private void initGUI(){

                   setBorder(null);

                   setLayout(new BorderLayout(5, 10));

                  

                   JPanel panel_choose = new JPanel();

                   panel_choose.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "\u8BF7\u9009\u62E9\u8BBE\u5907\u540D\u79F0", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 70, 213)));

                   add(panel_choose, BorderLayout.NORTH);

                   panel_choose.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));

                  

                   JLabel label = new JLabel("采集实体:");

                   label.setFont(new Font("SimSun", Font.BOLD, 20));

                   panel_choose.add(label);

                  

                  comboBox_entityName = new JComboBox();

                   comboBox_entityName.setModel(new DefaultComboBoxModel

                                    (MonitorPanel.configuratedEntity_List.toArray()));

                   comboBox_entityName.addItem("全部实体");

                   comboBox_entityName.setSelectedItem("全部实体");

                   comboBox_entityName.setFont(new Font("SimSun", Font.BOLD, 20));

                   comboBox_entityName.setPreferredSize(new Dimension(150,50));

                   panel_choose.add(comboBox_entityName);

                  

                   JPanel panel_table = new JPanel();

                   panel_table.setBorder(new TitledBorder(null, "数据采集状况实时监测",

                             TitledBorder.LEADING, TitledBorder.TOP, null, null));

                   panel_table.setLayout(new BorderLayout(0, 0));

                   add(panel_table);

                  

                   scrollPane =new JScrollPane();

                   panel_table.add(scrollPane,BorderLayout.CENTER);

                  

                  

                   dataTable[0] = new StyleTable();

                   dataTable[1] = new StyleTable();

                   tableModel[0] = new DefaultTableModel(

                        new Object[][] {

                {"1","XXXXX", "XXXXX", "XXXXX", "通过WebService拿不到数据",

                  new SimpleDateFormat("yyyy-MM-dd mm:HH:ss").format(new Date())}

                                               },

             new String[] {"序号","数据名称", "数据编码", "所属实体", "数据值", "采集时间"}

                   );

                   tableModel[1] = new DefaultTableModel(

                          new Object[][] {

                  {"1","XXXXX", "XXXXX", "XXXXX", "通过WebService拿不到数据",

                   new SimpleDateFormat("yyyy-MM-dd mm:HH:ss").format(new Date())}

                           },

             new String[] {"序号","数据名称", "数据编码", "所属实体", "数据值", "采集时间"}

                   );

                   dataTable[0].setModel(tableModel[0]);

                   dataTable[1].setModel(tableModel[1]);

                  

                   scrollPane.getViewport().add(dataTable[0]);

                  

                   columnIdentifier =  new Vector<String>();

                   columnIdentifier.add("序号");

                   columnIdentifier.add("数据名称");

                   columnIdentifier.add("数据编码");

                   columnIdentifier.add("所属实体");

                   columnIdentifier.add("数据值");

                   columnIdentifier.add("采集时间");

                  

                   comboBox_entityName.addActionListener(this);

         }

        

       //停止读数据线程

         public void stopReadDataThread(){

                   readDataThread.isFinish = true;

                   Thread.interrupted();

                   readDataThread = null;

         }

         //开启读数据线程

         public void startReadDataThread(){

                   if( readDataThread == null ){

                            readDataThread = new ReadDataThread();

                            readDataThread.start();

                                 

         }

        //读数据线程,把数据读取上来之后,放入table中

         @SuppressWarnings("unused")

         private class ReadDataThread extends Thread{

                   boolean isFinish = false;

                  

                   long flashTime = 1000;//刷新数据的周期 ,1s

                  

                   //用于记录上次水平和垂直的滚动条的位置

                   int scrollbarLastPositon_X ;

                   int scrollbarLastPositon_Y;

                  

                   long start ;

                  

                   public void run(){

                           

                            Vector<Vector<String>> dataVector;

                            while( true ){

                                    

                                     start = System.currentTimeMillis();

                                    

                                     if( isFinish ){

                                               return;

                                     }

                                    

                         //用于让另外一个表格来装载最新的数据,之前的表格任然显示之前的数据,

                         //待装载最新数据的表格完成一系列耗时的动作后,再由之前的显示旧内容的

                         //表格切换到该显示最新内容的表格,这样就比较流畅了

                                     tableIndex +=1;

                                    

                                     ReadData.readAllData();

                                     Vector<Vector<String>>  data_Vector = ReadData.data_SortByEntity_HashMap.get(selectedEntityName);

                                     tableModel[tableIndex%2].setDataVector(data_Vector, columnIdentifier);

                                     TableUtils.fitTableColumns(dataTable[tableIndex%2]);

                                     //让table有足够的时间刷新界面

                                     if( isFinish ){

                                               return;

                                     }

                                     try {

                                               Thread.sleep(500);

                                     } catch (InterruptedException e) {

                                               // TODO Auto-generated catch block

                                               e.printStackTrace();

                                               return;

                                     }

                                    

                                     //记录上次的水平和垂直的滚动条的位置

                                     JScrollBar scrollbar_X = scrollPane.getHorizontalScrollBar();

                                     JScrollBar scrollbar_Y = scrollPane.getVerticalScrollBar();

                                     scrollbarLastPositon_X = scrollbar_X.getValue();

                                     scrollbarLastPositon_Y = scrollbar_Y.getValue();

                                    

                                     //显示另一个table的内容

                                     scrollPane.getViewport().add(dataTable[tableIndex%2]);

 

                                     //将水平和垂直滚动条设置到上次的位置

                                     scrollbar_X.setValue(scrollbarLastPositon_X);

                                     scrollbar_Y.setValue(scrollbarLastPositon_Y);

        

                                     if( isFinish ){

                                               return;

                                     }

                                    

                                     long timeRemained =flashTime - (System.currentTimeMillis() - start);

                                    

                                     System.out.println("flashTime = "+flashTime);

                                     System.out.println("timeUsed = "+(System.currentTimeMillis() - start));

                                     System.out.println("timeRemained = "+timeRemained);

                                     System.out.println();

                                    

                                     if(  timeRemained > 0 ){

                                               try {

                                                        Thread.sleep(timeRemained);

                                               } catch (InterruptedException e) {

                                                        // TODO Auto-generated catch block

                                                        e.printStackTrace();

                                                        return;

                                               }

                                     }

                                    

                            }

                   }

         }

         public void actionPerformed(ActionEvent e) {

                   // TODO Auto-generated method stub

          Object source = e.getSource(); 

          if( source == comboBox_entityName ){

                selectedEntityName = comboBox_entityName.getSelectedItem().toString();

          }

         }

 

}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有