我正在尝试使用Swing类创建网格UI(5 * 5).我尝试了一个嵌套循环,并动态地将jPanel添加到jFrame.我还尝试在用户点击并删除时更改每个jPanel的背景颜色.
但是使用我的代码,每个单元格之间存在巨大差距,我无法使拖动事件起作用.
但是使用我的代码,每个单元格之间存在巨大差距,我无法使拖动事件起作用.
public class clsCanvasPanel extends JPanel { private static final int intRows = 5; private static final int intCols = 5; private List<JPanel> jpllist = new ArrayList<JPanel>(); public clsCanvasPanel() { /* * * Add eventListener to individual JPanel within CanvasPanel * * * TODO : * 1) mousePressed --> update Temperature and HeatConstant of clsElement Class * 2) start a new thread and * 3) call clsElement.run() method * * * Right Now : it updates the colours of the JPanel * */ MouseListener mouseListener = new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { JPanel panel = (JPanel) e.getSource(); Component[] components = panel.getComponents(); for (Component component : components) { component.setVisible(!component.isVisible()); component.setBackground(new Color(255,255,0)); } panel.revalidate(); panel.repaint(); } }; //TODO : refactoring GridLayout gdlyPlates = new GridLayout(); gdlyPlates.setColumns(intCols); gdlyPlates.setRows(intRows); gdlyPlates.setHgap(0); gdlyPlates.setVgap(0); setLayout(gdlyPlates); //TODO : refactoring for (int row = 0; row < intRows; row++) { for (int col = 0; col < intCols; col++) { JPanel panel = new JPanel(new GridBagLayout()); panel.setOpaque(false); JPanel jl = new JPanel(); jl.setVisible(true); panel.add(jl); panel.addMouseListener(mouseListener); jpllist.add(panel); add(panel); } } } }
所以现在我尝试创建一个面板并在其上绘制网格,然后检测网格上的鼠标位置,进一步更改每个单元格的颜色.
有人可以给我一些关于如何在JPanel上实现这个网格的建议,并改变所选单元格的颜色.
解决方法
有许多方法可以让它发挥作用,这取决于你想要实现的目标.
第一个示例仅使用2D Graphics API渲染单元格,使用MouseMotionListener监视突出显示的单元格.
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 Graphics了解更多详情
使用组件示例更新
此示例使用一系列JPanel来表示每个单元格.
每个单元格都定义为固定的宽度和高度,并且不会随主窗口调整大小.
在此示例中,每个单元面板都有自己的鼠标侦听器.重新编码它不会太困难,因此主面板只有一个鼠标监听器,而是自己管理工作负载.
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,Color.GRAY); } else { border = new MatteBorder(1,Color.GRAY); } } else { if (col < 4) { border = new MatteBorder(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); } } }