简体   繁体   中英

Expanding on Java Swing/AWT Program

I've written a small Swing program that draws a head and when a JCheckBox instance is selected/unselected by the user a hat is drawn or removed from on top of the head. I'm having some trouble taking the next step with this program -- I'd like to add a boolean field to the Head class that causes this component to listen to mouse events with a MouseListener. From there, I'd like to use two methods to set this field to true/false and render the remaining three methods lame ducks. Also, how would I change the paintComponent method so that if the boolean value is true the object is drawn with open eyes, and if it's false, the head is drawn with the eyes closed? Please provide any advice you have. Many thanks!

import javax.swing.*;
import java.awt.geom.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;


public class Head extends JPanel {
Rectangle2D.Double chapeau, chapeau2;
Ellipse2D.Double bouche, visage, oeil1, oeil2;
JCheckBox box;

public Head(){
   this.setBackground(Color.WHITE);

  visage = new Ellipse2D.Double (150,130,100,100);
  bouche = new Ellipse2D.Double (170,180,60,27);
  chapeau = new Rectangle2D.Double (170,80,60,40);
  chapeau2 = new Rectangle2D.Double (125,120,150,10);
  oeil1 = new Ellipse2D.Double (170,150,20,20);
  oeil2 = new Ellipse2D.Double (210,150,20,20);

  box = new JCheckBox("Hat");
  this.add(box);
  box.addItemListener(new ItemListener(){

    public void itemStateChanged(ItemEvent ie){
       repaint();
        }
     });
  }
      public void paintComponent(Graphics g){
         super.paintComponent(g);
         Graphics2D g2 = (Graphics2D)g;
         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
         RenderingHints.VALUE_ANTIALIAS_ON);
         g2.setStroke(new BasicStroke(3.0f));
         g2.setPaint(Color.BLUE);
         g2.draw(visage);
         g2.draw(oeil1);
         g2.draw(oeil2);
         g2.draw(bouche);

            if(box.isSelected()){
              g2.draw(chapeau);
              g2.draw(chapeau2);
          }
     }
      public static void main(String[] args){
         JFrame f = new JFrame("Face Display Window");
         f.setSize(425,285);
         f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
         f.setVisible(true);
         f.add(new Head());
     }
}

----------------------------------- Second Try

 import javax.swing.*;
 import java.awt.geom.*;
 import java.awt.*;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;


 public class Head extends JPanel implements MouseListener {
 Rectangle2D.Double chapeau, chapeau2;
 Ellipse2D.Double bouche, visage, oeil1, oeil2, oeil3, oeil4;
 JCheckBox box;
 boolean isClosed = false;

 public Head(){
 this.setBackground(Color.WHITE);


 visage = new Ellipse2D.Double (150,130,100,100);
 bouche = new Ellipse2D.Double (170,180,60,27);
 chapeau = new Rectangle2D.Double (170,80,60,40);
 chapeau2 = new Rectangle2D.Double (125,120,150,10);
 oeil1 = new Ellipse2D.Double (170,150,20,20);
 oeil2 = new Ellipse2D.Double (210,150,20,20);
 oeil3 = new Ellipse2D.Double (175,155,25,25);
 oeil4 = new Ellipse2D.Double (215,155,25,25);

 box = new JCheckBox("Hat");
 this.addMouseListener(this);
 this.add(box);
 box.addItemListener(new ItemListener(){

      public void itemStateChanged(ItemEvent ie){
         repaint();
      }
  });
  }


      public void paintComponent(Graphics g){
         super.paintComponent(g);
         Graphics2D g2 = (Graphics2D)g;
         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
         RenderingHints.VALUE_ANTIALIAS_ON);
         g2.setStroke(new BasicStroke(3.0f));
         g2.setPaint(Color.BLUE);
         g2.draw(visage);
         g2.draw(oeil1);
         g2.draw(oeil2);
         g2.draw(bouche);

            if(box.isSelected()){
              g2.draw(chapeau);
              g2.draw(chapeau2);

            if(isClosed) {
                g2.draw(oeil3);
                g2.draw(oeil4);
            }
            else {
                g2.draw(oeil1);
                g2.draw(oeil2);
            }


            }
     }

      @Override
    public void mouseClicked(MouseEvent e) {

       isClosed = !isClosed;  

    repaint();  

    }
    @Override
    public void mousePressed(MouseEvent e) {


    }
    @Override
    public void mouseReleased(MouseEvent e) {


    }
    @Override
    public void mouseEntered(MouseEvent e) {


    }
    @Override
    public void mouseExited(MouseEvent e) {


    }


      public static void main(String[] args){
         JFrame f = new JFrame("Face Display Window");
         f.setSize(425,285);
         f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
         f.setVisible(true);
         f.add(new Head());
     }
}

I'm intentionally being a little vague here because I'm not sure if this is homework or not since you already have a fair amount of code that does a lot of stuff that is very similar to what you want it to and modifying it shouldn't be very difficult. However, if you're actually stuck, please clarify and I'll add more details if required.

  1. I'd like to add a boolean field to the Head class that causes this component to listen to mouse events with a MouseListener.

    This isn't too hard, let's walk through it. It's trivial to add a boolean field to your Head class - you simply declare boolean isClosed = false; - indicating that you begin the execution with the field set to false which your code will later interpret as the instruction to draw eyes open.

    Your core requirement is the MouseListener . If you haven't already, check out the Java Trail for events ; it explains how to implement a simple MouseListener . At this point, note that MouseListener is an interface and thus, you'd necessarily need to provide an implementation for all it's methods, even if they're empty-bodied methods. You may want to check out the MouseAdapter abstract class . It provides empty implementations of all these methods (and more) so that you only need to override the ones you need - this makes your code cleaner since you don't have a bunch of empty methods just to satisfy the compiler. This would solve the problem I believe you're referring to when you say ' and render the remaining three methods lame ducks ' Of course, since you're already extending JPanel, you can't extend MouseAdapter as well so this doesn't apply here. But this (with other Adapters) is a useful class to keep in mind for later.

  2. From there, I'd like to use two methods to set this field to true/false

    If I understand you correctly, what you want is to toggle the value of isClosed on mouse clicks. So right now, you have a MouseListener / MouseAdapter that doesn't really do anything. What you need to do next is provide an implementation for, lets say, the MouseClicked() method where you toggle the value of your boolean field. This is really easy as well - you simply invert the current value using the ! (NOT) operator and assign it back the variable - isClosed = !isClosed; . You may wish to read up on operators in Java in more detail .

  3. Also, how would I change the paintComponent method so that if the boolean value is true the object is drawn with open eyes, and if it's false, the head is drawn with the eyes closed?

    One way of doing this is to create two more shapes for the two closed eyes, similar to the ones you have for open eyes. Once you've done that, it's a simple matter of deciding which ones to draw (ie the closed eyes or the open ones) on the basis of the value of isClosed . So you'd use an if clause to check the value of isClosed and draw the open eyes when it's false and the closed eyes when true . Note that since your value of isClosed is being modified in your click handler, you need to make sure that you call repaint() when you change the value otherwise Swing may not update the panel immediately to show the change so then you won't see anything happen.

To sum it up, one way to do what you want is to make the following modifications to Head :

public class Head 
    extends JPanel 
    implements MouseListener {

    //...all your other declarations still go here
    boolean isClosed = false;

    //also declare new 'eyes' which are closed

    public Head() {
        //..all your existing code is still here
        //add code to instantiate closed eyes

        //need to register a new MouseListener 
        //since head itself is a MouseListener, we can pass this as the argument
        this.addMouseListener(this);
    }

    //...all your existing code still goes here

    public void paintComponent(Graphics g) {
        //...all your existing code still goes here

        //decide which eyes to draw depending on isClosed
        if(isClosed) {
            //draw closed eyes
        }
        else {
            //draw open eyes
        }
        //draw everything else as before
    }

    //implementation for MouseListener
    //don't forget the rest of the MouseListener events
    //mousePressed, mouseReleased, mouseEntered, mouseExited
    public void mouseClicked(MouseEvent e) {
        //toggle the value of isClosed
        isClosed = !isClosed;

        //must repaint
        repaint();
    }

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