001: package org.jvnet.substance.netbeans.ui;
002:
003: import java.awt.event.ActionEvent;
004: import java.beans.PropertyChangeListener;
005: import java.util.Iterator;
006: import java.util.LinkedList;
007: import java.util.Map;
008: import javax.swing.AbstractAction;
009: import javax.swing.Action;
010: import javax.swing.JFileChooser;
011: import javax.swing.JMenu;
012: import javax.swing.JMenuItem;
013: import javax.swing.LookAndFeel;
014: import javax.swing.UIManager;
015: import org.jvnet.substance.SubstanceLookAndFeel;
016: import org.jvnet.substance.watermark.SubstanceImageWatermark;
017: import org.jvnet.substance.watermark.SubstanceWatermark;
018: import org.jvnet.substance.watermark.WatermarkInfo;
019: import org.openide.util.NbBundle;
020: import org.openide.util.WeakListeners;
021: import org.openide.util.WeakSet;
022: import org.openide.util.actions.Presenter;
023:
024: /**
025: * Adds a submenu to the View menu to let the user select watermarks.
026: *
027: * @author Timothy Boudreau
028: */
029: public class WatermarkSelector extends AbstractAction implements
030: Presenter.Menu, Presenter.Popup {
031:
032: private static final int HISTORY_SIZE = 5;
033:
034: private static LinkedList<String> history = new LinkedList<String>();
035:
036: private static JMenu imageMenu;
037:
038: public void actionPerformed(ActionEvent e) {
039: throw new UnsupportedOperationException();
040: }
041:
042: public JMenuItem getPopupPresenter() {
043: return getMenuPresenter();
044: }
045:
046: private static void updateImageMenu(JMenu menu) {
047: if (menu != null)
048: imageMenu = menu;
049: else
050: menu = imageMenu;
051:
052: menu.removeAll();
053:
054: for (String location : history) {
055: JMenuItem item = new JMenuItem(new SetImageWatermarkAction(
056: location));
057: menu.add(item);
058: }
059: if (history.size() > 0)
060: menu.addSeparator();
061:
062: menu.add(new JMenuItem(new ChooseImageWatermarkAction()));
063: }
064:
065: public JMenuItem getMenuPresenter() {
066: LookAndFeel lf = UIManager.getLookAndFeel();
067: JMenu result = new JMenu(NbBundle.getMessage(getClass(),
068: "LBL_Watermarks")); //NOI18N
069:
070: if (lf instanceof SubstanceLookAndFeel) {
071: SubstanceLookAndFeel slf = (SubstanceLookAndFeel) lf;
072: Map<String, WatermarkInfo> watermarks = slf
073: .getAllWatermarks();
074: for (WatermarkInfo watermarkInfo : watermarks.values()) {
075: JMenuItem item = new JMenuItem(
076: new ChangeWatermarkAction(watermarkInfo
077: .getDisplayName(), watermarkInfo
078: .getClassName()));
079:
080: result.add(item);
081: }
082: result.addSeparator();
083: // special item for image-based watermark
084: JMenu imageMenu = new JMenu(
085: new ChangeImageWatermarkAction());
086: result.add(imageMenu);
087: updateImageMenu(imageMenu);
088: } else {
089: result.setText(NbBundle.getMessage(getClass(),
090: "LBL_NotRunning")); //NOI18N
091: result.setEnabled(false);
092: }
093: return result;
094: }
095:
096: private static final WeakSet allActions = new WeakSet();
097:
098: private static void updateActions() {
099: for (Iterator i = allActions.iterator(); i.hasNext();) {
100: BasicWatermarkAction a = (BasicWatermarkAction) i.next();
101: if (a != null) {
102: a.update();
103: }
104: }
105: }
106:
107: private abstract static class BasicWatermarkAction extends
108: AbstractAction {
109: public abstract void update();
110: }
111:
112: private static class ChangeWatermarkAction extends
113: BasicWatermarkAction {
114: protected final String watermarkDisplayName;
115: protected final String watermarkClassName;
116:
117: public ChangeWatermarkAction(String watermarkDisplayName,
118: String watermarkClassName) {
119: this .watermarkDisplayName = watermarkDisplayName;
120: this .watermarkClassName = watermarkClassName;
121: update();
122: allActions.add(this );
123: }
124:
125: public void update() {
126: String nm = watermarkDisplayName;
127: if (nm.equals(SubstanceLookAndFeel
128: .getCurrentWatermarkName())) {
129: nm = "<html><b>" + nm + "</b></html>"; //NOI18N
130: }
131: putValue(Action.NAME, nm);
132: }
133:
134: public void addPropertyChangeListener(PropertyChangeListener pcl) {
135: //ensure old menu items can be garbage collected
136: super .addPropertyChangeListener(WeakListeners
137: .propertyChange(pcl, this ));
138: }
139:
140: public void actionPerformed(ActionEvent e) {
141: setWatermark(this .watermarkClassName);
142: ButtonShapeSelector.updateUIs();
143: persist(this .watermarkClassName);
144: updateActions();
145: }
146: }
147:
148: private static final class ChangeImageWatermarkAction extends
149: BasicWatermarkAction {
150: public ChangeImageWatermarkAction() {
151: update();
152: allActions.add(this );
153: }
154:
155: public void update() {
156: String nm = SubstanceImageWatermark.getName();
157: if (nm.equals(SubstanceLookAndFeel
158: .getCurrentWatermarkName())) {
159: nm = "<html><b>" + nm + "</b></html>"; //NOI18N
160: }
161: putValue(Action.NAME, nm);
162: }
163:
164: public void addPropertyChangeListener(PropertyChangeListener pcl) {
165: //ensure old menu items can be garbage collected
166: super .addPropertyChangeListener(WeakListeners
167: .propertyChange(pcl, this ));
168: }
169:
170: public void actionPerformed(ActionEvent e) {
171: }
172: }
173:
174: private static final class ChooseImageWatermarkAction extends
175: BasicWatermarkAction {
176: public ChooseImageWatermarkAction() {
177: update();
178: allActions.add(this );
179: }
180:
181: public void update() {
182: putValue(Action.NAME, "Select from local disk");
183: }
184:
185: public void addPropertyChangeListener(PropertyChangeListener pcl) {
186: //ensure old menu items can be garbage collected
187: super .addPropertyChangeListener(WeakListeners
188: .propertyChange(pcl, this ));
189: }
190:
191: public void actionPerformed(ActionEvent e) {
192: String imageLocation;
193: JFileChooser jfc = new JFileChooser();
194: if (jfc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
195: imageLocation = jfc.getSelectedFile().getAbsolutePath();
196: setImageWatermark(imageLocation);
197: ButtonShapeSelector.updateUIs();
198:
199: if (history.contains(imageLocation)) {
200: history.remove(imageLocation);
201: } else {
202: if (history.size() >= HISTORY_SIZE)
203: history.removeLast();
204: }
205: history.addFirst(imageLocation);
206:
207: persist(SubstanceImageWatermark.class.getName());
208: persistImageHistory(history);
209: updateActions();
210: }
211: }
212: }
213:
214: private static final class SetImageWatermarkAction extends
215: BasicWatermarkAction {
216: private String imageLocation;
217:
218: public SetImageWatermarkAction(String imageLocation) {
219: this .imageLocation = imageLocation;
220: update();
221: allActions.add(this );
222: }
223:
224: public void update() {
225: String nm = this .imageLocation;
226: SubstanceWatermark watermark = SubstanceLookAndFeel
227: .getCurrentWatermark();
228: if (watermark instanceof SubstanceImageWatermark) {
229: SubstanceImageWatermark imageWatermark = (SubstanceImageWatermark) watermark;
230: if (nm.equals(imageWatermark.getOrigImageLocation())) {
231: nm = "<html><b>" + nm + "</b></html>"; //NOI18N
232: }
233: }
234: putValue(Action.NAME, nm);
235: }
236:
237: public void addPropertyChangeListener(PropertyChangeListener pcl) {
238: //ensure old menu items can be garbage collected
239: super .addPropertyChangeListener(WeakListeners
240: .propertyChange(pcl, this ));
241: }
242:
243: public void actionPerformed(ActionEvent e) {
244: setImageWatermark(imageLocation);
245: ButtonShapeSelector.updateUIs();
246:
247: if (history.contains(imageLocation)) {
248: history.remove(imageLocation);
249: }
250: history.addFirst(imageLocation);
251:
252: persist(SubstanceImageWatermark.class.getName());
253: persistImageHistory(history);
254: updateActions();
255: }
256: }
257:
258: static void setWatermark(String s) {
259: SubstanceLookAndFeel.setCurrentWatermark(s);
260: }
261:
262: static void setImageWatermark(String location) {
263: SubstanceLookAndFeel
264: .setCurrentWatermark(new SubstanceImageWatermark(
265: location));
266: }
267:
268: static void persist(String value) {
269: NbPrefs p = new NbPrefs();
270: p.put("watermarkClassName", value); //NOI18N
271: //p.put("skinClassName", null);
272: }
273:
274: static void persistImageHistory(LinkedList<String> location) {
275: NbPrefs p = new NbPrefs();
276: for (int i = 0; i < location.size(); i++)
277: p.put("watermarkImageLocation" + i, location.get(i)); //NOI18N
278:
279: if (imageMenu != null)
280: updateImageMenu(null);
281: }
282:
283: public static boolean restore(String watermarkClassName,
284: String watermarkImageLocation) {
285: NbPrefs p = new NbPrefs();
286: // First restore the image history (in any case)
287: for (int i = 0; i < HISTORY_SIZE; i++) {
288: String imageLocation = p.get("watermarkImageLocation" + i,
289: null); // NOI18N
290: if (imageLocation == null) {
291: // no more
292: break;
293: } else {
294: history.addLast(imageLocation);
295: }
296: }
297: if (watermarkImageLocation != null) {
298: if (history.contains(watermarkImageLocation))
299: history.remove(watermarkImageLocation);
300: if (history.size() >= HISTORY_SIZE)
301: history.removeLast();
302: history.addFirst(watermarkImageLocation);
303: }
304: // persist history (will save the command-line parameter as the first
305: // image)
306: persistImageHistory(history);
307:
308: if (watermarkClassName == null) {
309: // no overriding value
310: String preferred = p.get("watermarkClassName", null); //NOI18N
311: if (preferred != null) {
312: if (preferred.equals(SubstanceImageWatermark.class
313: .getName())) {
314: if (history.size() > 0)
315: setImageWatermark(history.getFirst());
316: return true;
317: }
318: setWatermark(preferred);
319: }
320: return preferred != null;
321: }
322: return true;
323: }
324: }
|