Java custom mouse listeners?

First, I came to Java as a programmer on a site. In JavaScript, all you need to do to add a mousemove, mouseover, or click event is the addEventListener function. From my limited experience with Java, you cannot just implement the MouseListener interface from any object.

Basically, I'm still a JPanel that draws some shapes (a CustomShape object with a paint method) that have x / y / width / height values. I want to add some type of mouse listener to the shape object so that I can fire move / roll / click events for the shape. Just implementing the MouseListener interface for a CustomShape object does not work (apparently for obvious reasons). I looked at how to create custom event listeners, but it seems like creating a custom mouse listener is possible.

In the end, I resorted to adding a mouse listener to the JPanel, and then iterating over all the objects in the form. If a β€œlistener” was added to the shape object, and the mouse coordinates confirmed the mouse event, he fired the method. Initially, it was great, but as the application got more developed, it really got confused. Also, I would never be able to copy form objects / interfaces to another application without copying the code pool.

As a simple illustration: (the actual code is quite large)

Interface CustomShape{ int width, height, x, y; void paint(Graphics g); } public class StarShape implements CustomShape{ int width, height, x, y; public StarShape(){ width = 100; height = 100; x = 50; y = 50; } void paint(Graphics g){ g.setColor(Color.black); g.draw(new Rectangle(x,y,width,height)); } } public class Main extends JPanel{ StarShape check = new StarShape(); public Main(){ } @Override public void paintComponent(Graphics g){ super.paintComponent(g); check.paint(g); } } 

So, I was wondering if there is a clean way to implement some type of mouse listener for a "drawn" form.

+4
source share
3 answers

My approach to what you are trying to do. Compile, run, read :-)

(Note: you can copy each line of code below into a single Example01.java file. Compile it and run it.)

 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Example01 { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { JFrame jf = new JFrame(); MainPanel mainPanel = new MainPanel(); jf.add(mainPanel); jf.setSize(640, 480); jf.setLocationRelativeTo(null); jf.setVisible(true); } }); } } class MainPanel extends JPanel { StarShape check1 = new StarShape(); StarShape check2 = new StarShape(); public MainPanel() { check1.setName("check1"); check2.setName("check2"); check1.addMouseListener(new MyMouseListener(check1)); check2.addMouseListener(new MyMouseListener(check2)); this.add(check1); this.add(check2); } } class StarShape extends JComponent { public StarShape() { this.setPreferredSize(new Dimension(100, 100)); } @Override protected void paintComponent(Graphics g) { g.setColor(Color.black); Graphics2D g2d = (Graphics2D) g; int x = 0; int y = 0; int width = this.getWidth() - 1; int height = this.getHeight() - 1; g2d.draw(new Rectangle(x, y, width, height)); } } class MyMouseListener implements MouseListener { private final JComponent component; public MyMouseListener(JComponent component) { this.component = component; } public void mouseClicked(MouseEvent e) { System.out.println("mouseClicked: " + component.getName()); } public void mouseEntered(MouseEvent e) { System.out.println("mouseEntered: " + component.getName()); Dimension preferredSize = component.getPreferredSize(); preferredSize.height += 20; preferredSize.width += 20; component.setPreferredSize(preferredSize); component.invalidate(); SwingUtilities.getWindowAncestor(component).validate(); } public void mouseExited(MouseEvent e) { System.out.println("mouseExited: " + component.getName()); Dimension preferredSize = component.getPreferredSize(); preferredSize.height -= 20; preferredSize.width -= 20; component.setPreferredSize(preferredSize); component.invalidate(); SwingUtilities.getWindowAncestor(component).validate(); } public void mousePressed(MouseEvent e) { System.out.println("mousePressed: " + component.getName()); } public void mouseReleased(MouseEvent e) { System.out.println("mouseReleased: " + component.getName()); } } 
+2
source

To receive events, your Form objects must extend java.awt.Component (or javax.swing.JComponent). You can then add them to JPanel as a child, and they will receive events, and you can add them directly to them.

As you do this, you need to manually track the position of your shapes in JPanel. You would add a mouse listener to the panel itself, and depending on the x / y coordinates of the event that you receive, call some method in the form to handle the event. This pretty much redefines what the AWT / Swing base classes will do for you.

+5
source

What you can do is expand the JPanel form.

 public abstract class CustomShape extends JPanel { public CustomShape(){ setOpaque(false); } public abstract void paintShape(Graphics g); protected void paintComponent(Graphics g) { super.paintComponent(g); paintShape(g); } } 

Then you can add listeners directly to the shapes.

Then you need to create the parent JPanel and set its LayoutManager to null . And then you will need to manually set the Shape location on the parent.

Read a little more about how to manually assemble components here . And if you do not like this approach, look at my answer to this question. He talks about moving colored rectangles around the screen with the mouse.

+1
source

All Articles