简体   繁体   English

我必须画一个笑脸,并使用Graphics和Timer使它的左眼眨眼,但它不会眨眼

[英]I have to draw a smiley face and make its left eye blink using Graphics and Timer, but it doesn't blink

I start the timer and call paintRect to redraw the eye and create the blink effect but it's not working. 我启动计时器,并调用paintRect重绘眼睛并创建眨眼效果,但是它不起作用。 I call paintEye to draw the left eye again but with a yellow color. 我调用paintEye再次绘制左眼,但颜色为黄色。

I'm still trying to learn ActionListener works, so I'm not sure if I'm getting it right, which doesn't look like anyway. 我仍在尝试学习ActionListener工作原理,所以不确定是否正确,无论如何看起来都不对。

import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

public class Content extends JPanel {

    public Content() {
    }

    @Override
    public void paintComponent(Graphics g) {

        //face
        g.setColor(Color.yellow);
        g.fillOval(10, 10, 200, 200);

        //eyes
        g.setColor(Color.black);
        g.fillOval(55, 65, 30, 30);
        g.fillOval(135, 65, 30, 30);

        //mouth
        g.setColor(Color.black);
        g.fillOval(50, 110, 120, 60);

        //touchUp
        g.setColor(Color.YELLOW);
        g.fillRect(50, 110, 120, 30);
        g.fillOval(50, 120, 120, 40);

        time.start();
        paintEye(super.getComponentGraphics(g));

        //eyesAgain
        g.setColor(Color.black);
        g.fillOval(55, 65, 30, 30);
    }

    public void paintEye(Graphics grphcs) {

        grphcs.setColor(Color.yellow);
        grphcs.fillOval(55, 65, 30, 30);
    }

    Timer time = new Timer(100, new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {


            repaint();
        }
    });

}

You've problems (as noted within comments) 您遇到了问题(如评论中所述)

  • Your Timer's ActionListener should change the state of an instance field, say a boolean called blink . 您的Timer的ActionListener应该更改实例字段的状态,例如一个名为blink的布尔值。 I'd simply toggle its value: blink = !blink; 我倒是简单地拨动它的值: blink = !blink; , and then call repaint() 然后调用repaint()
  • Your paintComponent should use the value of this boolean to decide what to paint, an open or closed eye 您的paintComponent应该使用此布尔值来决定要绘画的内容(睁开或闭眼)
  • NEVER start or stop the Timer within the paintComponent method, but rather do so elsewhere such as in the constructor. 永远不要在paintComponent方法中启动或停止Timer,而要在其他地方(例如在构造函数中)启动或停止Timer。 The painting methods are for painting and painting only since you don't have full control over when or even if it is called, and you really only need to call start() on the Timer once, at the beginning of the program. 绘画方法仅用于绘画,因为您无法完全控制何时或什至没有调用它,并且您实际上只需要在程序start()时在Timer上调用一次start()即可。
  • Your paintComponent method must call its super's method, first thing to clear out any "dirty" pixels -- eg, the closed eye or the open eye images: 您的paintComponent方法必须调用其super的方法,首先要清除所有“脏”像素-例如,闭眼或睁眼图像:

@Override 
protected void paintComponent(Graphics g) {
    super.paintComponent(g); // ***** here

    // .... rest of the code goes below

    if (blink) {
        // ....
    } else {
        // ....
    }
}

eg, a simple toggle program 例如,一个简单的切换程序

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.*;

public class Foo01 extends JPanel {
    private static final int PREF_W = 600;
    private static final int PREF_H = PREF_W;
    private static final Color COLOR_1 = Color.RED;
    private static final Color COLOR_2 = Color.BLUE;
    private static final int TIMER_DELAY = 100;
    private static final int RECT_X = 100;
    private static final int RECT_W = 400;
    private boolean blink = false;

    public Foo01() {
        setPreferredSize(new Dimension(PREF_W, PREF_H));
        new Timer(TIMER_DELAY, e -> {
            blink = !blink;
            repaint();
        }).start();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (blink) {
            g.setColor(COLOR_1);
        } else {
            g.setColor(COLOR_2);
        }
        g.fillRect(RECT_X, RECT_X, RECT_W, RECT_W);
    }

    private static void createAndShowGui() {
        Foo01 mainPanel = new Foo01();

        JFrame frame = new JFrame("Foo01");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM