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