Расширение программы Java Swing/AWT

Я написал небольшую программу Swing, которая рисует голову, и когда пользователь выбирает/отменяет выбор экземпляра JCheckBox, шляпа рисуется или снимается сверху головы. У меня возникли проблемы с выполнением следующего шага с этой программой — я хотел бы добавить логическое поле в класс Head, которое заставляет этот компонент прослушивать события мыши с помощью MouseListener. Оттуда я хотел бы использовать два метода, чтобы установить для этого поля значение true/false и отобразить оставшиеся три метода хромыми утками. Кроме того, как мне изменить метод paintComponent, чтобы, если логическое значение равно true, объект рисовался с открытыми глазами, а если ложно, голова рисовалась с закрытыми глазами? Пожалуйста, дайте любой совет, который у вас есть. Большое спасибо!

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

person astroDude1    schedule 03.03.2011    source источник


Ответы (1)


Я намеренно немного расплывчат, потому что не уверен, является ли это домашним заданием или нет, поскольку у вас уже есть изрядное количество кода, который делает много вещей, очень похожих на то, что вы хотите, и изменить его не должно быть очень сложно. Однако, если вы действительно застряли, уточните, и я добавлю дополнительные сведения, если потребуется.

  1. Я хочу добавить логическое поле в класс Head, которое заставит этот компонент прослушивать события мыши с помощью MouseListener.

    Это не слишком сложно, давайте пройдемся по нему. Добавить поле boolean в класс Head очень просто — вы просто объявляете boolean isClosed = false; — указывая, что вы начинаете выполнение с полем, установленным в false, которое ваш код позже интерпретирует как инструкцию открыть глаза.

    Ваше основное требование — MouseListener. Если вы еще этого не сделали, ознакомьтесь с Java Trail для событий; в нем объясняется, как реализовать простой MouseListener. На данный момент обратите внимание, что MouseListener — это интерфейс, и поэтому вам обязательно нужно предоставить реализацию для всех его методов, даже если они являются методами с пустым телом. Вы можете проверить абстрактный класс MouseAdapter< /а>. Он предоставляет пустые реализации всех этих (и других) методов, так что вам нужно переопределить только те, которые вам нужны — это делает ваш код чище, поскольку у вас нет кучи пустых методов только для удовлетворения компилятора. Это решило бы проблему, о которой, как мне кажется, вы говорите 'и сделать оставшиеся три метода хромыми утками'. Конечно, поскольку вы уже расширяете JPanel, вы не можете расширять MouseAdapter как ну так это сюда не относится. Но это (с другими адаптерами) полезный класс, о котором стоит помнить на потом.

  2. Оттуда я хотел бы использовать два метода, чтобы установить для этого поля значение true/false

    Если я вас правильно понял, вы хотите переключить значение isClosed на щелчки мыши. Итак, прямо сейчас у вас есть MouseListener/ MouseAdapter, который на самом деле ничего не делает. Далее вам нужно реализовать реализацию, скажем, метода MouseClicked(), в котором вы переключаете значение поля boolean. Это также очень просто - вы просто инвертируете текущее значение с помощью оператора ! (НЕ) и присваиваете его обратно переменной - isClosed = !isClosed;. Вы можете прочитать более подробную информацию об операторах в Java. .

  3. Кроме того, как мне изменить метод paintComponent, чтобы, если логическое значение равно true, объект рисовался с открытыми глазами, а если false, голова рисовалась с закрытыми глазами?

    Один из способов сделать это — создать еще две фигуры для двух закрытых глаз, похожие на те, что у вас есть для открытых глаз. Как только вы это сделаете, вам будет просто решить, какие из них рисовать (например, закрытые глаза или открытые) на основе значения isClosed. Таким образом, для проверки значения isClosed и нарисуйте открытые глаза, когда будет false, и закрытые глаза, когда будет 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();
    }
person no.good.at.coding    schedule 03.03.2011
comment
Прежде всего, спасибо за вашу помощь. Это очень ценится. Однако после реализации предложенных вами элементов он по-прежнему работает неправильно, и я несколько запутался. Я знаю, что это простая проблема, но я все еще новичок в мире Java. Вот что у меня сейчас (см. выше): - person astroDude1; 03.03.2011