2

我有一个计时器类来更新我的表,但我发现影响更改的唯一方法是使用此代码。它本质上是一个休息时间的应用程序。我正在使用 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 一样。

4

3 回答 3

4

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

请参阅Javadoc教程

于 2013-02-04T21:45:49.200 回答
2

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

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

model.setValueAt(...)

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

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

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

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

table.setAutoCreateColumnsFromModel(false); 

这将使模型的更新更快,因为它只是更新数据并且不会重新创建所有 TableColumns 等。

使用此处的任何一种方法,您都无需使用 tableChanged() 方法。

于 2013-02-05T02:49:15.983 回答
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 中使用的方法调用对我来说似乎很可疑,就像它们会将您限制为表中的八行一样。考虑使用列表而不是命名值。

于 2013-02-04T23:44:27.363 回答