javaswingpaintcomponentmouse-listeners

Trying to draw 2 horizontal lines if Mouse is in a Component


I am struggling with a problem I have. I have this program which draws a face (w/ an optional hat). I am trying to get it so that if the mouse /cursor is inside the component, two extra little horizontal lines (c1,c2) are drawn to make it appear as if the eyes are closed. I am trying to use the mouse listener unsuccessfully and I was hoping someone may have some suggestions. Thanks

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.JCheckBox;
import java.awt.event.ItemListener;
import java.awt.event.*;
import javax.swing.event.ChangeListener;

public class Head extends JPanel implements MouseListener
{
private Ellipse2D.Double e1;
private Ellipse2D.Double e2; 
private Ellipse2D.Double e3;  
private Ellipse2D.Double e4;
private Ellipse2D.Double e5;
private Rectangle2D.Double r1;
private Ellipse2D.Double r2;

private Line2D.Double c1;
private Line2D.Double c2;

private JCheckBox check = new JCheckBox("Hat");
private int i;

public Head () {
    this.setPreferredSize (new Dimension (600,600));
    e1 = new Ellipse2D.Double(200,200, 200, 300);
    e2 = new Ellipse2D.Double(255,285, 20, 10);  //eyes
    e3 = new Ellipse2D.Double(325,285, 20, 10);  //eyes
    e4 = new Ellipse2D.Double(285, 345, 30,30);
    e5 = new Ellipse2D.Double(265,410, 75, 20);

    r2 = new Ellipse2D.Double (90,175, 450,75);
    r1 = new Rectangle2D.Double (200,110,200,115);

    c1 = new Line2D.Double (255, 290, 275, 290 );   //horizontal lines across ayes
    c2 = new Line2D.Double (325, 290, 345, 290 );   //horizontal lines across ayes

    this.add(check);

     //a separate itemlistener

    class itemlistener implements ItemListener  {
        public void itemStateChanged(ItemEvent check){
            repaint();
        }
    }

    check.addItemListener(new itemlistener());



}

public void update(Graphics g) {  
    paint(g);
} 

//All the mouselistening methods. Im only using exit and entered

public void mousePressed(MouseEvent e) {
}

public void mouseReleased(MouseEvent e) {
}

public void mouseEntered(MouseEvent e) {
    i= 0;

}

public void mouseExited(MouseEvent e) {
    i = 1;
}

public void mouseClicked(MouseEvent e) {
}

//this is a boolean method that is called is i==0 /mouse is inside to draw the lines

public boolean mouseInside(){
  return (i==0);
}


public void paintComponent (Graphics g) {
    // The first two lines are magic incantations to be explained in 209.
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D)g; // convert to better Graphics2D
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON); // looks nicer

    g2.setStroke(new BasicStroke(3.0f));
    g2.setPaint(Color.BLACK);
    g2.draw(e1); // draw the rectangle

    g2.setStroke(new BasicStroke(3.0f));
    g2.setPaint(Color.BLACK);
    g2.draw(e2); // draw the rectang

    g2.setStroke(new BasicStroke(3.0f));
    g2.setPaint(Color.BLACK);
    g2.draw(e3); // 

    g2.setStroke(new BasicStroke(3.0f));
    g2.setPaint(Color.BLACK);
    g2.draw(e4); // 

    g2.setStroke(new BasicStroke(3.0f));
    g2.setPaint(Color.BLACK);
    g2.draw(e5); // 

    if(check.isSelected()) {

        g2.setStroke(new BasicStroke(3.0f));
        g2.setPaint(Color.BLACK);
        g2.draw(r2); // 

        g2.setStroke(new BasicStroke(3.0f));
        g2.setPaint(Color.BLACK);
        g2.draw(r1); // 
    }

    //this is a method to draw the lines if the mouse is inside

    if (mouseInside()){
        g2.setStroke(new BasicStroke(3.0f));
        g2.setPaint(Color.BLACK);
        g2.draw(c1); // 

        g2.setStroke(new BasicStroke(3.0f));
        g2.setPaint(Color.BLACK);
        g2.draw(c2);

    }

}

public static void main(String[] args) {
    JFrame f = new JFrame("ShapePanel demo");
    f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    f.setLayout(new FlowLayout());
    // Let's add two separate ShapePanel instances, just to see how it works.
    f.add(new Head());

    f.pack();
    f.setVisible(true);  

}
}

Solution

  • You haven't added any mouse listener to the panel. You need to add this line:

    this.addMouseListener(this);
    

    (it would be cleaner if the panel itself was not a mouse listener, and if you used a separate, inner class for the listener).

    Moreover, the mouse listener changes the value of i, but doesn't ask the panel to repaint itself. So you need this line in the mouseEntered() and mouseExited() methods:

    repaint();
    

    Also, note that the main method should use SwingUtilities.invokeLater() to construct and display the frame in the event disptach thread, and that you shouldn't override update().