С Новым годом! Форум программистов, компьютерный форум, киберфорум
Java: GUI, графика
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 18.11.2021
Сообщений: 64

Изменение координат кнопки через потоки

29.12.2022, 14:27. Показов 2732. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
public class MainFrame extends JFrame {
    private int width = 1980;
    private int height = 1020;
 
    public MainFrame()
    {
        this.setSize(this.width, this.height);
        this.setTitle("Гонка    ");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
 
        JPanel panel = new JPanel();
        panel.setLayout(null);
 
 
        JButton Button1 = new JButton("Первая кнопка");
        JButton Button2 = new JButton("Вторая кнопка");
        JButton Start = new JButton("Начать гонку");
        Button1.setBounds(0, 50, 100, 50);
        Button2.setBounds(0, 150, 100, 50);
        Start.setBounds(0, 500, 300, 50);
 
        panel.add(Button1);
        panel.add(Button2);
        panel.add(Start);
        getContentPane().add(panel);
        setVisible(true);
 
 
        class StartActionListener implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent event) {
 
            }
        }
 
        Start.addActionListener(new StartActionListener());
    }
}
У меня есть 2 кнопки, мне нужно в разных потоках менять их координаты по иксу, устраивая своеобразную "гонку", но не очень понимаю как это сделать
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.12.2022, 14:27
Ответы с готовыми решениями:

Изменение координат кнопки
Здравствуйте, вопрос как программно изменять координаты кнопки ? ниже приведу ссылки с помощью которых пытался разобраться, возможно...

Изменение координат picturebox' а по нажатии кнопки
У меня есть picturebox к его вертикальным Y координатам надо прибавить значение переменной, и так чтобы значение переменной прибавлялост по...

Изменение координат кнопки в событии SizeChanged формы
Накидал такой код Public Class Form1 Public Sub Form1_Load() Handles MyBase.Load Dim x As New Button ...

5
wound up as Aussie
325 / 106 / 19
Регистрация: 15.05.2019
Сообщений: 434
29.12.2022, 16:22
Ну хотя бы вот так. (правда я сделал так, что надо каждый раз нажимать на кнопку "начать гонку"). Можно, конечно, и в потоках....

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
public class MainFrame extends JFrame {
    private int width = 1980;
    private int height = 1020;
    int xb1 = 0;
    int xb2 = 0;
 
    public MainFrame()
    {
        this.setSize(this.width, this.height);
        this.setTitle("Гонка    ");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
 
        JPanel panel = new JPanel();
        panel.setLayout(null);
 
 
        JButton Button1 = new JButton("Первая кнопка");
        JButton Button2 = new JButton("Вторая кнопка");
        JButton Start = new JButton("Начать гонку");
        Button1.setBounds(xb1, 50, 100, 50);
        Button2.setBounds(xb2, 150, 100, 50);
        Start.setBounds(0, 500, 300, 50);
 
        panel.add(Button1);
        panel.add(Button2);
        panel.add(Start);
        getContentPane().add(panel);
        setVisible(true);
 
 
        class StartActionListener implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent event) {
                if ("Начать гонку".equals(Start.getText())){
                  xb1= xb1 + 5;
                  xb2 = xb2 + 12; 
                  Button1.setBounds(xb1, 50, 100, 50);
                  Button2.setBounds(xb2, 150, 100, 50);
                }
            }
        }
 
        Start.addActionListener(new StartActionListener());
    }
    public static void main (String[] args){
     new MainFrame();
    }
}
0
wound up as Aussie
325 / 106 / 19
Регистрация: 15.05.2019
Сообщений: 434
30.12.2022, 10:31
Через потоки будет примерно так.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//import java.awt.Color;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
public class MainFrame extends JFrame {
 
    private final int width = 1980;
    private final int height = 1020;
    public static int xb1 = 0;
    public static int xb2 = 0;
    JButton Button1 = new JButton("Первая кнопка");
    JButton Button2 = new JButton("Вторая кнопка");
    JButton Start = new JButton("Начать гонку");
    JLabel car1_Xcoord = new JLabel();
    JLabel car2_Xcoord = new JLabel();
    JLabel Finish = new JLabel();
    JLabel Finish2 = new JLabel();
 
    public MainFrame() {
        this.setSize(this.width, this.height);
        this.setTitle("Гонка    ");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
 
        JPanel panel = new JPanel();
        panel.setLayout(null);
 
        Button1.setBounds(xb1, 50, 100, 50);
        Button2.setBounds(xb2, 150, 100, 50);
        Start.setBounds(0, 500, 300, 50);
        car1_Xcoord.setBounds(0, 600, 300, 50);
        car1_Xcoord.setText(Integer.toString(xb1));
        car2_Xcoord.setBounds(200, 600, 300, 50);
        car2_Xcoord.setText(Integer.toString(xb1));
        Finish.setBounds(0, 650, 300, 50);
        Finish.setText("Машина №1");
        Finish2.setBounds(200, 650, 300, 50);
        Finish2.setText("Машина №2");
 
        panel.add(Button1);
        panel.add(Button2);
        panel.add(Start);
        panel.add(car1_Xcoord);
        panel.add(car2_Xcoord);
        panel.add(Finish);
        panel.add(Finish2);
        getContentPane().add(panel);
        setVisible(true);
 
        class MyThread extends Thread {
 
            int xCoord;
            int nxb1, nxb2;
 
            MyThread(Integer xCoord) {
                this.xCoord = xCoord;
            }
 
            @Override
            public void run() {
                Thread thr;
                thr = Thread.currentThread();
 
                String strCond = thr.getName();
                switch (strCond) {
                    case "1":
                        for (int i = 0; i < 700; i++) {
                            nxb1 = xCoord + i * 2;
                            Button1.setBounds(nxb1, 50, 100, 50);
                            car1_Xcoord.setText(Integer.toString(nxb1));
                            try {
                                Thread.sleep((int) (20 * Math.random()));
                            } catch (InterruptedException ex) {
                            }
 
                            if (nxb1 > 1000) {
                               /* Finish2.setForeground(Color.red);
                                Finish2.setText("Машина №1 выиграла");
                                Finish.setText("Maшина №2 проиграла");*/
                                thr.stop();
                                break;
                            }
                        }
                    case "2":
                        for (int i = 0; i < 700; i++) {
                            nxb2 = xCoord + i * 2;
                            Button2.setBounds(nxb2, 150, 100, 50);
                            car2_Xcoord.setText(Integer.toString(nxb2));
                            try {
                                Thread.sleep((int) (20 * Math.random()));
                            } catch (InterruptedException ex) {
                            }
                            if (nxb2 > 1000) {
                               /* Finish2.setForeground(Color.red);
                                Finish2.setText("Машина №2 выиграла");
                                Finish.setText("Maшина №1 проиграла");*/
                                thr.stop();
                                break;
                            }
                        }
                } //switch
            }
        }
        class StartActionListener implements ActionListener {
 
            @Override
            public void actionPerformed(ActionEvent event) {
                if ("Начать гонку".equals(Start.getText())) {
                    // new MyThread((int)(10*Math.random())).start();
                    Thread thr1 = new Thread(new MyThread((int) (20 * Math.random())), "1");
                    Thread thr2 = new Thread(new MyThread((int) (20 * Math.random())), "2");
                    thr1.start();
                    thr2.start();
 
                }
            }
        }
        Start.addActionListener(new StartActionListener());
    }
    
    public static void main(String[] args) {
        new MainFrame();
    }
}
0
wound up as Aussie
325 / 106 / 19
Регистрация: 15.05.2019
Сообщений: 434
09.06.2023, 12:01
Сегодня ночью было делать особо нечего ))). Случайно нашёл недописанный код на этой теме. Дописал и чуть "разбавил". Хоть ТС и куда-то давно пропал, но может будет ещё кому-то полезно увидеть простые приёмы (хоть, возможно, и не самые лучшие).
Вот рабочий код со счётчиками времени, помоему это с Java8 включили этот класс. Ну там по мелочи - какой поток будет запущен первым, например. (хотя там есть некоторые шероховатости - заметно, что цвета победителей переключаются, но уже оставил всё как есть - уснул. )))))))))) ).
(комменты с Instant оставил для понимания).

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.Instant;
 
public class MainFrame extends JFrame {
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    int width = (int) screenSize.getWidth();
    int height = (int) screenSize.getHeight();
    //private final int width = 1980;
    //private final int height = 1020;
    public static int xb1 = 0;
    public static int xb2 = 0;
    JButton Button1 = new JButton("Первая кнопка");
    JButton Button2 = new JButton("Вторая кнопка");
    JButton Start = new JButton("Начать гонку");
    JLabel car1_Xcoord = new JLabel();
    JLabel car2_Xcoord = new JLabel();
    JLabel Finish = new JLabel();
    JLabel Finish2 = new JLabel();
    JLabel FinLine = new JLabel();
 
    public MainFrame() {
        this.setSize(this.width, this.height);
        this.setTitle("Гонка    ");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
 
        JPanel panel = new JPanel();
        panel.setLayout(null);
 
        Button1.setBounds(xb1, 50, 100, 50);
        Button2.setBounds(xb2, 150, 100, 50);
        Start.setBounds(0, 500, 300, 50);
        Font font = new Font("Serif", Font.BOLD, 24);
        car1_Xcoord.setFont(font);
        car2_Xcoord.setFont(font);
        car1_Xcoord.setBounds(0, 600, 300, 50);
        car1_Xcoord.setText(Float.toString(xb1)+" ms");
        car2_Xcoord.setBounds(200, 600, 300, 50);
        car2_Xcoord.setText(Float.toString(xb2)+" ms");
        Finish.setBounds(0, 650, 300, 50);
        Finish.setText("Машина №1");
        Finish2.setBounds(200, 650, 300, 50);
        Finish2.setText("Машина №2");
        FinLine.setBounds(1400, 100, 50, 50);
        FinLine.setText("Финиш!");
        
 
        panel.add(Button1);
        panel.add(Button2);
        panel.add(Start);
        panel.add(car1_Xcoord);
        panel.add(car2_Xcoord);
        panel.add(Finish);
        panel.add(Finish2);
        panel.add(FinLine);
        getContentPane().add(panel);
        setVisible(true);
 
        class MyThread extends Thread {
 
            int xCoord;
            int nxb1, nxb2;
           
            MyThread(Integer xCoord) {
                this.xCoord = xCoord;
            }
/*Instant start = Instant.now(); // счётчик времени в миллисекундах
// выполнение какой-то логики
Thread.sleep(1000);
Instant finish = Instant.now();
long elapsed = Duration.between(start, finish).toMillis();
System.out.println("Прошло времени, мс: " + elapsed);*/
            
            @Override
            public void run() {
                Thread thr;
                long elapsed1=0;
                long elapsed2=0;
                thr = Thread.currentThread();
                Instant start = Instant.now();
                String strCond = thr.getName();
                switch (strCond) {
                    case "1":
                        for (int i = 0; i < 700; i++) {
                            nxb1 = xCoord + i * 2;
                            Button1.setBounds(nxb1, 50, 100, 50);
                            //car1_Xcoord.setText(Integer.toString(nxb1));
                            Instant finish1 = Instant.now();
                           
                            try {
                                Thread.sleep((int) (20 * Math.random()));
                            } catch (InterruptedException ex) {
                            }
 
                            if (nxb1 > 1350) {
                                Finish.setForeground(Color.red);
                                Finish.setText("Машина №1 проиграла");
                                Finish2.setForeground(Color.green);
                                Finish2.setText("Maшина №2 выиграла");
                                Button1.setBackground(Color.red);
                                Button2.setBackground(Color.green);
                                thr.stop();
                                car1_Xcoord.setText(Float.toString(elapsed1)+" ms");
                                break;
                            }
                            else{
                                elapsed1 = Duration.between(start, finish1).toMillis();
                                car1_Xcoord.setText(Float.toString(elapsed1)+" ms");
                            }
                        }
                    case "2":
                        for (int i = 0; i < 700; i++) {
                            nxb2 = xCoord + i * 2;
                            Button2.setBounds(nxb2, 150, 100, 50);
                            //car2_Xcoord.setText(Integer.toString(nxb2));
                            Instant finish2 = Instant.now();
                            try {
                                Thread.sleep((int) (20 * Math.random()));
                            } catch (InterruptedException ex) {
                            }
                            if (nxb2 > 1350) {
                                Finish.setForeground(Color.green);
                                Finish.setText("Машина №1 выиграла");
                                Finish2.setForeground(Color.red);
                                Finish2.setText("Maшина №2 проиграла");
                                Button1.setBackground(Color.green);
                                Button2.setBackground(Color.red);
                                thr.stop();
                                car2_Xcoord.setText(Float.toString(elapsed2)+" ms");
                                break;
                            }
                            else{
                                elapsed2 = Duration.between(start, finish2).toMillis();
                                car2_Xcoord.setText(Float.toString(elapsed2)+" ms");
                            }
                        }
                } //switch
            }
        }
        class StartActionListener implements ActionListener {
            double dice;
           
            @Override
            public void actionPerformed(ActionEvent event) {
                if ("Начать гонку".equals(Start.getText())) {
                        // new MyThread((int)(10*Math.random())).start();
                        Finish.setForeground(Color.black);
                        Finish2.setForeground(Color.black);
                        Finish.setText("Машина №1");
                        Finish2.setText("Машина №2");
                        Button1.setBackground(null);
                        Button2.setBackground(null);
                        Thread thr1 = new Thread(new MyThread((int) (20 * Math.random())), "1");
                        Thread thr2 = new Thread(new MyThread((int) (20 * Math.random())), "2");
                        
                        dice = 10*Math.random();
                        if (dice < 5){
                            thr1.start();
                            thr2.start();
                        }
                        else {
                            thr2.start();
                            thr1.start();
                        }
                }
            }
        }
        Start.addActionListener(new StartActionListener());
    }
    
    public static void main(String[] args) {
        new MainFrame();
    }
}
0
 Аватар для Coffeini
753 / 370 / 133
Регистрация: 01.02.2020
Сообщений: 1,096
Записей в блоге: 1
13.06.2023, 22:40
Python_Val, я бы как-то так сделал:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
import sync.Ticker;
 
import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Objects;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Stream;
 
import static javax.swing.GroupLayout.Alignment.CENTER;
import static javax.swing.GroupLayout.Alignment.LEADING;
import static javax.swing.GroupLayout.DEFAULT_SIZE;
import static javax.swing.LayoutStyle.ComponentPlacement.RELATED;
 
public class Main {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(Main::start);
    }
 
    public static void start() {
        //Action
        final int N = 7, MAX = 10000000;
        final var ticker = Factory.newTicker(60);
 
        final var id = new AtomicLong();
        final var cars = Stream.generate(() -> new Car(MAX, ticker)).limit(N).toArray(Car[]::new);
        final var bars = Stream.generate(() -> Factory.newProgressBar(MAX)).limit(cars.length).toArray(JProgressBar[]::new);
        final var tp = Executors.newFixedThreadPool(cars.length);
        final var buttons = Stream.generate(() -> Factory.newButton("GAS")).limit(cars.length).toArray(JButton[]::new);
        final var labels = Stream.generate(() -> Factory.newLabel("0 ms")).limit(cars.length).toArray(JLabel[]::new);
        final var timeStart = new AtomicLong();
        final var barrier = new CyclicBarrier(cars.length + 1);
        for (int i = 0; i < cars.length; ++i) {
            final var car = cars[i];
            final var bar = bars[i];
            final var label = labels[i];
            car.setAfterUpdate(c -> SwingUtilities.invokeLater(() -> {
                bar.setString(String.valueOf(c));
                bar.setValue(c);
                label.setText(String.format("%d ms", (System.nanoTime() - timeStart.get()) / 1000000));
            }));
            buttons[i].addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    car.addAcceleration(MAX / 100.);
                }
 
                @Override
                public void mouseReleased(MouseEvent e) {
                    car.addAcceleration(-MAX / 100.);
                }
            });
        }
        final var start = Factory.newButton("Start");
        start.addActionListener(e -> {
            if (id.get() == 0) {
                for (int i = 0; i < cars.length; ++i) {
                    final var car = cars[i];
                    final var bar = bars[i];
                    final var label = labels[i];
                    tp.execute(() -> {
                        car.reset();
                        car.addAcceleration(MAX / 50.);//.addAcceleration(ThreadLocalRandom.current().nextDouble(MAX / 100., MAX / 50.));
                        ticker.reserve(0);
                        try {
                            barrier.await();
                        } catch (InterruptedException | BrokenBarrierException ex) {
                            Thread.currentThread().interrupt();
                            return;
                        }
                        car.run();
                        final var n = id.incrementAndGet();
                        final var time = System.nanoTime();
                        SwingUtilities.invokeLater(() -> {
                            bar.setString(String.valueOf(n));
                            label.setText(String.format("%d ms", (time - timeStart.get()) / 1000000));
                        });
                        id.compareAndSet(cars.length, 0);
                    });
                }
                try {
                    barrier.await();
                } catch (InterruptedException | BrokenBarrierException ex) {
                    Thread.currentThread().interrupt();
                    return;
                }
                timeStart.set(System.nanoTime());
            }
        });
 
        //Model
        final var frame = Factory.newMainFrame();
        final var layout = new GroupLayout(frame.getContentPane());
        frame.setLayout(layout);
        final var groupBarVertical = layout.createSequentialGroup().addGap(10);
        final var groupBarHorizontal = layout.createParallelGroup(LEADING);
        for (int i = 0; i < cars.length; ++i) {
            groupBarVertical.addPreferredGap(RELATED).addGroup(layout.createParallelGroup(LEADING)
                    .addComponent(buttons[i], DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(bars[i], DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(labels[i], DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE));
 
            groupBarHorizontal.addGroup(layout.createSequentialGroup().addGap(10).addComponent(buttons[i])
                    .addPreferredGap(RELATED).addComponent(bars[i]).addPreferredGap(RELATED)
                    .addComponent(labels[i]).addGap(10));
        }
        groupBarVertical.addPreferredGap(RELATED).addComponent(start).addGap(10);
        layout.setVerticalGroup(layout.createSequentialGroup().addGroup(groupBarVertical));
        layout.setHorizontalGroup(layout.createParallelGroup(CENTER).addGroup(groupBarHorizontal).addComponent(start));
        frame.setVisible(true);
    }
}
 
class Factory {
    public static JFrame newMainFrame() {
        var frame = new JFrame("Test");
        frame.setBounds(0, 0, 800, 600);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        return frame;
    }
 
    public static Ticker newTicker(int fps) {
        Ticker ticker = new Ticker();
        var tp = Executors.newScheduledThreadPool(1, n -> {
            var t = new Thread(n);
            t.setDaemon(true);
            return t;
        });
        tp.scheduleWithFixedDelay(() -> {
            try {
                ticker.tick();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }, 0, TimeUnit.SECONDS.toNanos(1) / fps, TimeUnit.NANOSECONDS);
        return ticker;
    }
 
    public static JProgressBar newProgressBar(int max) {
        final var p = new JProgressBar(0, max);
        p.setString("");
        p.setStringPainted(true);
        return p;
    }
 
    public static JButton newButton(String text) {
        return new JButton(text);
    }
 
    public static JPanel newPanel() {
        return new JPanel();
    }
 
    public static JLabel newLabel(String text) {
        return new JLabel(text);
    }
}
 
class Car implements Runnable {
    private final Ticker ticker;
    private final double endPosition;
    private final AtomicLong acceleration;
    private double speed, position;
    private long lastUpdate;
    private final AtomicReference<Action> afterUpdate;
    private static final long NANO_SECOND = TimeUnit.SECONDS.toNanos(1);
    private static final Action NULL_ACTION = position -> {
    };
 
    @FunctionalInterface
    public interface Action {
        void action(int position);
    }
 
    public Car(double finishPosition, Ticker ticker) {
        this.endPosition = finishPosition;
        this.ticker = ticker;
        this.afterUpdate = new AtomicReference<>(NULL_ACTION);
        acceleration = new AtomicLong();
    }
 
    /**
     * Not thread-safety
     */
    public void reset() {
        acceleration.set(0);
        position = 0;
        speed = 0;
    }
 
    public void addAcceleration(double acceleration) {
        long val;
        double newVal;
        do {
            val = this.acceleration.get();
            newVal = Double.longBitsToDouble(val) + acceleration;
        } while (!this.acceleration.compareAndSet(val, Double.doubleToLongBits(newVal)));
    }
 
    @Override
    public void run() {
        try {
            while (position < endPosition) {
                try {
                    ticker.reserveAndAwait(1);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                if (lastUpdate != 0) {
                    final var thisTime = System.nanoTime() - lastUpdate;
                    speed += getAcceleration() * thisTime / NANO_SECOND;
                    position += speed * thisTime / NANO_SECOND;
                    position = Math.min(endPosition, position);
                }
                afterUpdate.get().action((int) position);
                lastUpdate = System.nanoTime();
            }
        } finally {
            ticker.relax();
            lastUpdate = 0;
        }
    }
 
    public void setAfterUpdate(Action afterUpdate) {
        this.afterUpdate.set(Objects.requireNonNullElse(afterUpdate, NULL_ACTION));
    }
 
 
    public double getAcceleration() {
        return Double.longBitsToDouble(this.acceleration.get());
    }
}
Тут во первых нет обновлений ui вне EDT. Плюс движение плавное. И еще ускоренное. Также финиш нормальный. Еще барьеры на старте, чтобы точно одновременно стартовали. И еще куча мелочей. Тикер отсюда. В общем-то можно и без него: барьером глобальным или подобие GIL сделать, но в последнем случае треды не нужны.
1
wound up as Aussie
325 / 106 / 19
Регистрация: 15.05.2019
Сообщений: 434
14.06.2023, 04:22
Coffeini, я написал из того набора, что предложил ТС (два потока, одна кнопка), а потом просто дописал, как вариант.
А у Вас это нечто совершенно новое, намного интереснее и другое (мышки, демоны, frame per second (похоже), синхронизатор и т.п.). Кстати, по той ссылке вот эти Ship1,2,3 очень сильно напоминают примеры из книги "Java для профессионалов" (2003 год, вроде, но автора не помню, толстенная такая помню я с дуру с неё и начинал. ).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
14.06.2023, 04:22
Помогаю со студенческими работами здесь

Изменение координат кнопки при наведении курсора
всем привет как сделать что бы когда курсор мишки на него поставишь кнопка бутон от него сдвинулся помигите пожалуйста

Изменение координат кнопки при нажатии на нее
Есть кнопка, которая находиться в верху окна. Нажав на нее, она должна опуститься ниже на определенное число пунктов. Как это реализовать?

Изменение координат метки по удержанию левой кнопки мыши
На графике нужно двигать метку, только после удержания левой клавиши мыши. Как только отпускаем левую клавишу мыши, метка должна остаться в...

Произвольное изменение координат мышки при нажатии кнопки
как сделать так чтобы при нажатии кн0пки координаты мышки изменялись произвольным образом

Изменение данных главного потока через вторичные потоки
Доброго всем времени суток. Столкнулся с одной проблемой есть строка str , которая разбивается Split'ом, на массив стро slovoк, и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru