2015-10-10 2 views
1

Я создал программу, которая запускает 4 секундомера. У меня возникают проблемы с тем, чтобы руки на секундомерах графического интерфейса галочками независимо от времени, но я все пробовал.Многопоточные секундомеры

Это приложение выглядит следующим образом: 4 Stopwatches with keyboard contorl Проблема возникает в классе GUIClock при запуске потоков с 5 по 8.

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

} 

Вот класс ClockPane, который создает и изменяет GUI часы:

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

} 

Возможно неважным, но здесь также класс Time, который контролирует ход времени:

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; 
    } 
    } 
+0

По-прежнему нужна помощь в этом. –

ответ

0

В sLine.setStroke() вы не скрываете последнюю строку? Я заметил? Я также думаю, что этот вопрос связан с вашим семафором, где вы скрываете свой TextClock. Вероятно, вам следует просто описать семафор, который действует в графическом интерфейсе, который меняет время. Вы непосредственно с вашим цель объектив, который GUIClock. Хотя это может быть только я. Теперь у вас ничего нет в increaseTime(). Энндд .. да. Я думаю, что все.

Смежные вопросы