如何利用Java中的多个方法?
好的,所以我试着做一个笑脸程序,当它第一次启动时,它应该显示默认的笑脸(这部分工作正常,我想它很棒) 但是,它应该给你两个按钮,从微笑和皱眉按钮中选择,这两个按钮应该重新画出一张脸,显示一个微笑或皱眉,但由于某种原因它不起作用 我一直在读关于图形的书,我知道你不应该在paint()方法之外调用它们,所以我相应地修改了代码,我可以判断按钮是否正常工作,因为我每次都让它们打印一些东西,但实际的重画不起作用。我也尝试过使用repaint()和revalidate()。出于某种原因,如果您使用repaint(),它每次都会重新绘制越来越多的内容,这很奇怪,但也许它的行为应该是这样的 有人能看一下代码,让我知道你认为是什么问题,或者我应该在哪里寻找解决方案吗?我已经使用java有一段时间了,但我从来没有使用过图形:/I我读过你应该使用的setVisible/setSize(或pack())最后,这实际上帮助解决了我之前遇到的一些问题,但当你想画多个东西时,我不知道该怎么办大多数示例只显示了画一个东西如何利用Java中的多个方法?,java,swing,graphics,drawing,graphics2d,Java,Swing,Graphics,Drawing,Graphics2d,好的,所以我试着做一个笑脸程序,当它第一次启动时,它应该显示默认的笑脸(这部分工作正常,我想它很棒) 但是,它应该给你两个按钮,从微笑和皱眉按钮中选择,这两个按钮应该重新画出一张脸,显示一个微笑或皱眉,但由于某种原因它不起作用 我一直在读关于图形的书,我知道你不应该在paint()方法之外调用它们,所以我相应地修改了代码,我可以判断按钮是否正常工作,因为我每次都让它们打印一些东西,但实际的重画不起作用。我也尝试过使用repaint()和revalidate()。出于某种原因,如果您使用repai
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class JSmileFacePanel2 extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
JButton smile = new JButton("SMILE");
JButton frown = new JButton("FROWN");
public JSmileFacePanel2() {
setLayout(new FlowLayout());
setTitle("JSmileFace-V2: Jose M. Tobar");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(frown);
add(smile);
setSize(800, 800);
setVisible(true);
}
public void paint(Graphics g) {
super.paint(g);
//by default should show smiling
g.setColor(Color.YELLOW);
g.fillOval(200, 200, 500, 500);
g.setColor(Color.BLUE);
g.fillOval(300, 360, 50, 50);
g.setColor(Color.BLUE);
g.fillOval(600, 360, 50, 50);
g.drawArc(400, 400, 100, 40, 180, 185);
smile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("SMILE BUTTON CLICKED");
drawSmile(g);
}
});
frown.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("FROWN BUTTON CLICKED");
drawFrown(g);
}
});
}
public void drawSmile(Graphics g) {
g.setColor(Color.YELLOW);
g.fillOval(200, 200, 500, 500);
g.setColor(Color.BLUE);
g.fillOval(300, 360, 50, 50);
g.setColor(Color.BLUE);
g.fillOval(600, 360, 50, 50);
g.drawArc(400, 400, 100, 40, 180, 185);
repaint();
}
public void drawFrown(Graphics g) {
g.setColor(Color.WHITE);
g.fillOval(200, 200, 500, 500);
g.setColor(Color.BLUE);
g.fillOval(300, 360, 50, 50);
g.setColor(Color.BLUE);
g.fillOval(600, 360, 50, 50);
g.drawArc(400, 400, 100, 40, 180, 185);
repaint();
}
public static void main(String[] args) {
JSmileFacePanel2 js = new JSmileFacePanel2();
}
}
主要问题:您正在代码中添加许多ActionLister …无论何时调用
repaint()
,它都会在内部调用paint(Graphics g)
方法,并在您的paint方法中添加actionListener(无论何时重新绘制,它都会一次又一次地调用)
尝试在构造函数中添加actionListener:
public JSmileFacePanel2() {
setLayout(new FlowLayout());
setTitle("JSmileFace-V2: Jose M. Tobar");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(frown);
add(smile);
setSize(800, 800);
setVisible(true);
//here:
smile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("SMILE BUTTON CLICKED");
drawSmile(g);
}
});
frown.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("FROWN BUTTON CLICKED");
drawFrown(g);
}
});
}
您仍然在
paint
方法之外调用绘画方法,因为actionPerformed
方法与paint
方法不同。它们是否在文本中并不重要,这仍然是一种不同的方法
此外,每次发生重新绘制事件时,您都会重复添加操作侦听器,这将使应用程序减速到停止状态,并且也不会正确地重新绘制
因此,在paint
方法中检查是否应该微笑或皱眉,并在构造函数中添加动作侦听器
然后,代码变为:
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class JSmileFacePanel2 extends JFrame {
private static final long serialVersionUID = 1L;
// by default should show smiling
private boolean doSmile = true;
JButton smile = new JButton("SMILE");
JButton frown = new JButton("FROWN");
public JSmileFacePanel2() {
setLayout(new FlowLayout());
setTitle("JSmileFace-V2: Jose M. Tobar");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(frown);
add(smile);
smile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("SMILE BUTTON CLICKED");
doSmile = true;
repaint();
}
});
frown.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("FROWN BUTTON CLICKED");
doSmile = false;
repaint();
}
});
setSize(800, 800);
setVisible(true);
}
public void paint(final Graphics g) {
super.paint(g);
if (doSmile) {
drawSmile(g);
} else {
drawFrown(g);
}
}
public void drawSmile(Graphics g) {
g.setColor(Color.YELLOW);
g.fillOval(200, 200, 500, 500);
g.setColor(Color.BLUE);
g.fillOval(300, 360, 50, 50);
g.setColor(Color.BLUE);
g.fillOval(600, 360, 50, 50);
g.drawArc(400, 400, 100, 40, 180, 185);
}
public void drawFrown(Graphics g) {
g.setColor(Color.WHITE);
g.fillOval(200, 200, 500, 500);
g.setColor(Color.BLUE);
g.fillOval(300, 360, 50, 50);
g.setColor(Color.BLUE);
g.fillOval(600, 360, 50, 50);
g.drawArc(400, 400, 100, 40, 180, 185);
}
public static void main(String[] args) {
JSmileFacePanel2 js = new JSmileFacePanel2();
}
}
一句话,没有。但是,你走对了方向 请记住,您是在事件驱动的环境中运行的,这意味着发生了一些事情,然后您会做出响应 绘制只需绘制当前状态即可,在您的示例中,每次调用
paint
,您都会向按钮添加一个新的ActionListener
,这样,当屏幕显示时,每个按钮都会附加3+ActionListener
s,这将导致一些严重的怪异行为
您也不应该直接或间接地从绘制方法中修改组件的状态,这可能会导致计划重新绘制
,这将导致重复调用绘制方法,最终会消耗CPU周期,至少可以说是混乱的
您还应该避免从顶级容器扩展并覆盖paint
(通常),而是更喜欢使用JPanel
并覆盖它的paintComponent
方法
这有两个主要原因,第一,它将您锁定在一个用例中,这意味着您不能重复使用您的组件;第二,直接绘制到顶级容器,如JFrame
可以让您在框架的装饰/边框下进行绘制,并且由于绘制的方式,甚至让框架内容画在上面
有关详细信息,请参阅和
一般的解决方案是使用一个标志来更改绘制过程的工作方式,并在需要时相应地更改该标志(例如,从按钮的ActionListener
s中)
一个小瑕疵:
不要在actionListener
中调用Draw皱眉(g)
或drawSmile(g)
(你不能再调用了,你不再知道graphics
),而是调用repaint()
但是,在您告诉您的图形将绘制什么之前(我使用的是int
),最好使用Enums
,但现在就可以了
我只是在做微笑部分,皱眉部分是一样的
private int style = 0;
public JSmileFacePanel2() {
//other code as above
...
smile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("SMILE BUTTON CLICKED");
style = 1; //1=smile, 2=frown
repaint(); //this calls internally the paint(g) method
}
});
}
并调整您的绘制方法:
public void paint(Graphics g) {
super.paint(g);
//by default should show smiling
g.setColor(Color.YELLOW);
g.fillOval(200, 200, 500, 500);
g.setColor(Color.BLUE);
g.fillOval(300, 360, 50, 50);
g.setColor(Color.BLUE);
g.fillOval(600, 360, 50, 50);
g.drawArc(400, 400, 100, 40, 180, 185);
if(style == 1){
drawSmile(g);
}
if(style == 2){
drawFrown(g);
}
}
public void paint(Graphics g) {
super.paint(g);
//by default should show smiling
g.setColor(Color.YELLOW);
g.fillOval(200, 200, 500, 500);
g.setColor(Color.BLUE);
g.fillOval(300, 360, 50, 50);
g.setColor(Color.BLUE);
g.fillOval(600, 360, 50, 50);
g.drawArc(400, 400, 100, 40, 180, 185);
if(style == 1){
drawSmile(g);
}
if(style == 2){
drawFrown(g);
}
}