【问题标题】:How to repeatedly change colors of a circle using a timer in a Java GUI?如何在 Java GUI 中使用计时器重复更改圆圈的颜色?
【发布时间】:2021-01-16 13:02:18
【问题描述】:

我正在尝试使用 Java GUI 创建一个交通信号灯,它只显示一个圆圈,并将颜色从红色变为黄色,再变为绿色。应该有一个计时器,只有黄色应该在 3 秒内变为绿色。我已经设置了一个圆圈和一个红色,但我无法使用计时器将其分别更改为黄色和绿色。

顺便说一句,我对 GUI 非常陌生,无法在线找到有用的资源,尽管我仍然观看了一些 youtube 视频,但没有发现任何有用或与此任务相关的内容。任何帮助将不胜感激!

代码:

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

预期输出:

https://www.youtube.com/watch?v=8dn-_3t3XQE

注意:它应该只有一个圆圈,但它的行为应该与预期输出中的一样。

【问题讨论】:

  • 使用计时器。 - 好吧,您还没有发布任何计时器代码,所以我们无法猜测您可能尝试过或未尝试过什么。我们不是来为您编写代码的。按照我下面的建议后,如果您仍然需要帮助,请发布正确的minimal reproducible example 来证明问题。
  • (1-) 但没有找到任何有用的或与此任务相关的内容。 - 当然,您不会找到作业的确切代码。我为您提供了一个完整的工作示例,说明如何使用 Swing Timer。重点是让您了解 Timer 的基本概念,然后根据您的具体要求编写代码。

标签: java swing user-interface graphics


【解决方案1】:
  1. 不要扩展 Canvas。 Swing 中的自定义绘制是通过扩展JPanel 并覆盖paintComponent() 方法来完成的。阅读 Custom Painting 上的 Swing 教程部分,了解更多信息和工作示例。

  2. 绘制方法应该只绘制类的当前状态。因此,您需要将setLightColor(Color lightColor) 之类的方法添加到执行自定义绘画的组件中。然后在绘画方法中,您使用该值作为圆圈的颜色(而不是硬编码“RED”)。或者你有一个像 changeLight() 这样的方法,它可以从 0, 1, 2, 0, 1, 2... 更新一个变量。然后在绘制方法中检查变量的状态并绘制适当的颜色。

  3. 您需要使用Swing Timer 来安排活动。当 Timer 触发时,您调用类上的 setLightColor(...) 方法。

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

您可以查看:https://stackoverflow.com/a/7816604/131872,了解 Swing Timer 的基本示例。

【讨论】:

  • 你能给我看一个包含我的代码的示例吗?我是 GUI 新手,所以我基本上一无所知
  • 我给你举了很多例子。您尚未使用 minimal reproducible example 更新您的问题,显示您已尝试过的内容。我们不是来为您编写代码的。你通过尝试来学习。因此,采用工作代码并进行更改。第一步是从自定义绘画教程中获取代码,并了解如何正确进行自定义绘画的基础知识。然后添加 Timer 逻辑。一步一步解决问题。
【解决方案2】:

这是一种方法。指示灯保持亮起 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) {
        // 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);
        
    }
    
}

【讨论】:

  • @HussainOmer,我的导师希望它真的很容易,因为 - 我认为你的导师希望你自己编写代码。这就是为什么我没有发布工作代码,只给你关于所需步骤的建议。我相信“授人以鱼,终生食。授人以渔,终生食”。我试图向您展示这些步骤,以便您可以自己编写代码,并为向您的导师展示您的想法而感到自豪。所以要努力,不要指望人们因为太复杂而“简化”代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-26
  • 1970-01-01
  • 1970-01-01
  • 2016-03-05
  • 2012-06-27
  • 1970-01-01
相关资源
最近更新 更多