我在 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(因为 MouseClicktaskTwo 的内部 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());
}