简体   繁体   中英

I am having trouble implementing a mouse action listener in my GUI

I have created a simple GUI which contains a circle filled with a random colour. I am now trying to make it so that the colour of the circle changes when the mouse is clicked to another random colour. I have created a paint component method which initially paints the circle and a repaint method which will change the colour of the circle. I have then called upon this method in my mouse listener event class. The problem is that I am getting an error when I add my action listener to my pane. The error is as follows:

No enclosing instance of type taskTwo is accessible. Must qualify the allocation with an enclosing instance of type taskTwo (egxnew A() where x is an instance of taskTwo).

I understand why I am getting this error but do not know how to fix it, I have tried moving the action listener class into a class of its own but then I cannot call upon my repaint method within the listener. Here is my code:

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) {}

    }

}

Thanks, also an extension of this would be to make it so that the colour changes only when I click within the circle, any tips on how to do this would be appreciated.

The problem is that your MouseClick class is not static but you are trying to instantiate it from a static context (the main method).

You have multiple solutions:

  • turn your class into static class MouseClick
  • create and add the MouseListener in the taskTwo() constructor (since MouseClick is an internal class of taskTwo )
  • create a specific taskTwo to provide the requested instance, eg new taskTwo.MouseClick() , but don't do it , since it makes no sense in this situation.

I would add the MouseListener in the instance world, not in the static world, and that error will go away. I also recommend that you get rid of that strange repaint method as it looks too similar to Swing JComponent's own repaint method. You never call it and so it does you no good.

Also randomize your colors in the mouse listener, not in the paintComponent method (which should be protected). I also prefer to extend JPanel and not JComponent.

eg,

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();
            }
        });
    }
}

The problem is that you are accessing the MouseClick class from the public static void main function. Since, MouseClick is inside taskTwo he can´t access it, you first need to create an instance of taskTwo.

Quick fix : Add constructor and erase that lane from the main function.

public taskTwo (){
    this.addMouseListener(new MouseClick());
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM