如何使用鼠标监听器和按事件将填充的正方形更改为另一种颜色?



这是为了家庭作业,我已经完成了大部分工作,但我被困在最后一步(实现一个鼠标事件,它将我的一个随机彩色方块更改为红色而不是它被分配的颜色)并且担心使用我的教授提供的方法不适合这个,因为他让我们在鼠标事件后重新绘制(我觉得我的代码只会用更随机的颜色覆盖)。 任何帮助或朝着正确方向的推动都会有所帮助,我相信这是一团糟。 根据Camickr的帮助进行更新,我的代码已更改为以下内容:

import java.awt.GridLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.*;
// MouseListener Imports
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;

public class Test extends JPanel implements MouseListener
{
static Color[][] framework = new Color[8][8];
static int redCounter = 0;
// main Creates a JFrame and instantiates the 2d array of color objects
public static void main(String[] args)
{
// The frame handles all the outside window work
JFrame frame = new JFrame("MouseListener demo");
// Allows the 'X' in the upper right to cause the program to exit
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//Create and set up the content pane.
// contentPane holds a panel
JComponent newContentPane = new Test();
// MouseListenerDemo isa JPanel isa JComponent
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
/* Causes this Window to be sized to fit the preferred size and layouts of its subcomponents. 
The resulting width and height of the window are automatically enlarged if either of dimensions
is less than the minimum size as specified by the previous call to the setMinimumSize method. 
If the window and/or its owner are not displayable yet, both of them are made displayable before
calculating the preferred size. The Window is validated after its size is being calculated.
*/
frame.setVisible(true);
for (int x = 0; x < framework.length; x++) {
for (int y = 0; y < framework.length; y++) {
Color rc = randomColor();
framework[x][y] = rc;
}
}
}
// Constructor
public Test()
{
// layout the panel with an area in which to draw
super(new GridLayout(0,1));
// get Graphics object, which allows you to draw on the panel
// set initial size of the panel
setPreferredSize(new Dimension(400, 500));
// ADD this JPanel to the list of components notified when a mouse event happens
this.addMouseListener(this);
// calls paint()
repaint();
}
// draws the screen
public void paint(Graphics g)
{
// Get the size
Dimension d = this.getSize();
int size = 50;    // The edge length of the squares
int xSt = 50;    // Starting x-coordinate
int ySt = 50;    // Starting y-coordinate
int n = 8;        // n X n board
int xPos, yPos;
for(int row = 0; row < framework.length; row ++){
for (int col = 0; col < framework.length; col ++){
xPos = xSt*col;
yPos = xSt*row;
// set color
g.setColor (framework[row][col]);
// Draw square
g.fillRect(xPos, yPos, size, size);
}
}
g.setColor(Color.black);
g.drawString("There are " + redCounter + " reds." , d.width/3, d.height);
}
public static Color randomColor(){
Random rg = new Random();
int result = rg.nextInt(12); 
Color color; 
switch(result){
case 0: color = Color.black;
break;
case 1: color = Color.blue;
break;
case 2: color = Color.cyan;
break;
case 3: color = Color.darkGray;
break;
case 4: color = Color.yellow;
break;
case 5: color = Color.green;
break;
case 6: color = Color.lightGray;
break;
case 7: color = Color.magenta;
break;
case 8: color = Color.orange;
break;
case 9: color = Color.pink;
break;
case 10: color = Color.red; redCounter = redCounter + 1;
break;
case 11: color = Color.white;
break;
default: color = Color.black;
break;
}
return color;
}

// MouseListener methods
public void mousePressed(MouseEvent evt) 
{
// demonstrates how to use the parameter
// to get the position of the mouse press
Dimension d = this.getSize();
int x = evt.getX();
int y = evt.getY();
System.out.println(x+","+y);//these co-ords are relative to the component
System.out.println(evt.getSource());
for (int i = 0; i < framework.length; i++) {
for (int j = 0; j < framework.length; j++) {
System.out.println(framework[i][j]);
if (evt.getSource().equals(framework[i][j])) {
framework[i][j] = Color.red;
redCounter = redCounter + 1;
}
}
}
repaint(); // redisplay the frame by eventually calling the paint() method
}
// do nothing for the other mouse actions
public void mouseReleased(MouseEvent evt) {}
public void mouseClicked(MouseEvent evt) {}
public void mouseEntered(MouseEvent evt) {}
public void mouseExited(MouseEvent evt) {}
}
担心

使用我的教授提供的方法不适合这样做,因为他让我们在鼠标事件后重新绘制(我觉得我的代码只会用更随机的颜色覆盖)。

鼠标事件中的重绘()是正确的。但是,由于您的绘画代码不正确,将生成更多的随机颜色。

绘制方法应仅绘制组件的状态,而不更改状态。因此:

  1. 您需要保留一个数据结构(假设一个 2D 数组)来保存每个单元格的颜色。在类的构造函数中,您将遍历此数组,并为数组中的每个条目分配随机颜色。

  2. 然后在绘制方法中,您只需遍历数组并使用数组中的颜色绘制每个单元格。

请注意,您应该覆盖自定义绘画的paintComponent(),而不是 paint()。

  1. 然后在 MouseListener 代码中,您只需重置被单击单元格的数组中的颜色并调用 repaint()。

我通过获取 x/y 的位置并将它们除以 50(我的方形高度/宽度)并将 int 放入数组索引来修复它。

public void mousePressed(MouseEvent evt) 
{
// demonstrates how to use the parameter
// to get the position of the mouse press
Dimension d = this.getSize();
int x = evt.getX()/50;
int y = evt.getY()/50;
framework[y][x] = Color.red;
redCounter = redCounter+1;

repaint(); // redisplay the frame by eventually calling the paint() method
}