Java 如何以增量方式绘制JTable单元格?

Java 如何以增量方式绘制JTable单元格?,java,swing,jtable,paintcomponent,Java,Swing,Jtable,Paintcomponent,如何防止JTable擦除先前绘制的单元格?(完整的SSCCE如下所示) 此表中的每个单元格以1%的概率随机更改其颜色,并且每隔20毫秒调用JTable#repaint() 以下是单元组件的代码: class MyCell extends JComponent { private Color color = null; private final Random rand = new Random(); private final double probability =

如何防止JTable擦除先前绘制的单元格?(完整的SSCCE如下所示)

此表中的每个单元格以1%的概率随机更改其颜色,并且每隔20毫秒调用
JTable#repaint()

以下是单元组件的代码:

class MyCell extends JComponent {
    private Color color = null;
    private final Random rand = new Random();
    private final double probability = 0.01;  // change color with probability 1%
    @Override
    public void paintComponent(Graphics g){
        if (color == null || rand.nextDouble() < probability){
            color = new Color(rand.nextFloat(), rand.nextFloat(), rand.nextFloat());            
        }        
        g.setColor(color);
        g.fillRect(0, 0, getWidth(), getHeight());        
    }
}
class MyCell扩展了JComponent{
私有颜色=空;
私有最终随机兰德=新随机();
私有最终双概率=0.01;//以1%的概率更改颜色
@凌驾
公共组件(图形g){
if(color==null | | rand.nextDouble()<概率){
颜色=新颜色(rand.nextFloat(),rand.nextFloat(),rand.nextFloat());
}        
g、 设置颜色(颜色);
g、 fillRect(0,0,getWidth(),getHeight());
}
}
颜色不会以99%的概率变化,所以我不需要重新绘制这些单元格。我尝试以下实现(仅在颜色更改时绘制):

class MyCell扩展了JComponent{
私有颜色=空;
私有最终随机兰德=新随机();
私有最终双概率=0.01;//以1%的概率更改颜色
@凌驾
公共组件(图形g){
if(color==null | | rand.nextDouble()<概率){
颜色=新颜色(rand.nextFloat(),rand.nextFloat(),rand.nextFloat());
g、 设置颜色(颜色);
g、 fillRect(0,0,getWidth(),getHeight());
}        
}
}
结果如下:

  • 请仅在组件决定有效涂漆的情况下,建议如何有效涂漆。我需要消除任何不必要的绘画,并尽可能降低CPU利用率
  • 另外,请告知,为什么这个小应用程序在普通PC上使用了如此多的~10-15%的CPU
以下是完整的SSCCE:

    import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

class MyCell extends JComponent {
    private Color color = null;
    private final Random rand = new Random();
    private final double probability = 0.01;  // change color with probability 1%
    @Override
    public void paintComponent(Graphics g){
        if (color == null || rand.nextDouble() < probability){
            color = new Color(rand.nextFloat(), rand.nextFloat(), rand.nextFloat());            
        }        
        g.setColor(color);
        g.fillRect(0, 0, getWidth(), getHeight());        
    }
}

class MyTableModel extends DefaultTableModel {
    final private int NROWS = 10;
    final private int NCOLS = 5;
    final private MyCell[][] cells = new MyCell[NROWS][NCOLS];

    public MyTableModel(){
        for (int i = 0; i < NROWS; i++){
            for (int j = 0; j < NCOLS; j++){
                cells[i][j] = new MyCell();
            }
        }
    }    
    public int getRowCount() {
        return NROWS;
    }
    @Override
    public int getColumnCount() {
        return NCOLS;
    }
    @Override
    public Object getValueAt(final int row, final int column) {
        return cells[row][column];
    }
    @Override
    public boolean isCellEditable(final int row, final int column) {
        return false;
    }    
}

public class JTableIncremental extends JTable {
    private final long period = 20; // repaint every [ms]
    JTableIncremental(){
        setModel(new MyTableModel());        
    }
    @Override
    public Component prepareRenderer(final TableCellRenderer renderer, final int row, final int column) {
        return (Component)dataModel.getValueAt(row, column);
    }    
    public void start(){
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                repaint();
            }
        }, 0, period);
    }

    public static void main( String[] args ) throws Throwable {
        final JFrame frame = new JFrame("Random colors table");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JTableIncremental table = new JTableIncremental();
        frame.add(table);
        frame.pack();
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                frame.setVisible(true);
                table.start();
            }
        });
    }    
}
导入java.awt.Color;
导入java.awt.Component;
导入java.awt.Graphics;
导入java.util.Random;
导入java.util.Timer;
导入java.util.TimerTask;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
导入javax.swing.JTable;
导入javax.swing.SwingUtilities;
导入javax.swing.table.DefaultTableModel;
导入javax.swing.table.TableCellRenderer;
类MyCell扩展了JComponent{
私有颜色=空;
私有最终随机兰德=新随机();
私有最终双概率=0.01;//以1%的概率更改颜色
@凌驾
公共组件(图形g){
if(color==null | | rand.nextDouble()<概率){
颜色=新颜色(rand.nextFloat(),rand.nextFloat(),rand.nextFloat());
}        
g、 设置颜色(颜色);
g、 fillRect(0,0,getWidth(),getHeight());
}
}
类MyTableModel扩展了DefaultTableModel{
最终私有整数NROWS=10;
最终专用int NCOLS=5;
最终私有MyCell[][]单元=新MyCell[NROWS][NCOLS];
公共MyTableModel(){
对于(int i=0;i
    import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

class MyCell extends JComponent {
    private Color color = null;
    private final Random rand = new Random();
    private final double probability = 0.01;  // change color with probability 1%
    @Override
    public void paintComponent(Graphics g){
        if (color == null || rand.nextDouble() < probability){
            color = new Color(rand.nextFloat(), rand.nextFloat(), rand.nextFloat());            
        }        
        g.setColor(color);
        g.fillRect(0, 0, getWidth(), getHeight());        
    }
}

class MyTableModel extends DefaultTableModel {
    final private int NROWS = 10;
    final private int NCOLS = 5;
    final private MyCell[][] cells = new MyCell[NROWS][NCOLS];

    public MyTableModel(){
        for (int i = 0; i < NROWS; i++){
            for (int j = 0; j < NCOLS; j++){
                cells[i][j] = new MyCell();
            }
        }
    }    
    public int getRowCount() {
        return NROWS;
    }
    @Override
    public int getColumnCount() {
        return NCOLS;
    }
    @Override
    public Object getValueAt(final int row, final int column) {
        return cells[row][column];
    }
    @Override
    public boolean isCellEditable(final int row, final int column) {
        return false;
    }    
}

public class JTableIncremental extends JTable {
    private final long period = 20; // repaint every [ms]
    JTableIncremental(){
        setModel(new MyTableModel());        
    }
    @Override
    public Component prepareRenderer(final TableCellRenderer renderer, final int row, final int column) {
        return (Component)dataModel.getValueAt(row, column);
    }    
    public void start(){
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                repaint();
            }
        }, 0, period);
    }

    public static void main( String[] args ) throws Throwable {
        final JFrame frame = new JFrame("Random colors table");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JTableIncremental table = new JTableIncremental();
        frame.add(table);
        frame.pack();
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                frame.setVisible(true);
                table.start();
            }
        });
    }    
}