如何在Java GUI中使用计时器重复更改圆形的颜色?

huangapple go评论82阅读模式
英文:

How to repeatedly change colors of a circle using a timer in a Java GUI?

问题

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

public class Main extends Canvas {
    private Color currentColor;
    private Timer timer;
    private int timerCount;

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        Canvas canvas = new Main();
        canvas.setSize(700, 700);
        frame.add(canvas);
        frame.pack();
        frame.setVisible(true);
    }

    public Main() {
        currentColor = Color.red;
        timerCount = 0;
        timer = new Timer(1000, new TimerListener());
        timer.start();
    }

    public void paint(Graphics g) {
        g.setColor(currentColor);
        g.fillOval(200, 200, 300, 300);
    }

    private class TimerListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            timerCount++;
            if (timerCount == 1) {
                currentColor = Color.yellow;
                repaint();
            } else if (timerCount == 4) {
                currentColor = Color.green;
                repaint();
                timer.stop();
            }
        }
    }
}
英文:

I am trying to create a traffic light using a Java GUI, where it displays only one circle and it changes colours from red, to yellow, to green. There should be a timer and only yellow should be changing to green within 3 seconds. I have set up a circle and a colour red, but I am unable to change it to the colours yellow, and green respectively using a timer.

Btw I am really new to GUI and could not find helpful sources online, although I still watched a couple of youtube videos but did not find anything useful or relevant to this task. Any help would be much appreciated!

Code:

import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Color;
import javax.swing.JFrame;
public class Main extends Canvas {
public static void main(String[] args) {
JFrame frame = new JFrame();
Canvas canvas = new Main();
canvas.setSize(700, 700);
frame.add(canvas);
frame.pack();
frame.setVisible(true);
}
public void paint(Graphics g) {
g.setColor(Color.red);
g.fillOval(200, 200, 300, 300);
}
}

Expected Output:

It should be only one circle

答案1

得分: 1

  1. 不要扩展Canvas。在Swing中,自定义绘图是通过扩展JPanel并覆盖paintComponent()方法来完成的。阅读Swing教程中关于自定义绘图的部分,获取更多信息和工作示例。

  2. 绘图方法应该只绘制类的当前状态。因此,您需要添加一个类似于setLightColor(Color lightColor)的方法到您的组件中,该方法用于进行自定义绘图。然后在绘图方法中,您可以使用该值作为圆的颜色(而不是硬编码为“RED”)。或者您可以有一个类似于changeLight()的方法,该方法更新一个从0、1、2、0、1、2...开始的变量。然后在绘图方法中,您可以检查变量的状态并绘制相应的颜色。

  3. 您需要使用Swing定时器来安排一个事件。当定时器触发时,调用您类上的setLightColor(...)方法。

  4. 定时器应该是执行自定义绘图的类的一部分。您应该有一个方法可以启动/停止定时器。

您可以查看这个链接:https://stackoverflow.com/a/7816604/131872,获取Swing定时器的基本示例。

英文:
  1. Don't extend Canvas. Custom painting in Swing is done by extending JPanel and by overriding the paintComponent() method. Read the section from the Swing tutorial on Custom Painting for more information and working examples.

  2. A painting method should only paint the current state of the class. So you would need to add a method like setLightColor(Color lightColor) to your component that does the custom painting. Then in the painting method you use that value for the Color of your circle (instead of hard coding "RED"). Or you have a method like changeLight() that updates a varable from 0, 1, 2, 0, 1, 2... . Then in the painting method you you check the state of the variable and paint the appropriate color.

  3. You need to use a Swing Timer to schedule an event. When the Timer fires you invoke the setLightColor(...) method on your class.

  4. The Timer should be part of your class that does the custom painting. You should have a method that can start/stop the Timer.

You can check out: https://stackoverflow.com/a/7816604/131872 for a basic example of the Swing Timer.

答案2

得分: 1

这里是一个方法。灯亮持续3秒。要更改它们的持续时间,必须相应地修改代码。这将在计时器内完成。

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

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class TrafficLight extends JPanel {
	JFrame frame = new JFrame();
	
	int colorIdx = 0;
	Color[] colors = { Color.green, Color.yellow, Color.red };
	
	public static void main(String[] args) {
		// 确保程序在事件分派线程上启动
		SwingUtilities.invokeLater(() -> new TrafficLight().start());
	}
	
	public void start() {
		// 设置
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		// 设置首选大小。在这种情况下可以,但最佳实践是覆盖 getPreferredSize()
		setPreferredSize(new Dimension(500, 500));
		
		frame.add(this);
		frame.pack();
		
		// 在屏幕上居中
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
		
		Timer t = new Timer(3000, ae -> {
			colorIdx = colorIdx >= 2 ? 0 : colorIdx + 1;
			repaint();
		});
		t.start();
	}
	
	
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		
		g.setColor(colors[colorIdx]);
		g.fillOval(150, 150, 200, 200);
		
	}
	
}
英文:

Here is one approach. The lights stay on for 3 seconds. To change their duration the code must be modified accordingly. This would be done inside the timer.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class TrafficLight extends JPanel {
JFrame frame = new JFrame();
int colorIdx = 0;
Color[] colors = { Color.green, Color.yellow, Color.red };
public static void main(String[] args) {
// Ensure the program is started on the Event Dispatch Thread
SwingUtilities.invokeLater(() -> new TrafficLight().start());
}
public void start() {
// set up
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// set the preferred size. Okay in this instance but best
// practice dictates to override getPreferredSize()
setPreferredSize(new Dimension(500, 500));
frame.add(this);
frame.pack();
// center on screen
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Timer t = new Timer(3000, ae -> {
colorIdx = colorIdx >= 2 ? 0 : colorIdx + 1;
repaint();
});
t.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(colors[colorIdx]);
g.fillOval(150, 150, 200, 200);
}
}
</details>

huangapple
  • 本文由 发表于 2020年10月1日 03:41:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/64144653.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定