Java Notes

Example - MouseTest.java

In a standard GUI, you don't have to ever deal with these low-level mouse events. The only reason you would is if you wish to have draw graphics that the user can interact with.

This demonstrates listening to mouse events on a graphics component that you've defined. It shows two ways of handling the mouse events (in the component and in the component's owner) and implements both the MouseListener and MouseMotionListener interfaces.

The main program / applet

  1 
  2 
  3 
  4 
  5 
  6 
  7 
  8 
  9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
 38 
 39 
 40 
 41 
 42 
 43 
 44 
 45 
 46 
 47 
 48 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 
 57 
 58 
 59 
 60 
 61 
 62 
 63 
 64 
 65 
 66 
 67 
 68 
 69 
 70 
 71 
 72 
 73 
 74 
 75 
 76 
 77 
 78 
 79 
 80 
 81 
 82 
 83 
 84 
 85 
 86 
 87 
 88 
 89 
 90 
 91 
 92 
 93 
 94 
 95 
// File:   gui-lowlevel/mouse/mousedemo/MouseTest.java
// Purpose: Demonstrate mouse listeners.
//         Written as both applet and main program.
//         Shows two ways to handle mouse listeners:
//         (1) Handled in the graphics component subclass itself.  It's common
//             for a graphics component to handle its own mouse events.
//             The moved and dragged events are handled there.
//         (2) Handled by the "owner" of the component.  This is done here
//             for the 5 MouseListener events.
// Author: Fred Swartz - 2006-10-03 - Placed in public domain.

package mousedemo;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

//////////////////////////////////////////////////////////////// class MouseTest
public class MouseTest extends JApplet implements MouseListener{
    JTextArea              _loggingTA = new JTextArea(10, 40);
    MouseGraphicsComponent _display   = new MouseGraphicsComponent();
    
    //============================================================== constructor
    public MouseTest() {
        JButton clearBtn = new JButton("Clear");
        JLabel  commentsLbl = new JLabel("Experiment with combinations of " +
                "mouse buttons and modifier keys.");
        
        //... Add listeners.
        _display.addMouseListener(this);
        clearBtn.addActionListener(new ClearAction());
        
        //... Do layout.
        JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        topPanel.add(clearBtn);
        topPanel.add(commentsLbl);
        
        JPanel content = new JPanel();
        content.setLayout(new BorderLayout(5, 5));
        content.add(topPanel, BorderLayout.NORTH);
        content.add(_display, BorderLayout.WEST);
        content.add(new JScrollPane(_loggingTA), BorderLayout.CENTER);
        
        this.setContentPane(content);
    }
    
    //============================================================== method main
    public static void main(String[] args) {
        JFrame window = new JFrame("Mouse Demo");
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setContentPane(new MouseTest());
        window.pack();                        // Do the layout.
        window.setLocationRelativeTo(null);   // Center it.
        window.setVisible(true);
    }
    
    //========================================================== mouse listeners
    // I've violated the normal formatting rules because these all belong
    // together and all do the same thing.  Normally, some of them would do
    // something, and others would just ignore the event (no statements
    // in the method body).
    //
    // For ActionEvents, it's a very bad idea to have the outer class
    // implement ActionListener because typically there are many things that
    // might cause these events: buttons, menu items, radio buttons, checkboxes,
    // etc, so there would need to be lots of separate listeners. 
    //
    // Mouse events are different.  First, they are usually handled
    // within a component which listens to its own events, as in the
    // other class here.  Handling them outside the component, as in this class,
    // is unusual, and it's unlikely that more than one component's mouse 
    // events would be handled outside.  If there was a need to separate the
    // mouse events from several components, it would be easy to just put the
    // listeners in an inner class that implements MouseListener.  
    // That might, or might not, be a cleaner way to organize the code.
    public void mouseClicked(MouseEvent e) { log(e); }
    public void mouseEntered(MouseEvent e) { log(e); }
    public void mouseExited(MouseEvent e)  { log(e); }
    public void mousePressed(MouseEvent e) { log(e); }
    public void mouseReleased(MouseEvent e){ log(e); }
    
    //====================================================================== log
    // Utility method to handle common logging action by all listeners.
    private void log(MouseEvent e) {
        _loggingTA.append(e.paramString() + '\n');
    }
    
    //////////////////////////////////////////////////////////////// ClearAction
    class ClearAction implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            _loggingTA.setText("");  // Clear text in logging area.
            _display.clear();        // Clear graphics area.
        }
    }
}

The graphics component which listens to and shows mouse events

  1 
  2 
  3 
  4 
  5 
  6 
  7 
  8 
  9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
 38 
 39 
 40 
 41 
 42 
 43 
 44 
 45 
 46 
 47 
 48 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 
 57 
 58 
 59 
 60 
 61 
 62 
 63 
 64 
 65 
 66 
 67 
 68 
 69 
 70 
 71 
 72 
 73 
 74 
 75 
 76 
 77 
 78 
// File:   gui-lowlevel/mouse/mousedemo/MouseGraphicsComponent.java
// Purpose: Demonstrate mouse listeners.
// Author: Fred Swartz - 2006-10-03 - Placed in public domain.

package mousedemo;

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;

/////////////////////////////////////////////////// class MouseGraphicsComponent
class MouseGraphicsComponent extends JComponent implements MouseMotionListener {
    
    //======================================================= instance variables
    //... The appropriate listener sets the instance variables,
    //    then calls repaint(), which schedules a call to paintComponent,
    //    which uses these variable values.
    private int _lastMovedX   = 0;  // x coord of mouse move
    private int _lastMovedY   = 0;  // y coord of mouse move
    
    //... List of points for line constructed by dragging.
    ArrayList<Point> _points = new ArrayList<Point>(1000);
    
    //============================================================== constructor
    public MouseGraphicsComponent() {
        this.setPreferredSize(new Dimension(200, 200));
        this.addMouseMotionListener(this); // Listen to mouse moves, drags.
    }
    
    //================================================== override paintComponent
    @Override public void paintComponent(Graphics g) {
        //... Paint background.
        g.setColor(Color.YELLOW);
        g.fillRect(0, 0, this.getWidth(), this.getHeight());
        g.setColor(Color.BLACK);
        
        //... Draw coordinates of the mouse as it moves.
        String coords = "x=" + _lastMovedX   + ", y=" + _lastMovedY;
        g.drawString(coords, _lastMovedX, _lastMovedY);
        
        //... Draw lines between each of the points (if any).
        if (_points.size() > 1) {
            Point previousPoint = _points.get(0);
            for (int i = 1; i < _points.size(); i++) {
                Point thisPoint = _points.get(i);
                g.drawLine(previousPoint.x, previousPoint.y
                        , thisPoint.x, thisPoint.y);
                previousPoint = thisPoint;
            }
        }
    }
    
    //====================================================== listener mouseMoved
    // This sets the x, y coordinate that are used by paintComponent.
    // Could also save as a Point object, but ints are sometimes simpler.
    public void mouseMoved(MouseEvent e) {
        //log(e);
        _lastMovedX = e.getX();
        _lastMovedY = e.getY();
        this.repaint();  // Show the change.  Indirectly calls paintComponent.
    }
    
    //==================================================== listener mouseDragged
    // Save each point we dragged over to show as a "line" in paintComponent.
    // Saved as a Point object instead of ints because ArrayList needs object.
    public void mouseDragged(MouseEvent e) {
        _points.add(e.getPoint()); // Save the point for drawing.
        this.repaint();  // Show the change.  Indirectly calls paintComponent.
    }
    
    //==================================================================== clear
    // Clear the points that dragging recorded.
    public void clear() {
        _points.clear();
        this.repaint();  // Show the change.  Indirectly calls paintComponent.
    }
}