更新java表

时间:2013-02-04 21:22:30

标签: java swing jtable defaulttablemodel

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

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属性,这有助于他提高速度但仍然无法解决。 setDataVector和BreakTimev21.jTable1.setValueAt(StartIni2.one(), 0, 1);一样,StartIni2现在使用java属性而不是ini4j。

3 个答案:

答案 0 :(得分:4)

您不应为计时器中的每次更新更改表模型。相反,您应该通过继承AbstractTableModel来实现自己的模型。每次在计时器中更新数据时,您只更改已更改的模型的值,并使用AbstractTableModel的fire *()方法让Swing知道您做了什么。

请参阅Javadoctutorial

答案 1 :(得分:2)

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

没有理由不能使用DefaultTableModel。当您想要更改模型中的现有数据时,您只需调用:

model.setValueAt(...)

并且表格将自动重新绘制单元格。

因此,当Timer触发并更新表时,您可以使用新数据创建二维数组。然后循环遍历数组并将数组中的值与模型中的值进行比较。如果您发现差异,请按照我的建议更新模型。

或者另一种方法是继续使用现有模型,并使用DefaultTableModel的setDataVector()方法将数组中的所有数据替换为数组中的数据。

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

table.setAutoCreateColumnsFromModel(false); 

这样可以更快地更新模型,因为它只是更新数据而不会重新创建所有TableColumns等。

使用这里的任何一种方法都不需要你使用tableChanged()方法。

答案 2 :(得分: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而不是命名值。