001: /*
002: * $Id: HighlighterPropertyEditor.java,v 1.1 2006/03/11 01:11:52 rbair Exp $
003: *
004: * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005: * Santa Clara, California 95054, U.S.A. All rights reserved.
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
020: */
021: package org.jdesktop.swingx.editors;
022:
023: import java.awt.BorderLayout;
024: import java.awt.Color;
025: import java.awt.Container;
026: import java.awt.GridBagConstraints;
027: import java.awt.GridBagLayout;
028: import java.awt.Insets;
029: import java.awt.event.ActionEvent;
030: import java.beans.PropertyEditorSupport;
031: import java.beans.XMLDecoder;
032: import java.beans.XMLEncoder;
033: import java.io.ByteArrayInputStream;
034: import java.io.ByteArrayOutputStream;
035: import javax.swing.AbstractAction;
036: import javax.swing.AbstractListModel;
037: import javax.swing.BorderFactory;
038: import javax.swing.ButtonGroup;
039: import javax.swing.ImageIcon;
040: import javax.swing.JButton;
041: import javax.swing.JComboBox;
042: import javax.swing.JComponent;
043: import javax.swing.JDialog;
044: import javax.swing.JLabel;
045: import javax.swing.JRadioButton;
046: import javax.swing.JScrollPane;
047: import javax.swing.JSplitPane;
048: import javax.swing.JTextField;
049: import javax.swing.event.ListDataEvent;
050: import javax.swing.event.ListDataListener;
051: import javax.swing.event.ListSelectionEvent;
052: import javax.swing.event.ListSelectionListener; //import org.jdesktop.jdnc.incubator.rlopes.colorcombo.ColorComboBox;
053: import org.jdesktop.swingx.JXList;
054: import org.jdesktop.swingx.JXPanel;
055: import org.jdesktop.swingx.JXTitledPanel;
056: import org.jdesktop.swingx.decorator.AlternateRowHighlighter;
057: import org.jdesktop.swingx.decorator.Highlighter;
058: import org.jdesktop.swingx.decorator.HighlighterPipeline;
059: import org.jdesktop.swingx.decorator.PatternHighlighter;
060:
061: //import org.jdesktop.swingx.expression.ExpressionHighlighter;
062: //import org.netbeans.modules.form.NamedPropertyEditor;
063: //import org.openide.windows.WindowManager;
064:
065: /**
066: *
067: * @author rbair
068: */
069: public class HighlighterPropertyEditor extends PropertyEditorSupport { //implements NamedPropertyEditor {
070: private HighlighterPipeline pipeline = new HighlighterPipeline();
071: private Editor editor;
072:
073: /** Creates a new instance of HighlighterPropertyEditor */
074: public HighlighterPropertyEditor() {
075: editor = new Editor();
076: editor.highlightersList.setModel(new AbstractListModel() {
077: public Object getElementAt(int index) {
078: return pipeline.getHighlighters()[index];
079: }
080:
081: public int getSize() {
082: return pipeline.getHighlighters().length;
083: }
084: });
085: editor.highlightersList.getModel().addListDataListener(
086: new ListDataListener() {
087: public void contentsChanged(ListDataEvent e) {
088: HighlighterPropertyEditor.this
089: .firePropertyChange();
090: }
091:
092: public void intervalAdded(ListDataEvent e) {
093: HighlighterPropertyEditor.this
094: .firePropertyChange();
095: }
096:
097: public void intervalRemoved(ListDataEvent e) {
098: HighlighterPropertyEditor.this
099: .firePropertyChange();
100: }
101: });
102: }
103:
104: public boolean supportsCustomEditor() {
105: return true;
106: }
107:
108: public String getJavaInitializationString() {
109: StringBuffer buffer = new StringBuffer();
110: ByteArrayOutputStream baos = new ByteArrayOutputStream(300);
111: XMLEncoder e = new XMLEncoder(baos);
112: e.writeObject(pipeline.getHighlighters());
113: e.close();
114: Highlighter[] blar = (Highlighter[]) new XMLDecoder(
115: new ByteArrayInputStream(baos.toString().getBytes()))
116: .readObject();
117: buffer
118: .append("new org.jdesktop.swingx.decorator.HighlighterPipeline(\n");
119: buffer
120: .append("\t(org.jdesktop.swingx.decorator.Highlighter[])new java.beans.XMLDecoder(new java.io.ByteArrayInputStream(\"");
121: buffer.append(escapeString(baos.toString()));
122: buffer.append("\".getBytes())).readObject())");
123: return buffer.toString();
124: }
125:
126: private String escapeString(String s) {
127: return s.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"",
128: "\\\\\"").replaceAll("\n", "");
129: }
130:
131: public String getDisplayName() {
132: return "Highlighter Editor";
133: }
134:
135: public void setAsText(String text) throws IllegalArgumentException {
136: }
137:
138: public void setValue(Object value) {
139: //if the value is a HighlighterPipeline, hold on to this. The
140: //editor is going to need it
141: if (value instanceof HighlighterPipeline) {
142: pipeline = new HighlighterPipeline(
143: ((HighlighterPipeline) value).getHighlighters());
144: } else {
145: pipeline = new HighlighterPipeline();
146: }
147: super .setValue(value);
148: }
149:
150: public Object getValue() {
151: return pipeline;
152: }
153:
154: public String getAsText() {
155: return pipeline.toString();
156: }
157:
158: public java.awt.Component getCustomEditor() {
159: return editor;
160: }
161:
162: private class Editor extends JXPanel {
163: private JXList highlightersList;
164: private AlternateRowDetailPanel alternateRowDetailPanel = new AlternateRowDetailPanel();
165: private ExpressionDetailPanel expressionDetailPanel = new ExpressionDetailPanel();
166: private PatternDetailPanel patternDetailPanel = new PatternDetailPanel();
167:
168: public Editor() {
169: setLayout(new BorderLayout());
170:
171: JSplitPane mainsp = new JSplitPane();
172: mainsp.setBorder(BorderFactory.createEmptyBorder());
173: JXTitledPanel tp = new JXTitledPanel("Highlighters");
174: JXPanel buttonPanel = new JXPanel();
175: buttonPanel.setOpaque(false);
176: JButton btn = new JButton(new AddAction());
177: btn.setOpaque(false);
178: btn.setBorder(BorderFactory.createEmptyBorder());
179: buttonPanel.add(btn);
180: btn = new JButton(new DeleteAction());
181: btn.setOpaque(false);
182: btn.setBorder(BorderFactory.createEmptyBorder());
183: buttonPanel.add(btn);
184: tp.addRightDecoration(buttonPanel);
185: highlightersList = new JXList();
186: JScrollPane sp = new JScrollPane(highlightersList);
187: sp.setBorder(BorderFactory.createEmptyBorder());
188: tp.setContentContainer(sp);
189: mainsp.setLeftComponent(tp);
190: final JXTitledPanel details = new JXTitledPanel(
191: "Highlighter Details");
192: mainsp.setRightComponent(details);
193: add(mainsp);
194:
195: highlightersList
196: .addListSelectionListener(new ListSelectionListener() {
197: public void valueChanged(ListSelectionEvent e) {
198: if (!e.getValueIsAdjusting()) {
199: //get the first selected value...
200: Highlighter h = (Highlighter) highlightersList
201: .getSelectedValue();
202: //load the proper detail panel
203: Container c = details
204: .getContentContainer();
205: HighlighterDetailPanel content = null;
206: if (c instanceof HighlighterDetailPanel) {
207: content = (HighlighterDetailPanel) c;
208: content.save();
209: }
210: if (h instanceof AlternateRowHighlighter) {
211: alternateRowDetailPanel
212: .init((AlternateRowHighlighter) h);
213: content = alternateRowDetailPanel;
214: // } else if (h instanceof ExpressionHighlighter) {
215: // expressionDetailPanel.init((ExpressionHighlighter)h);
216: // content = expressionDetailPanel;
217: } else if (h instanceof PatternHighlighter) {
218: patternDetailPanel
219: .init((PatternHighlighter) h);
220: content = patternDetailPanel;
221: }
222: details
223: .setContentContainer(content == null ? new JXPanel()
224: : content);
225: details.revalidate();
226: details.repaint();
227: }
228: }
229: });
230: }
231:
232: private class DeleteAction extends AbstractAction {
233: public DeleteAction() {
234: super ();
235: super .putValue(AddAction.SMALL_ICON, new ImageIcon(
236: HighlighterPropertyEditor.class
237: .getResource("deleteHighlighter.gif")));
238: }
239:
240: public void actionPerformed(ActionEvent ae) {
241: //get the selected items
242: Object[] values = highlightersList.getSelectedValues();
243: for (int i = 0; i < values.length; i++) {
244: pipeline.removeHighlighter((Highlighter) values[i]);
245: }
246: ListDataListener[] listeners = ((AbstractListModel) highlightersList
247: .getModel()).getListDataListeners();
248: ListDataEvent evt = new ListDataEvent(highlightersList,
249: ListDataEvent.CONTENTS_CHANGED, 0, pipeline
250: .getHighlighters().length - 1);
251: for (int i = 0; i < listeners.length; i++) {
252: listeners[i].contentsChanged(evt);
253: }
254: }
255: }
256:
257: private class AddAction extends AbstractAction {
258: public AddAction() {
259: super ();
260: super .putValue(AddAction.SMALL_ICON, new ImageIcon(
261: HighlighterPropertyEditor.class
262: .getResource("newHighlighter.gif")));
263: }
264:
265: public void actionPerformed(ActionEvent ae) {
266: //show a true popup
267: final JDialog dlg = new JDialog(
268: /*WindowManager.getDefault().getMainWindow()*/(JDialog) null,
269: true);
270: JXPanel cp = new JXPanel(new GridBagLayout());
271: final JRadioButton newRB = new JRadioButton(
272: "New Highlighter");
273: final JRadioButton formRB = new JRadioButton(
274: "From Form");
275: ButtonGroup bg = new ButtonGroup();
276: bg.add(newRB);
277: bg.add(formRB);
278: newRB.setSelected(true);
279: cp.add(newRB, new GridBagConstraints(0, 0, 2, 1, 1.0,
280: 0.0, GridBagConstraints.WEST,
281: GridBagConstraints.HORIZONTAL, new Insets(12,
282: 12, 5, 11), 0, 0));
283: JLabel label = new JLabel("Type: ");
284: final JComboBox typeCB = new JComboBox(new String[] {
285: "Alternate Row", "Expression", "Pattern" });
286: label.setLabelFor(typeCB);
287: cp.add(label, new GridBagConstraints(0, 1, 1, 1, 0.0,
288: 0.0, GridBagConstraints.WEST,
289: GridBagConstraints.NONE,
290: new Insets(0, 24, 7, 3), 0, 0));
291: cp.add(typeCB, new GridBagConstraints(1, 1, 1, 1, 1.0,
292: 0.0, GridBagConstraints.WEST,
293: GridBagConstraints.HORIZONTAL, new Insets(0, 0,
294: 7, 11), 0, 0));
295: label = new JLabel("Name: ");
296: final JTextField nameTF = new JTextField(
297: "<auto-generate>");
298: label.setLabelFor(nameTF);
299: cp.add(label, new GridBagConstraints(0, 2, 1, 1, 0.0,
300: 0.0, GridBagConstraints.WEST,
301: GridBagConstraints.NONE,
302: new Insets(0, 24, 7, 3), 0, 0));
303: cp.add(nameTF, new GridBagConstraints(1, 2, 1, 1, 1.0,
304: 0.0, GridBagConstraints.WEST,
305: GridBagConstraints.HORIZONTAL, new Insets(0, 0,
306: 7, 11), 0, 0));
307: cp.add(formRB, new GridBagConstraints(0, 3, 2, 1, 1.0,
308: 0.0, GridBagConstraints.WEST,
309: GridBagConstraints.HORIZONTAL, new Insets(0,
310: 12, 5, 11), 0, 0));
311: label = new JLabel("Choose Highlighter: ");
312: final JComboBox highlighterCB = new JComboBox(
313: new Object[0]);
314: cp.add(label, new GridBagConstraints(0, 4, 1, 1, 0.0,
315: 0.0, GridBagConstraints.WEST,
316: GridBagConstraints.NONE,
317: new Insets(0, 24, 7, 3), 0, 0));
318: cp.add(highlighterCB, new GridBagConstraints(1, 4, 1,
319: 1, 1.0, 0.0, GridBagConstraints.WEST,
320: GridBagConstraints.HORIZONTAL, new Insets(0, 0,
321: 17, 11), 0, 0));
322: JButton okButton = new JButton(
323: new AbstractAction("OK") {
324: public void actionPerformed(ActionEvent ae) {
325: if (newRB.isSelected()) {
326: String type = (String) typeCB
327: .getSelectedItem();
328: Highlighter h = null;
329: if (type == null
330: || type == "Alternate Row") {
331: h = new AlternateRowHighlighter();
332: // } else if (type == "Expression") {
333: // h = new ExpressionHighlighter();
334: } else if (type == "Pattern") {
335: h = new PatternHighlighter();
336: }
337: //TODO deal with the name
338: pipeline.addHighlighter(h);
339: ListDataListener[] listeners = ((AbstractListModel) highlightersList
340: .getModel())
341: .getListDataListeners();
342: int size = pipeline
343: .getHighlighters().length;
344: ListDataEvent evt = new ListDataEvent(
345: highlightersList,
346: ListDataEvent.CONTENTS_CHANGED,
347: size - 1, size - 1);
348: for (int i = 0; i < listeners.length; i++) {
349: listeners[i]
350: .contentsChanged(evt);
351: }
352: }
353: dlg.setVisible(false);
354: }
355: });
356: JXPanel buttonPanel = new JXPanel(new GridBagLayout());
357: buttonPanel.add(okButton, new GridBagConstraints(0, 0,
358: 1, 1, 0.0, 0.0, GridBagConstraints.SOUTHEAST,
359: GridBagConstraints.NONE,
360: new Insets(0, 0, 0, 0), 0, 0));
361: cp.add(buttonPanel, new GridBagConstraints(0, 5, 2, 1,
362: 1.0, 1.0, GridBagConstraints.CENTER,
363: GridBagConstraints.BOTH, new Insets(0, 12, 11,
364: 11), 0, 0));
365: dlg.setContentPane(cp);
366: dlg.pack();
367: //TODO need to to center...
368: dlg.setVisible(true);
369: }
370: }
371:
372: private JComboBox createColorComboBox() {
373: // try {
374: // return new ColorComboBox();
375: // } catch (Exception e) {
376: return new JComboBox(new Color[] { Color.BLACK, Color.BLUE,
377: Color.CYAN, Color.DARK_GRAY, Color.GRAY,
378: Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA,
379: Color.ORANGE, Color.PINK, Color.RED, Color.WHITE,
380: Color.YELLOW });
381: // }
382: }
383:
384: private class HighlighterDetailPanel extends JXPanel {
385: private int rowCounter = 0;
386: protected JComboBox backgroundCB;
387: protected JComboBox selectedBackgroundCB;
388: protected JComboBox foregroundCB;
389: protected JComboBox selectedForegroundCB;
390: private Highlighter h;
391:
392: public HighlighterDetailPanel() {
393: setLayout(new GridBagLayout());
394: backgroundCB = createColorComboBox();
395: add("Background: ", backgroundCB, false);
396: selectedBackgroundCB = createColorComboBox();
397: add("Selected Background: ", selectedBackgroundCB,
398: false);
399: foregroundCB = createColorComboBox();
400: add("Foreground: ", foregroundCB, false);
401: selectedForegroundCB = createColorComboBox();
402: add("Selected Foreground: ", selectedForegroundCB,
403: false);
404: }
405:
406: protected void add(String labelText, JComponent component,
407: boolean isLast) {
408: JLabel label = new JLabel(labelText);
409: label.setLabelFor(component);
410: Insets insets = rowCounter == 0 ? new Insets(12, 12, 5,
411: 5) : new Insets(0, 12, 5, 5);
412: add(label, new GridBagConstraints(0, rowCounter, 1, 1,
413: 0.0, 0.0, isLast ? GridBagConstraints.NORTHWEST
414: : GridBagConstraints.WEST,
415: GridBagConstraints.NONE, insets, 0, 0));
416: insets = rowCounter == 0 ? new Insets(12, 0, 5, 11)
417: : new Insets(0, 0, isLast ? 11 : 5, 11);
418: add(component, new GridBagConstraints(1, rowCounter, 1,
419: 1, 1.0, isLast ? 1.0 : 0.0,
420: isLast ? GridBagConstraints.NORTHWEST
421: : GridBagConstraints.WEST,
422: GridBagConstraints.HORIZONTAL, insets, 0, 0));
423: rowCounter++;
424: }
425:
426: protected void init(Highlighter h) {
427: this .h = h;
428: backgroundCB.setSelectedItem(h.getBackground());
429: selectedBackgroundCB.setSelectedItem(h
430: .getSelectedBackground());
431: foregroundCB.setSelectedItem(h.getForeground());
432: selectedForegroundCB.setSelectedItem(h
433: .getSelectedForeground());
434: }
435:
436: public void save() {
437: this .h.setBackground((Color) backgroundCB
438: .getSelectedItem());
439: this .h
440: .setSelectedBackground((Color) selectedBackgroundCB
441: .getSelectedItem());
442: this .h.setForeground((Color) foregroundCB
443: .getSelectedItem());
444: this .h
445: .setSelectedForeground((Color) selectedForegroundCB
446: .getSelectedItem());
447: ListDataListener[] listeners = ((AbstractListModel) highlightersList
448: .getModel()).getListDataListeners();
449: int size = pipeline.getHighlighters().length;
450: ListDataEvent evt = new ListDataEvent(highlightersList,
451: ListDataEvent.CONTENTS_CHANGED, size - 1,
452: size - 1);
453: for (int i = 0; i < listeners.length; i++) {
454: listeners[i].contentsChanged(evt);
455: }
456: }
457: }
458:
459: private class AlternateRowDetailPanel extends
460: HighlighterDetailPanel {
461: private JComboBox evenRowCB;
462: private JComboBox oddRowCB;
463: private AlternateRowHighlighter h;
464:
465: public AlternateRowDetailPanel() {
466: evenRowCB = createColorComboBox();
467: add("Even Row Background: ", evenRowCB, false);
468: oddRowCB = createColorComboBox();
469: add("Odd Row Background: ", oddRowCB, true);
470: }
471:
472: public void init(AlternateRowHighlighter h) {
473: super .init(h);
474: this .h = h;
475: evenRowCB.setSelectedItem(h.getEvenRowBackground());
476: oddRowCB.setSelectedItem(h.getOddRowBackground());
477: }
478:
479: public void save() {
480: this .h.setEvenRowBackground((Color) evenRowCB
481: .getSelectedItem());
482: this .h.setOddRowBackground((Color) oddRowCB
483: .getSelectedItem());
484: super .save();
485: }
486: }
487:
488: private class ExpressionDetailPanel extends
489: HighlighterDetailPanel {
490: private JTextField bgExpressionTF;
491: private JTextField fgExpressionTF;
492:
493: // private ExpressionHighlighter h;
494:
495: public ExpressionDetailPanel() {
496: bgExpressionTF = new JTextField();
497: add("Background Expression: ", bgExpressionTF, false);
498: fgExpressionTF = new JTextField();
499: add("Foreground Expression: ", fgExpressionTF, true);
500: }
501:
502: public void init(/*Expression*/Highlighter h) {
503: super .init(h);
504: // this.h = h;
505: // bgExpressionTF.setText(h.getBackgroundExpression());
506: // fgExpressionTF.setText(h.getForegroundExpression());
507: }
508:
509: public void save() {
510: // this.h.setBackgroundExpression(bgExpressionTF.getText());
511: // this.h.setForegroundExpression(fgExpressionTF.getText());
512: super .save();
513: }
514: }
515:
516: private class PatternDetailPanel extends HighlighterDetailPanel {
517: private JTextField patternTF;
518: // private JCheckBox matchFlagsCB;
519: private PatternHighlighter h;
520:
521: public PatternDetailPanel() {
522: patternTF = new JTextField();
523: add("Pattern: ", patternTF, true);
524: // matchFlagsCB = new JCheckBox("Match Flags?");
525: // add("", matchFlagsCB, true);
526: }
527:
528: public void init(PatternHighlighter h) {
529: super .init(h);
530: this .h = h;
531: patternTF.setText(h.getPattern().pattern());
532: // matchFlagsCB.setSelected(...);
533: }
534:
535: public void save() {
536: this .h.setPattern(patternTF.getText(), 0); //TODO
537: super.save();
538: }
539: }
540:
541: }
542: }
|