多线程秒表

时间:2015-10-10 23:38:11

标签: java multithreading

我创建了一个运行4个秒表的程序。随着时间的推移,我在GUI秒表上遇到了麻烦,无法独立打勾但是我已经尝试了所有的东西。

这是应用程序的样子: 4 Stopwatches with keyboard contorl 当线程5到8启动时,GUIClock类中存在问题。

public class Stopwatches extends Application {

    @Override
    public void start(Stage primaryStage) {    
        Time time1 = new Time();
        Time time2 = new Time();
        Time time3 = new Time();
        Time time4 = new Time();
        Text text1 = new Text("00:00:00");
        Text text2 = new Text("00:00:00");
        Text text3 = new Text("00:00:00");
        Text text4 = new Text("00:00:00");
        text1.setFont(Font.font("Times", 35));
        text2.setFont(Font.font("Times", 35));
        text3.setFont(Font.font("Times", 35));
        text4.setFont(Font.font("Times", 35));
        Timeline textClock1 = createTextStopwatch(time1, text1);
        Timeline textClock2 = createTextStopwatch(time2, text2);
        Timeline textClock3 = createTextStopwatch(time3, text3);
        Timeline textClock4 = createTextStopwatch(time4, text4);

        ClockPane clock1 = new ClockPane();
        ClockPane clock2 = new ClockPane();
        ClockPane clock3 = new ClockPane();
        ClockPane clock4 = new ClockPane();

        BorderPane pane = new BorderPane();
        TilePane tilePane = new TilePane();
        tilePane.setPadding(new Insets(15,5,5,5));
        tilePane.setAlignment(Pos.CENTER);
        tilePane.setHgap(40.0);
        tilePane.getChildren().addAll(new VBox(clock1, text1), new VBox(clock2, text2), new VBox(clock3, text3), new VBox(clock4, text4));
        pane.setCenter(tilePane);

        Text message = new Text("Use the Q,W,E,R keys to control the speed of clocks from left to right respectively");
        message.setFont(Font.font("Times", 20));

        Scene scene = new Scene(new BorderPane(pane, message, null, null, null), 1500, 400);
        primaryStage.setTitle("Stop Watch");
        primaryStage.setScene(scene);
        primaryStage.show();

        Runnable task1 = new TextClock(textClock1, clock1, time1);
        Thread thread1 = new Thread(task1);
        Runnable task2 = new TextClock(textClock2, clock2, time2);
        Thread thread2 = new Thread(task2);
        Runnable task3 = new TextClock(textClock3, clock3, time3);
        Thread thread3 = new Thread(task3);
        Runnable task4 = new TextClock(textClock4, clock4, time4);
        Thread thread4 = new Thread(task4);

        Runnable task5 = new GUIClock(clock1, time1);
        Thread thread5 = new Thread(task5);
        Runnable task6 = new GUIClock(clock2, time2);
        Thread thread6 = new Thread(task6);
        Runnable task7 = new GUIClock(clock3, time3);
        Thread thread7 = new Thread(task7);
        Runnable task8 = new GUIClock(clock4, time4);
        Thread thread8 = new Thread(task8);

        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
        thread5.start();
        thread6.start();
        thread7.start();
        thread8.start();

        scene.setOnKeyPressed(e -> {
            if (e.getCode() == Q ){
                textClock1.setRate(20.0);
                clock1.setSecond(time1.getSecond());
            }
            else {
                if (e.getCode() == W ){
                    textClock2.setRate(20.0);
                    clock2.setSecond(time2.getSecond());
                }
                else {
                    if (e.getCode() == E ){
                        textClock3.setRate(20.0);
                        clock3.setSecond(time3.getSecond());
                    }
                    else {
                        if (e.getCode() == R ){
                            textClock4.setRate(20.0);
                            clock4.setSecond(time4.getSecond());
                        }
                    }
                }
            }
        });

        scene.setOnKeyReleased(e -> {
            if (e.getCode() == Q ){
                textClock1.setRate(1.0);
            }
            else {
                if (e.getCode() == W ){
                    textClock2.setRate(1.0);
                }
                else {
                    if (e.getCode() == E ){
                        textClock3.setRate(1.0);
                    }
                    else {
                        if (e.getCode() == R ){
                            textClock4.setRate(1.0);
                        }
                    }
                }
            }
        });
    }

    public Timeline createTextStopwatch(Time time, Text text) {
        Timeline animation = new Timeline(
        new KeyFrame(Duration.millis(1000), e -> {
            time.increase();
            text.setText(time.toString());
        }));
        animation.setCycleCount(Timeline.INDEFINITE);
        return animation;
    }

    public static void main(String[] args) {
        launch(args);
    }
}

class GUIClock implements Runnable {
    ClockPane clock;
    Time time;

    public GUIClock(ClockPane clock, Time time) {
        this.clock = clock;
        this.time = time;
    }

    @Override
    public void run() {
        clock.setSecond(time.getSecond());
    }

}

class TextClock implements Runnable {
    Timeline textClock;
    ClockPane clock;
    Time time;

    public TextClock(Timeline textClock, ClockPane clock, Time time) {
        this.textClock = textClock;
        this.clock = clock;
        this.time = time;

    }
    @Override
    public void run() {
        textClock.play();
    }

}

这是创建和更改GUI时钟的ClockPane类:

public class ClockPane extends Pane {
    private int hour;
    private int minute;
    private int second;
    private double w = 250, h = 250;

    public ClockPane() {
        this.hour = 0;
        this.minute = 0;
        this.second = 0;
        paintClock();
    }

    public void increaseTime() {

    }

    protected void paintClock() {
        double clockRadius = Math.min(w, h) * 0.8 * 0.5;
        double centreX = w / 2;
        double centreY = h / 2;

        Circle circle = new Circle(centreX, centreY, clockRadius);
        circle.setFill(Color.WHITE);
        circle.setStroke(Color.BLACK);
        Text t1 = new Text(centreX - 5, centreY - clockRadius + 12, "0");
        Text t2 = new Text(centreX - clockRadius + 3, centreY + 5, "45");
        Text t3 = new Text(centreX + clockRadius - 10, centreY + 3, "15");
        Text t4 = new Text(centreX - 3, centreY + clockRadius -3, "30");

        double sLength = clockRadius * 0.8;
        double secondX = centreX + sLength * Math.sin(second * (2 * Math.PI / 60));
        double secondY = centreY - sLength * Math.cos(second * (2 * Math.PI / 60));
        Line sLine = new Line(centreX, centreY, secondX, secondY);
        sLine.setStroke(Color.RED);

        getChildren().clear();
        getChildren().addAll(circle, t1, t2, t3, t4, sLine);
    }

    public void setSecond(int time) {
        this.second = time;
        paintClock();
    }

}

也许不重要,但这里也是控制时间流逝的时间类:

public class Time {
    int value = 0;

    int getSecond() {
      return value % 60;
    }

    int getMinute() {
      return (value / 60) % 60;
    }

    int getHour() {
      return value / 3600;
    }  

    void reset() {
      value = 0;
    }

    void increase() {
      value++;
    }

    @Override
    public String toString() {
      return getTwoDigitString(getHour()) + ":" + getTwoDigitString(getMinute())
        + ":" + getTwoDigitString(getSecond());
    }

    static String getTwoDigitString(int v) {
      if (v < 10)
        return "0" + v;
      else
        return "" + v;
    }
  }

1 个答案:

答案 0 :(得分:0)

sLine.setStroke(),你没有掩盖最后一行?我注意到?我认为我也看到,这个问题涉及到你的信号量,你隐藏了你的TextClock。您应该只描述一个在GUI中作用的信号量,它会改变时间。您可以立即使用GUIClock的 prime 目标。虽然那可能只是我。现在,increaseTime()中没有任何内容。 Annndd ..是的。我想就是这样。