更新: 所以我发现了造成这个问题的原因。 当我的Java窗口最小化时,我的表格呈现每一行。有谁知道如何防止这种情况?
我有一个JXTable,它每秒都在不断更新,删除和添加行数据。我们谈论平均每秒修改10-20行。
通常,CPU使用率在5%到10%之间。当我们每秒钟发布数百次更新时,它可以达到15%。
但是,我们注意到,当我们的Java窗口最小化时,无论何时发生任何更新,我们的CPU使用率每次都会达到25%。我们设置了一个脚本,每隔5秒添加一行,当这一行出现时,我们看到CPU使用率达到了25%。
我能想到的唯一解释是使用 SwingUtilities.invokeAndWait()。我修改了后台线程中的行数据,并使用invokeAndWait来处理各种fireTableDataChanged()方法。
我使用invokeAndWait,因为我需要按顺序触发我的事件。例如,我删除了一些行,调用fireTableRowsDeleted(),然后我添加一些行并调用fireTableRowsInserted()。
为什么我的CPU使用率仅在表更新和窗口最小化时才达到25%?
答案 0 :(得分:2)
JTable
使用flyweight pattern仅渲染可见单元格,但主机操作系统可能通过干扰,例如通过尝试动画最小化的图标; profile可以肯定。无论原因是什么,publish()
更新了TableModel
doInBackground()
process()
的{{1}}更新,如SwingWorker
所示。工作人员将合并更新并以here,~30 Hz将其发送至TableModel
。然后,您的 protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.ScaleTransform(1.0f, -1.0f); //Invert coordinatesystem on screen
e.Graphics.TranslateTransform(420, -this.ClientRectangle.Height + 300); //PUT coordinate 0, 0 in the middle of screen
int min = 0;
int max = 250;
int x = 0;
int y = 0;
e.Graphics.DrawLine(Pens.LightSteelBlue, min-400, min, max+200, min); //X1,Y1,X2;Y2
e.Graphics.DrawLine(Pens.LightSteelBlue, min, min-250, min, max); //X1,Y1,X2;Y2
Brush aBrush = (Brush)Brushes.LightSteelBlue;
while (x <= max && y <= max)
{
y = x*x/128;
if (y > max)
break;
e.Graphics.FillRectangle(aBrush, x, y, 1, 1); //x,y,width,height
System.Threading.Thread.Sleep(10);
Application.DoEvents();
x++;
}
INPUT_FORMULA.Focus(); // textbox to enter formula
INPUT_FORMULA.Select(INPUT_FORMULA.Text.Length, 0);
}
可以按照对您的应用程序有意义的方式推迟更新事件。
答案 1 :(得分:2)
我使用invokeAndWait因为我需要按顺序启动我的事件
无需使用invokeAndWait()。你可以使用invokeLater()。事件仍将按照收到的顺序执行。
各种fireTableDataChanged()方法。
您不应该调用fireTableDataChanged。 TableModel将调用适当的fireXXX()方法。当您只能更改几行时,为什么要重新绘制整个表格。如有必要,RepaintManager会将多个绘制请求合并为一个。
编辑:
这是我躺在身边的一些代码。所有更新都在EDT上的模型上完成,代码不会调用fireXXX(...)方法:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableThread extends JFrame
implements ActionListener, Runnable
{
JTable table;
DefaultTableModel model;
int count;
public TableThread()
{
String[] columnNames = {"Date", "String", "Integer", "Decimal", "Boolean"};
Object[][] data =
{
{new Date(), "A", new Integer(1), new Double(5.1), new Boolean(true)},
{new Date(), "B", new Integer(2), new Double(6.2), new Boolean(false)},
{new Date(), "C", new Integer(3), new Double(7.3), new Boolean(true)},
{new Date(), "D", new Integer(4), new Double(8.4), new Boolean(false)}
};
model = new DefaultTableModel(data, columnNames);
table = new JTable( model );
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.setIgnoreRepaint(false);
JScrollPane scrollPane = new JScrollPane( table );
getContentPane().add( scrollPane );
JButton button = new JButton( "Start Thread to Update Table" );
button.addActionListener( this );
getContentPane().add(button, BorderLayout.SOUTH );
}
public void actionPerformed(ActionEvent e)
{
new Thread( this ).start();
table.requestFocus();
}
public void run()
{
Random random = new Random();
while (true)
{
final int row = random.nextInt( table.getRowCount() );
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
table.setValueAt( new Integer(count++), row, 2);
table.setRowSelectionInterval(row, row);
Object[] aRow = { new Date(), "f", row, new Double(123), new Boolean(true) };
model.addRow( aRow );
}
});
try { Thread.sleep(500); }
catch(Exception e) {}
}
}
public static void main(String[] args)
{
TableThread frame = new TableThread();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setVisible(true);
}
}
无论框架是可见还是最小化,CPU都是一致的。
如果您需要更多帮助,请发布与上述代码相同的SSCCE来证明问题。