Я создал программу, которая запускает 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;
}
}
По-прежнему нужна помощь в этом. –