扩展 Java Swing/AWT 程序
我编写了一个小的 Swing 程序,它绘制一个头部,当用户选择/取消选择 JCheckBox 实例时,会在头顶绘制或移除帽子。我在执行该程序的下一步时遇到了一些麻烦 - 我想向 Head 类添加一个布尔字段,使该组件使用 MouseListener 侦听鼠标事件。从那里,我想使用两种方法将此字段设置为 true/false 并呈现其余三个方法跛脚鸭。另外,我将如何更改 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());
}
}
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());
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我故意在这里说得有点含糊,因为我不确定这是否是家庭作业,因为你已经有相当数量的代码,它们做的很多事情与你想要的非常相似,并且修改它应该不是很困难。但是,如果您确实遇到困难,请澄清,如果需要,我将添加更多详细信息。
我想向 Head 类添加一个布尔字段,使该组件能够监听使用 MouseListener 来处理鼠标事件。
这并不太难,让我们来看看吧。将
boolean
字段添加到您的Head
类中非常简单 - 您只需声明boolean isClosed = false;
- 指示您从以下位置开始执行字段设置为false
,您的代码稍后会将其解释为睁开眼睛的指令。您的核心需求是
MouseListener
。如果您还没有,请查看事件的 Java Trail;它解释了如何实现一个简单的MouseListener
。此时,请注意,MouseListener 是一个接口,因此,您必须为其所有方法提供实现,即使它们是空体方法。您可能需要查看 MouseAdapter 抽象类< /a>.它提供了所有这些方法(以及更多)的空实现,以便您只需要重写您需要的方法 - 这使您的代码更干净,因为您没有一堆空方法只是为了满足编译器的要求。这将解决我相信您在说“并渲染其余三个方法跛脚鸭”时所指的问题。当然,由于您已经扩展了 JPanel,因此无法扩展MouseAdapter
也是如此,因此这不适用于此处。但这(与其他适配器一起)是一个有用的类,稍后需要记住。从那里,我想使用两种方法将此字段设置为 true/false
如果我理解正确的话,您想要的是在鼠标单击时切换
isClosed
的值。所以现在,您有一个MouseListener
/MouseAdapter
,它实际上并没有做任何事情。接下来您需要做的是为MouseClicked()
方法提供一个实现,您可以在其中切换boolean
字段的值。这也非常简单 - 您只需使用!
(NOT) 运算符反转当前值并将其分配回变量 -isClosed = !isClosed;
。您可能希望阅读更详细地了解 Java 中的运算符 .另外,我该如何更改 PaintComponent 方法,以便如果布尔值为 true,则用睁着眼睛绘制对象,如果为 false,则用闭着眼睛绘制头部?< /p>
一种方法是为两只闭着的眼睛创建另外两个形状,类似于睁开眼睛的形状。完成此操作后,根据
isClosed
的值决定绘制哪些眼睛(即闭上的眼睛或睁开的眼睛)就很简单了。因此,您可以使用if
子句 检查isClosed
的值,并在false
时绘制睁开的眼睛,在true
时绘制闭上的眼睛。请注意,由于您的isClosed
值正在点击处理程序中进行修改,因此您需要确保在更改该值时调用repaint()
,否则 Swing 可能无法更新面板立即显示更改,这样您就不会看到任何事情发生。总而言之,实现您想要的目的的一种方法是对
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.
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 yourHead
class - you simply declareboolean isClosed = false;
- indicating that you begin the execution with the field set tofalse
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 simpleMouseListener
. At this point, note thatMouseListener
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 extendMouseAdapter
as well so this doesn't apply here. But this (with other Adapters) is a useful class to keep in mind for later.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 aMouseListener
/MouseAdapter
that doesn't really do anything. What you need to do next is provide an implementation for, lets say, theMouseClicked()
method where you toggle the value of yourboolean
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.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 (i.e. the closed eyes or the open ones) on the basis of the value of
isClosed
. So you'd use anif
clause to check the value ofisClosed
and draw the open eyes when it'sfalse
and the closed eyes whentrue
. Note that since your value ofisClosed
is being modified in your click handler, you need to make sure that you callrepaint()
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
: