2013-02-04 34 views
2

我有一个计时器类更新我的表,但我发现影响更改的唯一方法是使用此代码。这实质上是一个休息时间应用程序。我正在使用ini4j来读取网络上的ini文件。它确实有效,但它正在与我正在做的其他事情一起创造速度问题。使用目前的设置,它可以或多或少地正确显示时间,但当我添加更多人时会开始滞后。如果你的答案是学习jTables,这不会有帮助大声笑。我无法使用jtables和fireupdate更改来实现这个功能。更新java表

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.File; 
import java.io.IOException; 
import java.text.SimpleDateFormat; 
import java.util.TimeZone; 

import javax.swing.JLabel; 
import javax.swing.JTable; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 

import main.Break; 

import org.ini4j.InvalidFileFormatException; 
import org.ini4j.Wini; 

public class TableUpdate extends JLabel implements ActionListener { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 4357754555235469274L; 
    private volatile static boolean running = true; 
    SimpleDateFormat UTC = new SimpleDateFormat("HH:mm:ss");  
    Timer breaktimer = new Timer(1000, this); 
    public static long now = System.currentTimeMillis(); 

    final static String local = ConfigIni.location(); 
    final static File FILENAME = new File(local+"\\master.ini"); 

    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     Runnable runnable = new Runnable() { 
      public void run() { 

        tableupdate(); 
      }}; 
      SwingUtilities.invokeLater(runnable); 
     } 

    public void tableupdate() { 
     UTC.setTimeZone(TimeZone.getTimeZone("UTC"));   
      Wini ini = null; 
      try { 
       ini = new Wini(FILENAME); 
      } catch (InvalidFileFormatException e1) {    
       e1.printStackTrace(); 
      } catch (IOException e1) {    
       e1.printStackTrace(); 
      } 
      String number = ini.get("analysts", "number"); 

      if (number.equals("8")) { 
       Break.jTable1.setModel(new javax.swing.table.DefaultTableModel(
       new Object [][] { 
       {AnalystIni.one(), StartIni.one(), BreakIni.one(), TypeIni.one()}, 
       {AnalystIni.two(), StartIni.two(), BreakIni.two(), TypeIni.two()}, 
       {AnalystIni.three(), StartIni.three(), BreakIni.three(), TypeIni.three()}, 
       {AnalystIni.four(), StartIni.four(), BreakIni.four(), TypeIni.four()}, 
       {AnalystIni.five(), StartIni.five(), BreakIni.five(), TypeIni.five()}, 
       {AnalystIni.six(), StartIni.six(), BreakIni.six(), TypeIni.six()}, 
       {AnalystIni.seven(), StartIni.seven(), BreakIni.seven(), TypeIni.seven()}, 
       {AnalystIni.eight(), StartIni.eight(), BreakIni.eight(), TypeIni.eight()},    
         }, 
         new String [] { 
         "Analyst", "Start Time", "Timer", "Status" 
         } 
        )); 


      } 
    } 

    public void start() { 

     running = true; 
     breaktimer.start(); 
    } 

    public void stop() { 

     running = false; 
    } 

    public static void main(String[] args) {  

     java.awt.EventQueue.invokeLater(new Runnable() { 
     public void run() {   
      TableUpdate jtl = new TableUpdate(); 
      jtl.start(); 
      } 
    });      
    } 
} 

这里是我的表

try { 
      jTable1.setModel(new javax.swing.table.DefaultTableModel(

       new Object [][] { 
        {AnalystIni.one(), StartIni.one(), BreakIni.one(), TypeIni.one()}, 
        {AnalystIni.two(), StartIni.two(), BreakIni.two(), TypeIni.two()}, 
        {AnalystIni.three(), StartIni.three(), BreakIni.three(), TypeIni.three()}, 
        {AnalystIni.four(), StartIni.four(), BreakIni.four(), TypeIni.four()}, 
        {AnalystIni.five(), StartIni.five(), BreakIni.five(), TypeIni.five()}, 
        {AnalystIni.six(), StartIni.six(), BreakIni.six(), TypeIni.six()}, 
        {AnalystIni.seven(), StartIni.seven(), BreakIni.seven(), TypeIni.seven()}, 
        {AnalystIni.eight(), StartIni.eight(), BreakIni.eight(), TypeIni.eight()} 
       }, 
       new String [] { 
        "Analyst", "Time Started", "Timer", "Status" 
       } 
      )); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     JTableHeader header = jTable1.getTableHeader(); 
     header.setBackground(SettingsIni.jtable1h()); 
     header.setForeground(SettingsIni.jtable1ht()); 
     jTable1.setBackground(SettingsIni.jtable1()); 
     jTable1.setForeground(SettingsIni.jtable1t()); 
     jTable1.setOpaque(false); 
     jScrollPane1.setViewportView(jTable1); 
     jScrollPane1.setOpaque(false); 
     jTable1.setFocusable(false); 
     //jScrollPane1.setBorder(BorderFactory.createMatteBorder(0,1,0,0,Color.black)); 
     jScrollPane1.setBorder(BorderFactory.createEmptyBorder(0,0,0,0)); 

     jScrollPane1.getViewport().setOpaque(false); 
     final Color jcolor1 = new Color(0, true); 
     jScrollPane1.getViewport().setBackground(jcolor1); 

     getRootPane().setBorder(BorderFactory.createEmptyBorder(0,0,0,0));//removed border 

我加入这个代码与表中的类的代码。

@Override 
    public void tableChanged(TableModelEvent e) { 
     int row = e.getFirstRow(); 
     int column = e.getColumn(); 
     TableModel model = (TableModel)e.getSource(); 
     String columnName = model.getColumnName(column); 
     Object data = model.getValueAt(row, column);   
    } 

而且我在看这个添加到我的计时器,但它仍然感觉就像我失去了一些东西。

BreakTimev21.jTable1.tableChanged(new TableModelEvent(BreakTimev21.jTable1.getModel())); 

从camickr我在我的tableupdate类中试过这个。仍然没有帮助,它确实更新,但有点让人毛骨悚然。我也记得用jTable1.setAutoCreateColumnsFromModel(false);

Object [][] data = { 
         {a1, StartIni2.one(), BreakIni2.one(), TypeIni2.one()}, 
         {a2, StartIni2.two(), BreakIni2.two(), TypeIni2.two()}, 
         {a3, StartIni2.three(), BreakIni2.three(), TypeIni2.three()}, 
         {a4, StartIni2.four(), BreakIni2.four(), TypeIni2.four()}, 
         {a5, StartIni2.five(), BreakIni2.five(), TypeIni2.five()}, 
         {a6, StartIni2.six(), BreakIni2.six(), TypeIni2.six()}, 
         {a7, StartIni2.seven(), BreakIni2.seven(), TypeIni2.seven()}, 
         {a8, StartIni2.eight(), BreakIni2.eight(), TypeIni2.eight()}, 
        }; 
        String [] columnNames = { 
         "Analyst", "Start Time", "Timer", "Status" 
        }; 

        TableModel model = BreakTimev21.jTable1.getModel(); 
        ((DefaultTableModel) model).setDataVector(data, columnNames); 

我停止使用ini4j为TABLEUPDATE的读取部分,只是用java性能,这有助于witht他加快了很多,但仍然没有解决。 setDataVector的工作原理与BreakTimev21.jTable1.setValueAt(StartIni2.one(), 0, 1);一样StartIni2现在使用java属性而不是ini4j。

回答

2

首先,您不应该扩展JLabel来实现TableUpdate类。

没有理由不能使用DefaultTableModel。当您想在模型中更改现有数据你要做的就是调用:

model.setValueAt(...) 

和表将自动重新绘制的单元格。

所以当计时器火灾和它的时间来更新你可以只创建新数据2维数组的表。然后循环访问数组,并将数组中的值与模型中的值进行比较。当你发现一个区别时,你按照上面的建议更新模型。

或者另一种方法是使用现有的模型来保持,并通过使用的DefaultTableModel的到setDataVector()方法代替与所述阵列中的数据模型中的所有数据。

如果您在初始创建JTable中后使用第二种方法,那么你将要使用:

table.setAutoCreateColumnsFromModel(false); 

这将使模型的更新速度更快,因为它只是更新的数据,并且不会重新创建所有在TableColumn来等

无论使用的方法在这里没有必要为你与tableChanged()方法玩。

+0

我能得到他们两人的更新,但它仍然是缓慢的,它是罚款8行,但在16+它开始滞后。 – user1753429

+0

我结束了不使用ini4j和公正使用java的道具,它的速度帮助很大,所以也许问题不在桌子上,不过你答对我最有帮助,谢谢! – user1753429

4

对于计时器中的每个更新,您都不应更改表格模型。相反,你应该实现你自己的模型,通过继承AbstractTableModel。每次在计时器中更新数据时,只更改已更改模型的值,并使用AbstractTableModel的fire *()方法让Swing知道您已完成了哪些工作。

查看Javadoctutorial

+0

据我所知,我已阅读教程,并看了很多帖子。它只是没有陷入。我想我在计时器中添加'BreakTimev21.jTable1.tableChanged(新的TableModelEvent(BreakTimev21.jTable1.getModel()));'而不是重新制作表格,但我该怎么处理这个@Override public void tableChanged(TableModelEvent e){int row = e.getFirstRow(); int column = e.getColumn(); TableModel model =(TableModel)e.getSource(); String columnName = model.getColumnName(column); Object data = model.getValueAt(row,column); ''?我觉得我从中错过了一些东西。 – user1753429

+0

我不知道你在这里做什么。你说你已经阅读过这个教程,但是你仍然没有按照它推荐的方式去做,并且你提出了一堆不遵循这个方向的代码(并且你的tableChanged方法什么都不做)。也许你有一个完全合理的理由,不要在AbstractTableModel的子类中做你的东西,但如果我们不知道为什么,我们不能帮助你。 –

+0

我提到了其他选项,因为这是我通过阅读其他帖子发现的。它也在教程中。不知道如何将其作为'AbstractTableModel'继承。该教程甚至会说“...... //对数据做些什么......”,而没有解释要做什么。它还说,“考虑继承AbstractTableModel上,如果的DefaultTableModel是不是一个合适的我不知道的DefaultTableModel适合或不属于Oracle exmaples的表中没有说明如何使用tablechanged – user1753429

1

问题是,您正在将数据复制到Object [] []数组中,并将其用于表模型。但是当你的数据发生变化时,不清楚如何告诉表模型哪个值发生了变化。

相反,子类和AbstractTableModel上重写以下的(至少):

public int getRowCount(); 
public int getColumnCount(); 
public Object getValueAt(int row, int column); 
isCellEditable(int rowIndex, int columnIndex); 
public Object setValueAt(Object aValue, int rowIndex, int columnIndex); 

当setValueAt被调用时,找出哪些对象备份/属性进行修改,并对其进行修改。然后调用fireTableCellUpdated(int row,int column)方法。

作为一个方面说明,该方法调用你在AnalystIni中使用对我来说似乎很腥,就像它们会限制你在表中的八行一样。考虑使用List而不是命名值。