有很多方法可以让它发挥作用,具体取决于您想要实现的目标。
第一个示例仅使用 2D 图形 API 来呈现单元格并MouseMotionListener
监视突出显示的单元格。
![在此处输入图像描述](https://i.stack.imgur.com/WQ2JV.png)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestGrid01 {
public static void main(String[] args) {
new TestGrid01();
}
public TestGrid01() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private int columnCount = 5;
private int rowCount = 5;
private List<Rectangle> cells;
private Point selectedCell;
public TestPane() {
cells = new ArrayList<>(columnCount * rowCount);
MouseAdapter mouseHandler;
mouseHandler = new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
Point point = e.getPoint();
int width = getWidth();
int height = getHeight();
int cellWidth = width / columnCount;
int cellHeight = height / rowCount;
selectedCell = null;
if (e.getX() >= xOffset && e.getY() >= yOffset) {
int column = (e.getX() - xOffset) / cellWidth;
int row = (e.getY() - yOffset) / cellHeight;
if (column >= 0 && row >= 0 && column < columnCount && row < rowCount) {
selectedCell = new Point(column, row);
}
}
repaint();
}
};
addMouseMotionListener(mouseHandler);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
public void invalidate() {
cells.clear();
selectedCell = null;
super.invalidate();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int width = getWidth();
int height = getHeight();
int cellWidth = width / columnCount;
int cellHeight = height / rowCount;
int xOffset = (width - (columnCount * cellWidth)) / 2;
int yOffset = (height - (rowCount * cellHeight)) / 2;
if (cells.isEmpty()) {
for (int row = 0; row < rowCount; row++) {
for (int col = 0; col < columnCount; col++) {
Rectangle cell = new Rectangle(
xOffset + (col * cellWidth),
yOffset + (row * cellHeight),
cellWidth,
cellHeight);
cells.add(cell);
}
}
}
if (selectedCell != null) {
int index = selectedCell.x + (selectedCell.y * columnCount);
Rectangle cell = cells.get(index);
g2d.setColor(Color.BLUE);
g2d.fill(cell);
}
g2d.setColor(Color.GRAY);
for (Rectangle cell : cells) {
g2d.draw(cell);
}
g2d.dispose();
}
}
}
此示例确实使用窗口调整了网格的大小,但是使单元格固定大小将是一个微不足道的更改。
查看2D 图形了解更多详情
更新组件示例
此示例使用一系列JPanel
s 来表示每个单元格。
每个单元格都定义有固定的宽度和高度,并且不随主窗口调整大小。
![在此处输入图像描述](https://i.stack.imgur.com/UzgS1.png)
在此示例中,每个单元格面板都有自己的鼠标侦听器。重新编码并不会太难,这样主面板就有一个鼠标监听器,而是自己管理工作负载。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.border.MatteBorder;
public class TestGrid02 {
public static void main(String[] args) {
new TestGrid02();
}
public TestGrid02() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 5; col++) {
gbc.gridx = col;
gbc.gridy = row;
CellPane cellPane = new CellPane();
Border border = null;
if (row < 4) {
if (col < 4) {
border = new MatteBorder(1, 1, 0, 0, Color.GRAY);
} else {
border = new MatteBorder(1, 1, 0, 1, Color.GRAY);
}
} else {
if (col < 4) {
border = new MatteBorder(1, 1, 1, 0, Color.GRAY);
} else {
border = new MatteBorder(1, 1, 1, 1, Color.GRAY);
}
}
cellPane.setBorder(border);
add(cellPane, gbc);
}
}
}
}
public class CellPane extends JPanel {
private Color defaultBackground;
public CellPane() {
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
defaultBackground = getBackground();
setBackground(Color.BLUE);
}
@Override
public void mouseExited(MouseEvent e) {
setBackground(defaultBackground);
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(50, 50);
}
}
}