最小化时更新时JTable高CPU使用率

时间:2015-11-20 21:46:34

标签: java swing jtable swingx swingutilities

更新: 所以我发现了造成这个问题的原因。 当我的Java窗口最小化时,我的表格呈现每一行。有谁知道如何防止这种情况?

我有一个JXTable,它每秒都在不断更新,删除和添加行数据。我们谈论平均每秒修改10-20行。

通常,CPU使用率在5%到10%之间。当我们每秒钟发布数百次更新时,它可以达到15%。

但是,我们注意到,当我们的Java窗口最小化时,无论何时发生任何更新,我们的CPU使用率每次都会达到25%。我们设置了一个脚本,每隔5秒添加一行,当这一行出现时,我们看到CPU使用率达到了25%。

我能想到的唯一解释是使用 SwingUtilities.invokeAndWait()。我修改了后台线程中的行数据,并使用invokeAndWait来处理各种fireTableDataChanged()方法。

我使用invokeAndWait,因为我需要按顺序触发我的事件。例如,我删除了一些行,调用fireTableRowsDeleted(),然后我添加一些行并调用fireTableRowsInserted()。

为什么我的CPU使用率仅在表更新和窗口最小化时才达到25%?

2 个答案:

答案 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来证明问题。