编辑 :我发现以下代码有效。看来早期的代码出现了问题。但是,我仍然有一个亟待解决的问题,这个代码是否是一个好习惯?这是在主应用程序线程和Swing事件派发线程之间共享Swing对象底层的模型数据的可接受方法吗?
package com.guitest;
import java.awt.*;
import java.util.*;
import javax.swing.*;
public class Test {
public static void main(String[] args) {
new Test().run();
}
public void run() {
Board board = new Board();
board.createBoard();
board.setTileValue(2, 2, 3);
board.revalidate();
board.repaint();
}
@SuppressWarnings("serial")
public class Board extends JFrame {
final int tileSize = 100;
final int numberOfRows = 2;
final int numberOfCols = 3;
private final Map<Integer, Integer> _tiles;
public Board() {
_tiles = Collections.synchronizedMap(new HashMap<Integer, Integer>(numberOfRows*numberOfCols));
for (int row = 0; row < numberOfRows; row++) {
for (int col = 1; col <= numberOfCols; col++) {
_tiles.put(row*numberOfCols+col, 1);
}
}
}
public void setTileValue(int row, int col, int value) {
_tiles.put(row*(numberOfCols-1)+col, value);
}
public void createBoard() {
SwingUtilities.invokeLater(new Runnable() {
@Override public void run() {
setLayout(new GridLayout(numberOfRows, numberOfCols, 0, 0));
for (int row = 0; row < numberOfRows; row++) {
for (int col = 1; col <= numberOfCols; col++) {
add(createPanelFor(row, col));
}
}
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(numberOfCols*tileSize, numberOfRows*tileSize);
setVisible(true);
}
});
}
public JPanel createPanelFor(final int row, final int col) {
return new JPanel() {
@Override protected void paintComponent(Graphics g) {
g.setColor((col % 2 == 0) == (row % 2 == 0) ? Color.BLACK : Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
String string = String.valueOf(_tiles.get(row*numberOfCols+col));
g.setColor(Color.RED);
g.drawString(string, getHeight() / 2, getWidth() / 2);
}
};
}
}
}