我创建了一个简单的GUI,其中包含一个填充了随机颜色的圆圈。我现在正试图使鼠标点击到另一种随机颜色时圆的颜色发生变化。我创建了一个最初绘制圆形的绘画组件方法和一个将改变圆形颜色的重绘方法。然后我在我的鼠标监听器事件类中调用了这个方法。问题是当我将动作监听器添加到窗格时出现错误。错误如下:
无法访问taskTwo类型的封闭实例。必须使用taskTwo类型的封闭实例限定分配(例如x.new A(),其中x是taskTwo的实例)。
我理解为什么我收到此错误但不知道如何修复它,我已经尝试将动作侦听器类移动到它自己的类中但是我不能在侦听器中调用我的重绘方法。这是我的代码:
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) {}
}
}
谢谢,这也是一个扩展,只有当我在圈内点击时才会使颜色发生变化,任何有关如何做到这一点的提示都将受到赞赏。
答案 0 :(得分:2)
问题是您的MouseClick
课程不是static
,但您正尝试从static
上下文(main
方法)对其进行实例化。
您有多种解决方案:
static class MouseClick
MouseListener
构造函数中创建并添加taskTwo()
(因为MouseClick
是内部类taskTwo
)taskTwo
来提供所请求的实例,例如new taskTwo.MouseClick()
,但不要,因为在这种情况下没有任何意义。< / LI>
答案 1 :(得分:2)
我会在实例世界中添加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();
}
});
}
}
答案 2 :(得分:2)
问题是您正在从public static void main
函数访问MouseClick类。因为,MouseClick在taskTwo里面,所以他无法访问它,你首先需要创建一个taskTwo实例。
快速修复:添加构造函数并从主函数中删除该通道。
public taskTwo (){
this.addMouseListener(new MouseClick());
}