我想我的jframe在这个程序中是正确的,但不确定

时间:2013-11-13 22:31:12

标签: java swing

我想我已经在这个程序中使用了jframe,但是当我运行它时为什么没有出现? 我有两个不同的课程,这是我的第一个课程。只需忽略最后一个方法,我将在其中绘制一个带圆圈的矩形作为红绿灯。

这是我的代码。

package trafficlight;

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

public class TrafficLight {

private int goDuration;
private int stopDuration;
private int warnDuration;

public enum State {STOP, GO, WARN};
public Color GO_COLOR = Color.green;
public Color STOP_COLOR = Color.red;
public Color OFF_COLOR = Color.darkGray;
public Color WARNING_COLOR = Color.yellow;
private State currentState;


public TrafficLight() {
goDuration =  2;
stopDuration = 2;
warnDuration =1;
currentState =  State.GO;
}

public void changeLight(){
if(currentState  == State.GO){
        currentState = State.WARN;
}
if(currentState == State.WARN){
        currentState = State.STOP;
}
if(currentState == State.STOP){
        currentState = State.GO;
}
}


public int getGoDuration() {
    return goDuration;
}

public void setGoDuration(int goDuration) {
    this.goDuration = goDuration;
}

public int getStopDuration() {
    return stopDuration;
}

public void setStopDuration(int stopDuration) {
    this.stopDuration = stopDuration;
}

public int getWarnDuration() {
    return warnDuration;
}

public void setWarnDuration(int warnDuration) {
    this.warnDuration = warnDuration;
}

public State getCurrentState() {
    return currentState;
}

public void setCurrentState(State currentState) {
    this.currentState = currentState;
}
public int getCurrentDuration(){
    int duration = 0;
    if (currentState == State.STOP){
        duration = stopDuration;
    }
    if (currentState == State.GO){
        duration = goDuration;
    }
    if (currentState == State.WARN){
        duration = warnDuration;
    }
    return duration;
}
public void draw(Graphics canvas) {
    canvas.drawRect(125,185,100,250);
    canvas.drawOval(145,200,60,60);
    canvas.drawOval(145,280,60,60);
    canvas.drawOval(145,360,60,60);

    if (currentState == State.STOP){

    }


}

}

这是我的第二堂课。

package trafficlight;
import java.awt.*;
import javax.swing.*;

public class TrafficLightDriver extends JFrame {

private static TrafficLight light;

public void message() {
}

public static void main(String[] args) {
    TrafficLightDriver myFrame = new TrafficLightDriver();
    int delay, answer;
    String valueString;

    do {
        valueString = JOptionPane.showInputDialog("What is the green light delay? (1.. 10)");
        light.setGoDuration(Integer.parseInt(valueString));
        valueString = JOptionPane.showInputDialog("What is the yellow light delay? (1.. 10)");
        light.setWarnDuration(Integer.parseInt(valueString));
        valueString = JOptionPane.showInputDialog("What is the red light delay? (1.. 10)");
        light.setStopDuration(Integer.parseInt(valueString));
        for (int i = 1; i <= 10; i++) {
            delay = light.getCurrentDuration();
            Wait.manySec(delay);
            light.changeLight();
            myFrame.repaint();
        }
        answer = JOptionPane.showConfirmDialog(null, "Would you like to run the light again?",
                null, JOptionPane.YES_NO_OPTION);
    } while (answer == JOptionPane.YES_OPTION);
    System.exit(0);
}

@Override
public void paint(Graphics canvas) {
    light.draw(canvas);
}

public TrafficLightDriver() {  //constructor
    setSize(350, 600);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    light = new TrafficLight();
    setVisible(true);
}
}

这是我的等候课

package trafficlight;

public class Wait {

public static void oneSec() {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        System.err.println(e);
    }
}

public static void manySec(long s) {
    try {
        Thread.sleep(s * 1000);
    } catch (InterruptedException e) {
        System.err.println(e);
    }
}

public static void tenthOfSec(long s) {
    try {
        Thread.sleep(s * 100);
    } catch (InterruptedException e) {
        System.err.println(e);
    }
}
}

2 个答案:

答案 0 :(得分:1)

  1. 您应该避免覆盖paint顶级容器,而应该使用JPanel之类的内容并覆盖它的paintComponent方法。
  2. 绘制过程是一系列链接方法,所有这些方法都构建在彼此之上以生成输出,当您打破此更改时,您允许引入工件和不规则性。通过始终致电super.paintXxx
  3. ,确保您尊重油漆链
  4. Swing是一个单线程框架。也就是说,有一个线程负责处理系统中的所有事件,包括重绘请求。这意味着如果您出于任何原因阻止此线程,您将阻止处理任何新事件,这将使您的程序显示为已挂起。您还需要确保对此UI的任何更新都是在此线程的上下文中进行的。
  5. 首先阅读

    现在,我不知道你Wait班的工作方式,所以我不能对那部分发表评论,但是你的TrafficLight没有更新自己以反映它的当前状态... < / p>

    <强>更新...

    您还有两个main方法非常令人困惑。应用程序逻辑似乎在TrafficLightDriver中,您应该确保在执行程序时运行此类。

    您的changeLight方法

    存在逻辑问题
    public void changeLight(){
        if(currentState  == State.GO){
            currentState = State.WARN;
        }
        if(currentState == State.WARN){
            currentState = State.STOP;
        }
        if(currentState == State.STOP){
            currentState = State.GO;
        }
    }
    

    基本上,这就是说......

    如果currentState为GO,则将currentState设置为WARN ...
    如果currentState是WARN,则将currentState设置为STOP ...
    如果currentState为STOP,则将currentState设置为GO ...

    鉴于默认状态为GO,当您调用此方法时,状态永远不会更改为GO以外的任何其他状态。相反,您应该使用if-else语句

    public void changeLight() {
        if (currentState == State.GO) {
            currentState = State.WARN;
        } else if (currentState == State.WARN) {
            currentState = State.STOP;
        } else if (currentState == State.STOP) {
            currentState = State.GO;
        }
    }
    

    <强>更新

    渲染灯光本身很大程度上取决于个人喜好,例如,我可能会想做类似......

    switch (getCurrentState()) {
        case GO:
            canvas.setColor(GO_COLOR);
            canvas.drawOval(145,360,60,60);
            break;
        case WARN:
            canvas.setColor(WARNING_COLOR);
            canvas.drawOval(145,280,60,60);
            break;
        case STOP:
            canvas.setColor(STOP_COLOR);
            canvas.drawOval(145,200,60,60);
            break;
    }
    canvas.setColor(OFF_COLOR);
    canvas.drawRect(125,185,100,250);
    canvas.drawOval(145,200,60,60);
    canvas.drawOval(145,280,60,60);
    canvas.drawOval(145,360,60,60);
    

    这将填充活动的灯光,但随后将所有其他内容渲染到顶部,因此灯光始终被勾勒出来

答案 1 :(得分:0)

您调用System.exit()。这会杀死java VM并结束程序。删除该行。

如果要在关闭JFrame时控制程序的行为,请使用frame.setDefaultCloseOperation()。