]> gitweb.fperrin.net Git - GpsPrune.git/blob - src/tim/prune/function/settings/SetDisplaySettings.java
Version 20.1, December 2020
[GpsPrune.git] / src / tim / prune / function / settings / SetDisplaySettings.java
1 package tim.prune.function.settings;
2
3 import java.awt.BorderLayout;
4 import java.awt.Component;
5 import java.awt.FlowLayout;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8
9 import javax.swing.BorderFactory;
10 import javax.swing.Box;
11 import javax.swing.BoxLayout;
12 import javax.swing.ButtonGroup;
13 import javax.swing.ImageIcon;
14 import javax.swing.JButton;
15 import javax.swing.JCheckBox;
16 import javax.swing.JComboBox;
17 import javax.swing.JDialog;
18 import javax.swing.JLabel;
19 import javax.swing.JList;
20 import javax.swing.JPanel;
21 import javax.swing.JRadioButton;
22 import javax.swing.ListCellRenderer;
23 import javax.swing.border.EtchedBorder;
24
25 import tim.prune.App;
26 import tim.prune.DataSubscriber;
27 import tim.prune.GenericFunction;
28 import tim.prune.I18nManager;
29 import tim.prune.UpdateMessageBroker;
30 import tim.prune.config.Config;
31 import tim.prune.gui.GuiGridLayout;
32 import tim.prune.gui.WholeNumberField;
33 import tim.prune.gui.map.WpIconLibrary;
34
35 /**
36  * Class to show the dialog for setting the display settings
37  * like line width, antialiasing, waypoint icons
38  */
39 public class SetDisplaySettings extends GenericFunction
40 {
41         /**
42          * Inner class to render waypoint icons
43          */
44         class IconComboRenderer extends JLabel implements ListCellRenderer<Integer>
45         {
46                 /** Cached icons for each waypoint type */
47                 private ImageIcon[] _icons = new ImageIcon[WpIconLibrary.WAYPT_NUMBER_OF_ICONS];
48
49                 /** Constructor */
50                 IconComboRenderer()
51                 {
52                         setOpaque(true);
53                 }
54
55                 /** Get the label text at the given index */
56                 private String getLabel(int inIndex)
57                 {
58                         return I18nManager.getText("dialog.displaysettings.wpicon." + WpIconLibrary.getIconName(inIndex));
59                 }
60
61                 /** Get the image icon at the given index */
62                 private ImageIcon getIcon(int inIndex)
63                 {
64                         if (_icons[inIndex] == null)
65                         {
66                                 _icons[inIndex] = WpIconLibrary.getIconDefinition(inIndex, 1).getImageIcon();
67                         }
68                         return _icons[inIndex];
69                 }
70
71                 /** @return a label to display the combo box entry */
72                 public Component getListCellRendererComponent(
73                         JList<? extends Integer> inList, Integer inValue, int inIndex,
74                         boolean inSelected, boolean inFocus)
75                 {
76                         if (inSelected) {
77                                 setBackground(inList.getSelectionBackground());
78                                 setForeground(inList.getSelectionForeground());
79                         } else {
80                                 setBackground(inList.getBackground());
81                                 setForeground(inList.getForeground());
82                         }
83                         setIcon(getIcon(inValue));
84                         setText(getLabel(inValue));
85                         return this;
86                 }
87         }
88
89
90         // Members of SetDisplaySettings
91         private JDialog _dialog = null;
92         private WholeNumberField _lineWidthField = null;
93         private JCheckBox _antialiasCheckbox = null;
94         private JComboBox<Integer> _wpIconCombobox = null;
95         private JRadioButton[] _sizeRadioButtons = null;
96         private JRadioButton[] _windowStyleRadios = null;
97         private JButton _okButton = null;
98
99         private static final String STYLEKEY_NIMBUS = "javax.swing.plaf.nimbus.NimbusLookAndFeel";
100         private static final String STYLEKEY_GTK = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
101
102
103         /**
104          * Constructor
105          * @param inApp app object
106          */
107         public SetDisplaySettings(App inApp)
108         {
109                 super(inApp);
110         }
111
112         /**
113          * Return the name key for this function
114          */
115         public String getNameKey()
116         {
117                 return "function.setdisplaysettings";
118         }
119
120         /**
121          * @return the contents of the window as a Component
122          */
123         private Component makeContents()
124         {
125                 JPanel mainPanel = new JPanel();
126                 mainPanel.setLayout(new BorderLayout(0, 5));
127                 JPanel midPanel = new JPanel();
128                 midPanel.setLayout(new BoxLayout(midPanel, BoxLayout.Y_AXIS));
129                 midPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
130
131                 JPanel linesPanel = new JPanel();
132                 linesPanel.setBorder(BorderFactory.createCompoundBorder(
133                         BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), BorderFactory.createEmptyBorder(3, 3, 3, 3))
134                 );
135                 GuiGridLayout grid = new GuiGridLayout(linesPanel);
136
137                 // line width
138                 JLabel lineWidthLabel = new JLabel(I18nManager.getText("dialog.displaysettings.linewidth"));
139                 grid.add(lineWidthLabel);
140                 _lineWidthField = new WholeNumberField(1);
141                 grid.add(_lineWidthField);
142                 // Antialiasing
143                 _antialiasCheckbox = new JCheckBox(I18nManager.getText("dialog.displaysettings.antialias"), false);
144                 grid.add(_antialiasCheckbox);
145                 grid.add(new JLabel(""));
146
147                 linesPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
148                 midPanel.add(linesPanel);
149                 midPanel.add(Box.createVerticalStrut(10));
150
151                 // Panel for waypoint icons
152                 JPanel waypointsPanel = new JPanel();
153                 waypointsPanel.setBorder(BorderFactory.createCompoundBorder(
154                         BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), BorderFactory.createEmptyBorder(3, 3, 3, 3))
155                 );
156                 waypointsPanel.setLayout(new BoxLayout(waypointsPanel, BoxLayout.Y_AXIS));
157                 // Select which waypoint icon to use
158                 JPanel iconPanel = new JPanel();
159                 GuiGridLayout iconGrid = new GuiGridLayout(iconPanel);
160                 JLabel headerLabel = new JLabel(I18nManager.getText("dialog.displaysettings.waypointicons"));
161                 headerLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
162                 iconGrid.add(headerLabel);
163                 _wpIconCombobox = new JComboBox<Integer>(new Integer[] {0, 1, 2, 3, 4});
164                 _wpIconCombobox.setRenderer(new IconComboRenderer());
165                 iconGrid.add(_wpIconCombobox);
166                 waypointsPanel.add(iconPanel);
167                 // Select size of waypoints
168                 JPanel sizePanel = new JPanel();
169                 sizePanel.setLayout(new FlowLayout(FlowLayout.CENTER));
170                 _sizeRadioButtons = new JRadioButton[3];
171                 ButtonGroup sizeRadioGroup = new ButtonGroup();
172                 final String[] sizeKeys = {"small", "medium", "large"};
173                 for (int i=0; i<3; i++)
174                 {
175                         _sizeRadioButtons[i] = new JRadioButton(I18nManager.getText("dialog.displaysettings.size." + sizeKeys[i]));
176                         sizeRadioGroup.add(_sizeRadioButtons[i]);
177                         sizePanel.add(_sizeRadioButtons[i]);
178                 }
179                 waypointsPanel.add(sizePanel);
180                 waypointsPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
181                 midPanel.add(waypointsPanel);
182
183                 // Panel for window style
184                 JPanel windowStylePanel = new JPanel();
185                 windowStylePanel.setBorder(BorderFactory.createCompoundBorder(
186                         BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), BorderFactory.createEmptyBorder(3, 3, 3, 3))
187                 );
188                 windowStylePanel.setLayout(new FlowLayout(FlowLayout.CENTER));
189                 windowStylePanel.add(new JLabel(I18nManager.getText("dialog.displaysettings.windowstyle")));
190                 windowStylePanel.add(Box.createHorizontalStrut(10));
191                 ButtonGroup styleGroup = new ButtonGroup();
192                 final String[] styleKeys = {"default", "nimbus", "gtk"};
193                 _windowStyleRadios = new JRadioButton[3];
194                 for (int i=0; i<3; i++)
195                 {
196                         _windowStyleRadios[i] = new JRadioButton(
197                                 I18nManager.getText("dialog.displaysettings.windowstyle." + styleKeys[i]));
198                         styleGroup.add(_windowStyleRadios[i]);
199                         if (i != 2 || platformHasPlaf(STYLEKEY_GTK))
200                         {
201                                 windowStylePanel.add(_windowStyleRadios[i]);
202                         }
203                 }
204                 midPanel.add(windowStylePanel);
205                 mainPanel.add(midPanel, BorderLayout.CENTER);
206
207                 // button panel at bottom
208                 JPanel buttonPanel = new JPanel();
209                 buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
210                 // OK button
211                 _okButton = new JButton(I18nManager.getText("button.ok"));
212                 _okButton.addActionListener(new ActionListener() {
213                         public void actionPerformed(ActionEvent e) {
214                                 finish();
215                         }
216                 });
217                 buttonPanel.add(_okButton);
218                 // Cancel button
219                 JButton cancelButton = new JButton(I18nManager.getText("button.cancel"));
220                 cancelButton.addActionListener(new ActionListener() {
221                         public void actionPerformed(ActionEvent e) {
222                                 _dialog.dispose();
223                         }
224                 });
225                 buttonPanel.add(cancelButton);
226                 mainPanel.add(buttonPanel, BorderLayout.SOUTH);
227                 return mainPanel;
228         }
229
230         /**
231          * @return true if the specified style name is available on this platform
232          */
233         private static boolean platformHasPlaf(String styleName)
234         {
235                 for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
236                 {
237                         if (info.getClassName().equals(styleName)) {
238                                 return true;
239                         }
240                 }
241                 return false;
242         }
243
244         /**
245          * Show window
246          */
247         public void begin()
248         {
249                 if (_dialog == null)
250                 {
251                         _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()));
252                         _dialog.setLocationRelativeTo(_parentFrame);
253                         _dialog.getContentPane().add(makeContents());
254                         _dialog.pack();
255                 }
256                 // Set values from config
257                 int lineWidth = Config.getConfigInt(Config.KEY_LINE_WIDTH);
258                 if (lineWidth < 1 || lineWidth > 4) {lineWidth = 2;}
259                 _lineWidthField.setValue(lineWidth);
260                 _antialiasCheckbox.setSelected(Config.getConfigBoolean(Config.KEY_ANTIALIAS));
261                 _wpIconCombobox.setSelectedIndex(Config.getConfigInt(Config.KEY_WAYPOINT_ICONS));
262                 selectIconSizeRadio(Config.getConfigInt(Config.KEY_WAYPOINT_ICON_SIZE));
263                 selectWindowStyleRadio(Config.getConfigString(Config.KEY_WINDOW_STYLE));
264                 _dialog.setVisible(true);
265         }
266
267         /**
268          * Select the corresponding radio button according to the numeric value
269          * @param inValue numeric value saved in Config
270          */
271         private void selectIconSizeRadio(int inValue)
272         {
273                 if (inValue < 0 || inValue >= _sizeRadioButtons.length)
274                 {
275                         inValue = 1;
276                 }
277                 if (_sizeRadioButtons[inValue] != null)
278                 {
279                         _sizeRadioButtons[inValue].setSelected(true);
280                 }
281         }
282
283         /**
284          * Select the corresponding radio button according to the selected style
285          * @param inValue style string saved in Config
286          */
287         private void selectWindowStyleRadio(String inValue)
288         {
289                 int selectedRadio = 0;
290                 if (inValue != null && inValue.equals(STYLEKEY_NIMBUS))
291                 {
292                         selectedRadio = 1;
293                 }
294                 else if (inValue != null && inValue.equals(STYLEKEY_GTK) && _windowStyleRadios[2] != null)
295                 {
296                         selectedRadio = 2;
297                 }
298                 _windowStyleRadios[selectedRadio].setSelected(true);
299         }
300
301         /**
302          * @return numeric value of selected icon size according to radio buttons
303          */
304         private int getSelectedIconSize()
305         {
306                 for (int i=0; i<_sizeRadioButtons.length; i++)
307                 {
308                         if (_sizeRadioButtons[i] != null && _sizeRadioButtons[i].isSelected())
309                         {
310                                 return i;
311                         }
312                 }
313                 return 1; // default is medium
314         }
315
316         /**
317          * @return the style string according to the selected radio button
318          */
319         private String getSelectedStyleString()
320         {
321                 if (_windowStyleRadios[1].isSelected()) {
322                         return STYLEKEY_NIMBUS;
323                 }
324                 if (_windowStyleRadios[2] != null && _windowStyleRadios[2].isSelected()) {
325                         return STYLEKEY_GTK;
326                 }
327                 return null;
328         }
329
330         /**
331          * Save settings and close
332          */
333         public void finish()
334         {
335                 // update config
336                 int lineWidth = _lineWidthField.getValue();
337                 if (lineWidth < 1 || lineWidth > 4) {lineWidth = 2;}
338                 Config.setConfigInt(Config.KEY_LINE_WIDTH, lineWidth);
339                 Config.setConfigBoolean(Config.KEY_ANTIALIAS, _antialiasCheckbox.isSelected());
340                 Config.setConfigInt(Config.KEY_WAYPOINT_ICONS, _wpIconCombobox.getSelectedIndex());
341                 Config.setConfigInt(Config.KEY_WAYPOINT_ICON_SIZE, getSelectedIconSize());
342                 Config.setConfigString(Config.KEY_WINDOW_STYLE, getSelectedStyleString());
343                 // refresh display
344                 UpdateMessageBroker.informSubscribers(DataSubscriber.MAPSERVER_CHANGED);
345                 _dialog.dispose();
346         }
347 }