2013-02-04 64 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而不是命名值。