我在 GUI 中实现鼠标动作侦听器时遇到问题
I am having trouble implementing a mouse action listener in my GUI
我创建了一个简单的 GUI,其中包含一个用随机颜色填充的圆圈。我现在正试图做到这一点,以便当鼠标单击到另一种随机颜色时,圆圈的颜色会发生变化。我创建了一个 paint 组件方法,它最初绘制圆圈和一个 repaint 方法,它将改变圆圈的颜色。然后我在我的鼠标侦听器事件 class 中调用了这个方法。问题是当我将我的动作侦听器添加到我的窗格时出现错误。错误如下:
无法访问类型为 taskTwo 的封闭实例。必须使用 taskTwo 类型的封闭实例来限定分配(例如 x.new A(),其中 x 是 taskTwo 的实例)。
我明白为什么会收到此错误,但不知道如何解决,我曾尝试将动作侦听器 class 移动到它自己的 class 中,但后来我无法调用我在监听器中的重绘方法。这是我的代码:
package weekThree;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class taskTwo extends JComponent {
static Random rand = new Random();
JPanel pane = new JPanel();
public static void main(String[] args) {
JFrame window = new JFrame("Task Two");
JPanel pane = new JPanel();
pane.setLayout(new FlowLayout());
taskTwo t2 = new taskTwo();
window.setContentPane(t2);
t2.paint(null);
pane.addMouseListener(new MouseClick());
window.setBackground(Color.WHITE);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(300,300);
window.setVisible(true);
}
public void paintComponent(Graphics g) {
float red = rand.nextFloat();
float green = rand.nextFloat();
float blue = rand.nextFloat();
Color randomColor = new Color(red, green, blue);
g.drawOval(300, 300, 200, 200);
g.setColor(randomColor);
g.fillOval(300, 300, 200, 200);
}
public void repaint(Graphics g) {
float red = rand.nextFloat();
float green = rand.nextFloat();
float blue = rand.nextFloat();
Color randomColor = new Color(red, green, blue);
g.drawOval(300, 300, 200, 200);
g.setColor(randomColor);
g.fillOval(300, 300, 200, 200);
}
class MouseClick implements MouseListener {
public void mouseClicked(MouseEvent e) {
repaint();
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
}
}
谢谢,这也是一个扩展,只有当我在圆圈内点击时颜色才会改变,任何关于如何做到这一点的提示都将不胜感激。
问题是您的 MouseClick
class 不是 static
但您正试图从 static
上下文中实例化它(main
方法).
您有多个解决方案:
- 把你的class变成
static class MouseClick
- 在
taskTwo()
构造函数中创建并添加 MouseListener
(因为 MouseClick
是 taskTwo
的内部 class)
- 创建一个特定的
taskTwo
来提供请求的实例,例如new taskTwo.MouseClick()
,但不要这样做,因为它在这方面没有意义情况。
我会在实例世界中添加 MouseListener,而不是在静态世界中,这样错误就会消失。我还建议您摆脱那个奇怪的重绘方法,因为它看起来与 Swing JComponent 自己的重绘方法太相似了。你永远不会调用它,所以它对你没有好处。
同时在鼠标侦听器中随机化您的颜色,而不是在 paintComponent 方法(应该受到保护)中。我也更喜欢扩展 JPanel 而不是 JComponent。
例如,
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.*;
@SuppressWarnings("serial")
public class MyTaskToo extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private Color circleColor = Color.RED;
private int circX = 10;
private int circY = circX;
private int circW = PREF_W - 2 * circX;
private int circH = PREF_H - 2 * circY;
public MyTaskToo() {
// add in constructor -- in the "instance realm" not in the static realm
addMouseListener(new MyMouse());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// to smooth out graphics
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(circleColor);
g2.fillOval(circX, circY, circW, circH);
g2.setColor(Color.BLACK);
g2.drawOval(circX, circY, circW, circH);
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class MyMouse extends MouseAdapter {
Random rand = new Random();
@Override
public void mousePressed(MouseEvent e) {
float red = rand.nextFloat();
float green = rand.nextFloat();
float blue = rand.nextFloat();
circleColor = new Color(red, green, blue);
repaint();
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("MyTaskToo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new MyTaskToo());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
问题是您正在从 public static void main
函数访问 MouseClick class。由于 MouseClick 在 taskTwo 中,他无法访问它,因此您首先需要创建一个 taskTwo 的实例。
快速修复:添加构造函数并从主函数中删除该通道。
public taskTwo (){
this.addMouseListener(new MouseClick());
}
我创建了一个简单的 GUI,其中包含一个用随机颜色填充的圆圈。我现在正试图做到这一点,以便当鼠标单击到另一种随机颜色时,圆圈的颜色会发生变化。我创建了一个 paint 组件方法,它最初绘制圆圈和一个 repaint 方法,它将改变圆圈的颜色。然后我在我的鼠标侦听器事件 class 中调用了这个方法。问题是当我将我的动作侦听器添加到我的窗格时出现错误。错误如下:
无法访问类型为 taskTwo 的封闭实例。必须使用 taskTwo 类型的封闭实例来限定分配(例如 x.new A(),其中 x 是 taskTwo 的实例)。
我明白为什么会收到此错误,但不知道如何解决,我曾尝试将动作侦听器 class 移动到它自己的 class 中,但后来我无法调用我在监听器中的重绘方法。这是我的代码:
package weekThree;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class taskTwo extends JComponent {
static Random rand = new Random();
JPanel pane = new JPanel();
public static void main(String[] args) {
JFrame window = new JFrame("Task Two");
JPanel pane = new JPanel();
pane.setLayout(new FlowLayout());
taskTwo t2 = new taskTwo();
window.setContentPane(t2);
t2.paint(null);
pane.addMouseListener(new MouseClick());
window.setBackground(Color.WHITE);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(300,300);
window.setVisible(true);
}
public void paintComponent(Graphics g) {
float red = rand.nextFloat();
float green = rand.nextFloat();
float blue = rand.nextFloat();
Color randomColor = new Color(red, green, blue);
g.drawOval(300, 300, 200, 200);
g.setColor(randomColor);
g.fillOval(300, 300, 200, 200);
}
public void repaint(Graphics g) {
float red = rand.nextFloat();
float green = rand.nextFloat();
float blue = rand.nextFloat();
Color randomColor = new Color(red, green, blue);
g.drawOval(300, 300, 200, 200);
g.setColor(randomColor);
g.fillOval(300, 300, 200, 200);
}
class MouseClick implements MouseListener {
public void mouseClicked(MouseEvent e) {
repaint();
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
}
}
谢谢,这也是一个扩展,只有当我在圆圈内点击时颜色才会改变,任何关于如何做到这一点的提示都将不胜感激。
问题是您的 MouseClick
class 不是 static
但您正试图从 static
上下文中实例化它(main
方法).
您有多个解决方案:
- 把你的class变成
static class MouseClick
- 在
taskTwo()
构造函数中创建并添加MouseListener
(因为MouseClick
是taskTwo
的内部 class) - 创建一个特定的
taskTwo
来提供请求的实例,例如new taskTwo.MouseClick()
,但不要这样做,因为它在这方面没有意义情况。
我会在实例世界中添加 MouseListener,而不是在静态世界中,这样错误就会消失。我还建议您摆脱那个奇怪的重绘方法,因为它看起来与 Swing JComponent 自己的重绘方法太相似了。你永远不会调用它,所以它对你没有好处。
同时在鼠标侦听器中随机化您的颜色,而不是在 paintComponent 方法(应该受到保护)中。我也更喜欢扩展 JPanel 而不是 JComponent。
例如,
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.*;
@SuppressWarnings("serial")
public class MyTaskToo extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private Color circleColor = Color.RED;
private int circX = 10;
private int circY = circX;
private int circW = PREF_W - 2 * circX;
private int circH = PREF_H - 2 * circY;
public MyTaskToo() {
// add in constructor -- in the "instance realm" not in the static realm
addMouseListener(new MyMouse());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// to smooth out graphics
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(circleColor);
g2.fillOval(circX, circY, circW, circH);
g2.setColor(Color.BLACK);
g2.drawOval(circX, circY, circW, circH);
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class MyMouse extends MouseAdapter {
Random rand = new Random();
@Override
public void mousePressed(MouseEvent e) {
float red = rand.nextFloat();
float green = rand.nextFloat();
float blue = rand.nextFloat();
circleColor = new Color(red, green, blue);
repaint();
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("MyTaskToo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new MyTaskToo());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
问题是您正在从 public static void main
函数访问 MouseClick class。由于 MouseClick 在 taskTwo 中,他无法访问它,因此您首先需要创建一个 taskTwo 的实例。
快速修复:添加构造函数并从主函数中删除该通道。
public taskTwo (){
this.addMouseListener(new MouseClick());
}