如何防止JTable擦除以前涂过的细胞? (完整的SSCCE如下)
此表中的每个单元格以1%的概率随机改变颜色,每20毫秒调用JTable#repaint()
。
以下是Cell组件的代码:
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());
}
}
颜色不会以99%的概率变化,所以我不需要重新绘制这样的细胞。我尝试以下实现(仅在颜色改变时绘画):
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());
}
}
}
结果如下:
这是完整的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();
}
});
}
}