如何在java swing中更改网格单元格的颜色



我正在为我的一个类开发一个最短路径查找应用程序,作为该项目的一部分,我们需要制作一个非常简单的GUI。它只需要一个7跨5下的网格、一个说明框、一个下拉菜单和几个按钮来调整网格大小并启动每个算法。我们决定使用javaswing构建GUI。但是,当用户单击网格上的一个正方形时,我们需要在该网格正方形中着色。我们还没能找到一种方法来做到这一点。

为了构建网格,我们创建了一个内部类,该类只需使用嵌套的for循环创建和绘制网格。这部分工作得很好。

public static class Grid extends JPanel {
public Grid() {
setSize(400, 400);
setVisible(true);
}
public void paint(Graphics g) {
for (int x = 30; x <= 30*cols; x += 30)
for (int y = 30; y <= 30*rows; y += 30)
g.drawRect(x,y, 30, 30);
}
}

我们试图为我们想要着色的单元格做一些类似的事情,但它不会出现在我们的GUI窗口中。我从其他人的问题中看到,你需要将Graphics对象转换为2D Graphics对象,当我在接受鼠标输入之外运行一些测试代码时,它就起作用了。但当我尝试使用我创建的方法在网格单元中着色时,它并没有出现。这是我创建的内部类Cell,用于绘制和填充单元格。

public static class Cell extends JPanel {
int x;
int y;
Color color;
public Cell(int x, int y, Color color) {
this.x = x;
this.y = y;
this.color = color;
setVisible(true);

}

public void paintComponent(Graphics g) {
System.out.println("here");
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(color);
g2d.drawRect(x,y, 30, 30);
g2d.setColor(color);
g2d.fillRect(x,y,30,30);
}

}

我是否需要以某种方式访问我们已经在网格中绘制的单元格,而不是试图在网格顶部绘制?我怎么能那样做?我甚至可以在网格顶部绘制吗?是我们的鼠标事件阻止了它的出现吗?我们是否应该每次都重新绘制一个单元格的网格?

我还创建了这个方法,当用户点击我们的网格时,我会调用它。这是我们还没有真正弄清楚的部分。

//input: the cell's id number and the color we want the cell to be
public Cell colorCell(int cell, Color color){
int gridTopX = 33; //this is how our grid is oriented in the window
int gridTopY = 33; //this is how our grid is oriented in the window
int cellX;
int cellY;

//this finds the row and colum of the cell (to find top left corner to draw it)
int counter = 0; //row
int holder = cell; //column
while(holder > 7){
holder -= 7; //subtract 7
counter++; //increment counter
}
//once that is done we have the row and column -1 each
holder++;
counter++;
cellX = 33 + (30 *holder);
cellY = 33 + (30*counter);

//create the cell
Cell cellToColor = new Cell(cellX,cellY, color);
return cellToColor;
}

我想,如果我用这种方法创建一个单元格,它将能够在网格顶部的单元格中绘制和着色。但是单元的创建从来没有进入到cell类的paintComponent(Graphics g(方法。我不知道如何调用这个方法,因为我不相信有一种方法可以创建图形对象。每隔一次我从单元格类创建一个单元格时,就会自动调用它。不能从另一个方法内部调用它吗?如有任何帮助或建议,我们将不胜感激。

您可以放弃自定义绘制工作流程,只使用JPanel已经提供的功能

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.border.LineBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new GridPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class GridPane extends JPanel {
public GridPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
for (int row = 0; row < 5; row++) {
gbc.gridy = row;
for (int col = 0; col < 7; col++) {
gbc.gridx = col;
add(new CellPane(), gbc);
}
}
}
}
public class CellPane extends JPanel {
private boolean selected;
public CellPane() {
setBorder(new LineBorder(Color.DARK_GRAY));
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
toggleSelection();
}
});
}
public void setSelected(boolean selected) {
this.selected = selected;
if (selected) {
setBackground(Color.BLUE);
setBorder(new LineBorder(Color.WHITE));
} else {
setBackground(null);
setBorder(new LineBorder(Color.DARK_GRAY));
}
repaint();
}
public void toggleSelection() {
setSelected(!isSelected());
}
public boolean isSelected() {
return selected;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(30, 30);
}
}
}

当然,如果你想遵循自定义绘画工作流程,你可以看看:

  • 用Java为网格创建一个绘制矩形(填充黑色(函数
  • 如何使用swing类Java绘制网格并在点击和拖动时检测鼠标位置
  • 网格不准确';s单元格坐标

作为一些想法

此外

记住,模特才是王道。细胞的状态应基于模型的状态

最新更新