Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何利用Java中的多个方法?_Java_Swing_Graphics_Drawing_Graphics2d - Fatal编程技术网

如何利用Java中的多个方法?

如何利用Java中的多个方法?,java,swing,graphics,drawing,graphics2d,Java,Swing,Graphics,Drawing,Graphics2d,好的,所以我试着做一个笑脸程序,当它第一次启动时,它应该显示默认的笑脸(这部分工作正常,我想它很棒) 但是,它应该给你两个按钮,从微笑和皱眉按钮中选择,这两个按钮应该重新画出一张脸,显示一个微笑或皱眉,但由于某种原因它不起作用 我一直在读关于图形的书,我知道你不应该在paint()方法之外调用它们,所以我相应地修改了代码,我可以判断按钮是否正常工作,因为我每次都让它们打印一些东西,但实际的重画不起作用。我也尝试过使用repaint()和revalidate()。出于某种原因,如果您使用repai

好的,所以我试着做一个笑脸程序,当它第一次启动时,它应该显示默认的笑脸(这部分工作正常,我想它很棒)

但是,它应该给你两个按钮,从微笑和皱眉按钮中选择,这两个按钮应该重新画出一张脸,显示一个微笑或皱眉,但由于某种原因它不起作用

我一直在读关于图形的书,我知道你不应该在paint()方法之外调用它们,所以我相应地修改了代码,我可以判断按钮是否正常工作,因为我每次都让它们打印一些东西,但实际的重画不起作用。我也尝试过使用repaint()和revalidate()。出于某种原因,如果您使用repaint(),它每次都会重新绘制越来越多的内容,这很奇怪,但也许它的行为应该是这样的

有人能看一下代码,让我知道你认为是什么问题,或者我应该在哪里寻找解决方案吗?我已经使用java有一段时间了,但我从来没有使用过图形:/I我读过你应该使用的setVisible/setSize(或pack())最后,这实际上帮助解决了我之前遇到的一些问题,但当你想画多个东西时,我不知道该怎么办大多数示例只显示了画一个东西

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