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
package my3d;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.layout.GridPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.Window;
public class _slider_dialog extends Stage {
public static class _slider extends Slider {
private static final double TICK_COUNT = 20;
private double min, max;
private double prev_t;
public _slider(double min, double max, double val,
Orientation ori, _slider_listener lis) {
super(0, 1, (val - min) / (max - min));
this.min = min;
this.max = max;
valueProperty().addListener((ov, prev, curr) -> {
double t = curr.doubleValue();
if (b_tick_response) {
prev_t = tick_value(prev_t);
t = tick_value(t);
}
if (t == prev_t)
return;
lis.value_changed((1 - t) * min + t * max);
prev_t = t;
});
setShowTickMarks(true);
setMajorTickUnit(5 / TICK_COUNT);
setMinorTickCount(4);
setSnapToTicks(true);
setOrientation(ori);
}
public void init_value(double val) {
prev_t = (val - min) / (max - min);
setValue(prev_t);
}
public static interface _slider_listener {
public void value_changed(double value);
}
private static boolean b_tick_response;
public static void set_tick_response(boolean b) { b_tick_response = b; }
private double tick_value(double t) {
return ((int)(t * TICK_COUNT + 0.5)) / TICK_COUNT;
}
}
private double[] values;
private _slider[] sliders;
public _slider_dialog(Window owner, String title, _dialog_listener lis,
_slider_data... sd_list) {
super(StageStyle.UTILITY);
GridPane grid_pane = new GridPane();
grid_pane.setAlignment(Pos.CENTER);
grid_pane.setHgap(20);
grid_pane.setVgap(20);
setTitle(title);
initOwner(owner);
initModality(Modality.NONE);
int n = sd_list.length;
values = new double[n];
sliders = new _slider[n];
_slider slider;
_slider_data sd;
for (int i = 0; i < n; i++) {
sd = sd_list[i];
slider = new _slider(sd.min, sd.max, sd.val,
Orientation.HORIZONTAL,
(val) -> {
for (int j = 0; j < sliders.length; j++) {
if (sliders[j].isFocused())
values[j] = val;
}
lis.value_changed(values);
});
values[i] = sd.val;
grid_pane.add(new Label(sd.name), 0, i);
grid_pane.add(slider, 1, i);
sliders[i] = slider;
}
setScene(new Scene(grid_pane, 350, n * 50));
setResizable(false);
}
public void init_values(double... values) {
for (int i = 0; i < sliders.length; i++) {
this.values[i] = values[i];
sliders[i].init_value(values[i]);
}
}
public void init_value_at(int index, double value) {
this.values[index] = values[index];
sliders[index].init_value(value);
}
public static class _slider_data {
public String name;
public double min, max, val;
public _slider_data(String name, double min, double max, double val) {
this.name = name;
this.min = min; this.max = max; this.val = val;
}
}
public static interface _dialog_listener {
public void value_changed(double[] values);
}
}