source: java/main/src/main/java/com/framsticks/gui/controls/SliderControl.java @ 193

Last change on this file since 193 was 193, checked in by Maciej Komosinski, 10 years ago

Set svn:eol-style native for all textual files

  • Property svn:eol-style set to native
File size: 5.5 KB
Line 
1package com.framsticks.gui.controls;
2
3import java.awt.BorderLayout;
4import java.awt.Dimension;
5import java.util.Hashtable;
6
7import javax.swing.Box;
8import javax.swing.BoxLayout;
9import javax.swing.JComponent;
10import javax.swing.JLabel;
11import javax.swing.JPanel;
12import javax.swing.JSlider;
13import javax.swing.JTextField;
14import javax.swing.event.ChangeEvent;
15import javax.swing.event.ChangeListener;
16
17import org.apache.logging.log4j.Logger;
18import org.apache.logging.log4j.LogManager;
19
20import com.framsticks.gui.Gui;
21import com.framsticks.params.types.DecimalParam;
22import com.framsticks.params.types.FloatParam;
23import com.framsticks.params.types.NumberParam;
24import com.framsticks.util.lang.Numbers;
25import com.framsticks.util.swing.Layout;
26
27@SuppressWarnings("serial")
28public class SliderControl extends TextControl {
29
30        private static final Logger log = LogManager.getLogger(SliderControl.class.getName());
31
32        protected final JSlider slider;
33
34        protected final JTextField text;
35
36        /**
37         * Division factor used to implement float value slider.
38         */
39        private final int div = 10;
40        private JComponent changing = null;
41        public final static float LINE_HEIGHT_FACTOR = 1.2f;
42
43        private Class<? extends Number> valueType;
44
45        public SliderControl(NumberParam<?> param) {
46                super(param);
47                text = new JTextField();
48
49                this.setMaximumSize(new Dimension(Integer.MAX_VALUE, (int)(LINE_HEIGHT * LINE_HEIGHT_FACTOR)));
50
51                // ComponentUI ui = UIManager.getUI(slider);
52                // assert ui instanceof SliderUI;
53                // SliderUI sui = (SliderUI) ui;
54                // slider.setUI(sui);
55
56                slider = new JSlider();
57
58                slider.setPaintLabels(false);
59                if (param instanceof DecimalParam) {
60                        valueType = Integer.class;
61
62                        int min = param.getMin(Integer.class);
63                        int max = param.getMax(Integer.class);
64                        slider.setMinimum(min);
65                        slider.setMaximum(max);
66                        if (param.getDef(Integer.class) != null) {
67                                slider.setValue(param.getDef(Integer.class));
68                        } else {
69                                slider.setValue(min);
70                        }
71                        slider.setMajorTickSpacing((int) ((max - min) / 5));
72                        slider.setMinorTickSpacing((int) ((max - min) / 10));
73                } else if (param instanceof FloatParam) {
74                        valueType = Double.class;
75
76                        double min = param.getMin(Double.class) * div;
77                        slider.setMinimum((int) min);
78                        double max = param.getMax(Double.class) * div;
79                        double diff = max - min;
80                        slider.setMaximum((int) max);
81
82                        Hashtable<Integer, java.awt.Component> labels = new Hashtable<Integer, java.awt.Component>();
83                        int ticks = 6;
84                        for (int i = 0; i <= ticks; i++) {
85                                double val = (diff / ticks) * i + min;
86                                String label = String.format("%1$.1f", (val / 10)).replace(",",
87                                                ".");
88                                labels.put((int) val, new JLabel(label, JLabel.CENTER));
89                        }
90                        slider.setLabelTable(labels);
91                        slider.setMajorTickSpacing((int) (diff / 5));
92                        slider.setMinorTickSpacing((int) (diff / 10));
93                        if (param.getDef(Double.class) != null) {
94                                double defaultValue = param.getDef(Double.class) * div;
95                                slider.setValue((int) defaultValue);
96                        }
97                }
98                slider.setPaintLabels(true);
99                slider.setPaintTicks(true);
100
101
102
103
104                Layout.fixComponentSize(text, new Dimension(90, Control.LINE_HEIGHT));
105                text.setHorizontalAlignment(JSlider.CENTER);
106
107
108                slider.addChangeListener(new ChangeListener() {
109                        @Override
110                        public void stateChanged(ChangeEvent e) {
111                                if (changing != null) {
112                                        return;
113                                }
114                                log.trace("changing {} with slider: {}", getParam(), slider.getValue());
115                                changing = slider;
116                                text.setText(convertFromSliderDomain(slider.getValue()).toString());
117                                changing = null;
118                        }
119                });
120
121                text.getDocument().addDocumentListener(createDocumentListener(new Runnable() {
122                        @Override
123                        public void run() {
124                                if (changing != null) {
125                                        return;
126                                }
127                                log.trace("changing {} with text: {}", getParam(), text.getText());
128                                changing = text;
129                                Integer i = convertToSliderDomain(convertTextToNumber());
130                                if (i != null) {
131                                        slider.setValue(i);
132                                }
133                                changing = null;
134                                notifyOfChange();
135                        }
136                }));
137
138                JPanel valuePanel = new JPanel();
139                valuePanel.setLayout(new BoxLayout(valuePanel, BoxLayout.LINE_AXIS));
140                valuePanel.add(text);
141                Layout.copyComponentDimensions(valuePanel, text);
142
143
144                JPanel sliderPanel = new JPanel();
145                sliderPanel.setLayout(new BorderLayout());
146                sliderPanel.add(slider, BorderLayout.CENTER);
147                sliderPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
148                sliderPanel.setMinimumSize(new Dimension(0, 60));
149
150
151                this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
152                this.setAlignmentX(Box.CENTER_ALIGNMENT);
153                this.setAlignmentY(Box.CENTER_ALIGNMENT);
154
155                Gui.addLeftToLabel(this, valuePanel, sliderPanel);
156        }
157
158        @Override
159        public NumberParam<?> getParam() {
160                return (NumberParam<?>) param;
161        }
162
163        private Number convertFromSliderDomain(int value) {
164                if (param instanceof DecimalParam) {
165                        return value;
166                }
167                if (param instanceof FloatParam) {
168                        return (double) value / (double) div;
169                }
170                return null;
171        }
172
173        private Integer convertToSliderDomain(Number value) {
174                if (value == null) {
175                        return null;
176                }
177                if (param instanceof DecimalParam) {
178                        return (Integer) value;
179                }
180                if (param instanceof FloatParam) {
181                        return (int) ((Double) value * div);
182                }
183                return null;
184        }
185
186        private Number convertTextToNumber() {
187                return Numbers.cast(text.getText(), valueType);
188        }
189
190        @Override
191        public void pushValueToUserInterfaceImpl(Object value) {
192                if (value == null) {
193                        return;
194                }
195                text.setText(value.toString());
196        }
197
198
199        @Override
200        public Number pullValueFromUserInterface() {
201                return convertTextToNumber();
202        }
203
204        @Override
205        protected void updateEnabled(boolean enabled) {
206                slider.setEnabled(enabled);
207                text.setEnabled(enabled);
208        }
209
210}
Note: See TracBrowser for help on using the repository browser.