1 | // Jomic - a viewer for comic book archives. |
2 | // Copyright (C) 2004-2011 Thomas Aglassinger |
3 | // |
4 | // This program is free software: you can redistribute it and/or modify |
5 | // it under the terms of the GNU General Public License as published by |
6 | // the Free Software Foundation, either version 3 of the License, or |
7 | // (at your option) any later version. |
8 | // |
9 | // This program is distributed in the hope that it will be useful, |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | // GNU General Public License for more details. |
13 | // |
14 | // You should have received a copy of the GNU General Public License |
15 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | package net.sf.jomic.ui; |
17 | |
18 | import java.awt.event.ActionEvent; |
19 | import java.awt.event.ActionListener; |
20 | import java.awt.event.ItemEvent; |
21 | import java.awt.event.ItemListener; |
22 | import java.beans.PropertyChangeEvent; |
23 | import java.beans.PropertyChangeListener; |
24 | |
25 | import javax.swing.Action; |
26 | import javax.swing.JCheckBoxMenuItem; |
27 | |
28 | import net.sf.jomic.common.JomicTools; |
29 | import net.sf.jomic.common.Settings; |
30 | |
31 | import org.apache.commons.logging.Log; |
32 | import org.apache.commons.logging.LogFactory; |
33 | |
34 | /** |
35 | * JCheckBoxMenuItem to change a setting of type <code>boolean</code>, and keep in sync with it. It |
36 | * attaches a PropertyChangeListener that updates the item state according to the current value of |
37 | * the property. Likewise, if the menu item is selected, it sends an ActionEvent with a specified |
38 | * command to a specified ActionListener indicating that the property needs to be updated. It does |
39 | * not however update the property itself - this has to be done by (the centralized) delegate |
40 | * ActionListener. |
41 | * |
42 | * @see net.sf.jomic.common.Settings |
43 | * @author Thomas Aglassinger |
44 | */ |
45 | public class BooleanSettingMenuItem extends JCheckBoxMenuItem implements ItemListener, PropertyChangeListener |
46 | { |
47 | private String command; |
48 | private ActionListener delegate; |
49 | private JomicTools jomicTools; |
50 | private Log logger; |
51 | private String propertyName; |
52 | private Settings settings; |
53 | |
54 | /** |
55 | * @param newLabel Description of the parameter |
56 | * @param newPropertyName Description of the parameter |
57 | */ |
58 | public BooleanSettingMenuItem(String newLabel, String newPropertyName) { |
59 | this(); |
60 | assert newLabel != null; |
61 | assert newPropertyName != null; |
62 | propertyName = newPropertyName; |
63 | |
64 | Action toggleAction = new ToggleBooleanSettingAction(newLabel, propertyName); |
65 | |
66 | setAction(toggleAction); |
67 | |
68 | boolean defaultState = settings.getBooleanProperty(propertyName); |
69 | |
70 | setState(defaultState); |
71 | setActionCommand(command); |
72 | settings.addPropertyChangeListener(propertyName, this); |
73 | } |
74 | |
75 | /** |
76 | * Create a new BooleanSettingMenuItem. |
77 | * |
78 | * @param newLabel the label to use for the menu item (already localized) |
79 | * @param newPropertyName the name of the propery in Settings the menu item should synchronize |
80 | * with |
81 | * @param newCommand the action command the menu item should send to toggle the state of |
82 | * the property |
83 | * @param newDelegate the target ActionListener where to send newCommand to |
84 | */ |
85 | public BooleanSettingMenuItem( |
86 | String newLabel, String newPropertyName, String newCommand, ActionListener newDelegate) { |
87 | this(); |
88 | assert newLabel != null; |
89 | assert newPropertyName != null; |
90 | assert newCommand != null; |
91 | assert newDelegate != null; |
92 | |
93 | setText(newLabel); |
94 | propertyName = newPropertyName; |
95 | command = newCommand; |
96 | delegate = newDelegate; |
97 | |
98 | boolean defaultState = settings.getBooleanProperty(propertyName); |
99 | |
100 | setState(defaultState); |
101 | setActionCommand(command); |
102 | settings.addPropertyChangeListener(propertyName, this); |
103 | addItemListener(this); |
104 | } |
105 | |
106 | private BooleanSettingMenuItem() { |
107 | super(); |
108 | jomicTools = JomicTools.instance(); |
109 | settings = Settings.instance(); |
110 | logger = LogFactory.getLog(BooleanSettingMenuItem.class); |
111 | } |
112 | |
113 | public void dispose() { |
114 | removeItemListener(this); |
115 | settings.removePropertyChangeListener(propertyName, this); |
116 | } |
117 | |
118 | public void itemStateChanged(ItemEvent event) { |
119 | try { |
120 | assert event != null; |
121 | assert event.getSource() == this; |
122 | boolean menuItemSelected = event.getStateChange() == ItemEvent.SELECTED; |
123 | boolean currentValue = settings.getBooleanProperty(propertyName); |
124 | |
125 | if (menuItemSelected != currentValue) { |
126 | ActionEvent actionEvent = new ActionEvent(this, 0, command); |
127 | |
128 | delegate.actionPerformed(actionEvent); |
129 | } |
130 | } catch (Throwable error) { |
131 | jomicTools.showError(null, "errors.cannotToggleProperty", new String[]{propertyName, command}, error); |
132 | } |
133 | } |
134 | |
135 | public void propertyChange(PropertyChangeEvent event) { |
136 | try { |
137 | assert event != null; |
138 | assert event.getSource() == settings; |
139 | boolean currentState = getState(); |
140 | boolean newState = Boolean.valueOf((String) event.getNewValue()).booleanValue(); |
141 | |
142 | if (logger.isInfoEnabled()) { |
143 | logger.info("property " + propertyName + " changed from " + currentState + " to " + newState); |
144 | } |
145 | if (currentState != newState) { |
146 | setState(newState); |
147 | } |
148 | } catch (Throwable error) { |
149 | jomicTools.showError(event, error); |
150 | } |
151 | } |
152 | } |