0

我编写了一个绘制头部的小型 Swing 程序,当用户选择/取消选择 JCheckBox 实例时,会从头顶绘制或移除帽子​​。我在执行该程序的下一步时遇到了一些麻烦——我想向 Head 类添加一个布尔字段,使该组件使用 MouseListener 侦听鼠标事件。从那里开始,我想使用两种方法将此字段设置为真/假,并渲染其余三种方法跛脚鸭。另外,我将如何更改paintComponent 方法,以便如果布尔值为true,则对象是睁着眼睛绘制的,如果为false,则头部是闭着眼睛绘制的?请提供您的任何建议。非常感谢!

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

---------------------------------- 第二次尝试

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

1 回答 1

0

我故意在这里有点含糊,因为我不确定这是否是家庭作业,因为你已经有相当多的代码可以做很多与你想要的非常相似的东西,并且应该修改它不是很困难。但是,如果你真的被卡住了,请澄清一下,如果需要,我会添加更多细节。

  1. 我想向 Head 类添加一个布尔字段,使该组件使用 MouseListener 侦听鼠标事件。

    这并不难,让我们逐步完成。向您的类添加一个boolean字段Head很简单 - 您只需声明boolean isClosed = false;- 表明您从设置的字段开始执行false,您的代码稍后将解释为睁开眼睛的指令。

    您的核心要求是MouseListener. 如果您还没有,请查看Java Trail 以了解事件;它解释了如何实现一个简单的MouseListener. 此时,请注意这MouseListener是一个接口,因此,您必须为它的所有方法提供一个实现,即使它们是空体方法。您可能想查看MouseAdapter 抽象类。它提供了所有这些方法(以及更多)的空实现,因此您只需要覆盖您需要的那些 - 这使您的代码更清晰,因为您没有一堆空方法只是为了满足编译器。这将解决我相信您在说 '并渲染其余三种方法时所指的问题' 当然,由于您已经在扩展 JPanel,因此不能同时扩展MouseAdapter,因此此处不适用。但是这个(和其他适配器)是一个有用的类,以后要记住。

  2. 从那里,我想使用两种方法将此字段设置为真/假

    如果我理解正确,你想要的是切换isClosed鼠标点击的值。所以现在,你有一个MouseListener/MouseAdapter并没有真正做任何事情。您接下来需要做的是为MouseClicked()您切换boolean字段值的方法提供一个实现。这也很容易 - 您只需使用!(NOT) 运算符反转当前值并将其分配回变量 - isClosed = !isClosed;。您可能希望更详细地阅读 Java 中的运算符

  3. 另外,我将如何更改paintComponent 方法,以便如果布尔值为true,则对象是睁着眼睛绘制的,如果为false,则头部是闭着眼睛绘制的?

    这样做的一种方法是为两只闭合的眼睛创建另外两个形状,类似于睁开眼睛的形状。完成此操作后,根据 的值决定绘制哪些(即闭上的眼睛或睁开的眼睛)就很简单了isClosed。因此,您将使用一个if子句来检查 的值isClosed并绘制睁开的眼睛 when it'sfalse和闭上的眼睛 when true。请注意,由于isClosed在单击处理程序中修改了您的值,因此您需要确保repaint()在更改值时调用,否则 Swing 可能不会立即更新面板以显示更改,因此您不会看到任何事情发生。

总而言之,做你想做的事情的一种方法是对以下进行修改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();
    }
于 2011-03-03T03:44:20.890 回答