[英]Update JTable Based on Tiem
I am using a JTable to display values produced by a long running process and I want the appearance to change as values "age out".我正在使用 JTable 来显示由长时间运行的过程产生的值,并且我希望外观随着值“老化”而改变。 There is a timestamp indicating the last time each row of data changed and I want to display this in a different format when it is more than a minute (or an hour) old.
有一个时间戳指示每行数据最后一次更改的时间,当它超过一分钟(或一小时)时,我想以不同的格式显示它。
I might change the background color for active rows but I have not worked on that yet.我可能会更改活动行的背景颜色,但我还没有这样做。
Relevant sections of my code are below.我的代码的相关部分如下。 I call repaint, and I've tried calling fireTableDataChanged without any luck.
我打电话给 repaint,我试过打电话 fireTableDataChanged 没有任何运气。 The older values never change to the "inactive" format.
旧值永远不会更改为“非活动”格式。 If I quit and restart, the older values get drawn with the inactive format but it does not happen dynamically.
如果我退出并重新启动,旧值会以非活动格式绘制,但它不会动态发生。
private final long startup = System.currentTimeMillis ();
private static long minuteMillis = 1000 * 60;
private final SimpleDateFormat inactiveFormat = new SimpleDateFormat ("HH:mm");
private final SimpleDateFormat currentFormat = new SimpleDateFormat ("HH:mm:ss");
private long timestamp = 0; // Obtained from data
// Part of the table model
@Override // Subclass of DefaultTableModel
public Object getValueAt (int row, int column)
{
if (timestamp < startup - minuteMillis)
{
return inactiveFormat.format (timestamp);
}
return currentFormat.format (timestamp);
}
final Thread thread = new Thread ()
{
@Override
public void run ()
{
while (true)
{
try
{
Thread.sleep (100);
timestamp = readFromFile(); // Read from elsewhere
// model.fireTableDataChanged (); // Does not help
table.repaint (); // Does not update older values
}
catch (final Throwable e)
{
e.printStackTrace ();
}
}
}
};
thread.start ();
I found the problem.我发现了问题。 The variable 'startup' in the code above should be System.currentTimeMillis().
上面代码中的变量“startup”应该是 System.currentTimeMillis()。 Here is a working demo in case anyone else wants to do something similar.
这是一个工作演示,以防其他人想做类似的事情。 I think it is fun.
我认为这很有趣。
package demo;
import java.io.File;
import java.text.SimpleDateFormat;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import org.apache.logging.log4j.*;
public class TableDemo extends JPanel
{
private final Logger logger = LogManager.getFormatterLogger (this.getClass ());
public static void main (String[] args)
{
final TableDemo app = new TableDemo ();
app.execute ();
app.cycle ();
}
private final SimpleDateFormat inactiveFormat = new SimpleDateFormat ("HH:mm");
private final SimpleDateFormat activeFormat = new SimpleDateFormat ("HH:mm:ss");
/** Timestamp of learning data. */
private final Long[][] timestamp = {{0l, 0l, 0l}, {0l, 0l, 0l}};
private static long minuteMillis = 1000 * 10; // Reduced for testing
/**
* Create table model with data
*
* @see https://www.codejava.net/java-se/swing/a-simple-jtable-example-for-display
*/
private final DefaultTableModel model = new DefaultTableModel ()
{
@Override
public int getColumnCount ()
{
return timestamp[0].length;
}
@Override
public int getRowCount ()
{
return timestamp.length;
}
@Override
public Object getValueAt (int row, int column)
{
String result = "-";
if (row < timestamp.length)
{
if (column < timestamp[0].length)
{
final long value = timestamp[row][column];
if (value < System.currentTimeMillis () - minuteMillis)
{
result = inactiveFormat.format (value);
}
else
{
result = activeFormat.format (value);
}
}
}
return result;
}
};
private final JTable table = new JTable (model);
private final JFrame frame = new JFrame ("Demo");
public TableDemo ()
{
frame.setContentPane (new JScrollPane (table));
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
}
public void execute ()
{
frame.pack ();
frame.setVisible (true);
}
public void cycle ()
{
final Thread thread = new Thread ()
{
@Override
public void run ()
{
// Make it easy to cd to the right place
logger.info (new File ("data.txt").getAbsolutePath ());
while (true)
{
try
{
Thread.sleep (1000);
for (int i = 0; i < table.getRowCount (); i++)
{
// From bash:
// > touch data10.txt ; touch data02.txt
for (int j = 0; j < table.getColumnCount (); j++)
{
final String filename = String.format ("data%d%d.txt", i, j);
final File file = new File (filename);
if (file.exists ())
{
timestamp[i][j] = file.lastModified ();
}
else
{
timestamp[i][j] = 0L;
}
}
}
table.repaint ();
}
catch (final Throwable e)
{
e.printStackTrace ();
}
}
}
};
thread.start ();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.