001: /*
002: * Copyright (c) 2005-2008 Substance Kirill Grouchnikov. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of Substance Kirill Grouchnikov nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030: package test.check;
031:
032: import java.awt.*;
033: import java.awt.event.ActionEvent;
034: import java.awt.event.ActionListener;
035: import java.util.ArrayList;
036: import java.util.List;
037:
038: import javax.swing.*;
039: import javax.swing.event.*;
040:
041: import org.jvnet.lafwidget.LafWidget;
042: import org.jvnet.lafwidget.utils.LafConstants.AnimationKind;
043: import org.jvnet.substance.*;
044: import org.jvnet.substance.combo.WidestComboPopupPrototype;
045:
046: import com.jgoodies.forms.builder.DefaultFormBuilder;
047: import com.jgoodies.forms.layout.FormLayout;
048:
049: /**
050: * Test application panel for testing {@link JList} component.
051: *
052: * @author Kirill Grouchnikov
053: */
054: public class ListPanel extends ControllablePanel {
055:
056: /**
057: * List model implementation with support for moving elements.
058: *
059: * @author Kirill Grouchnikov
060: */
061: private static class MoveableListModel extends AbstractListModel {
062: /**
063: * The string list backing up the model.
064: */
065: protected List<String> model;
066:
067: /**
068: * Creates a new model.
069: */
070: public MoveableListModel(int modelSize) {
071: super ();
072: model = new ArrayList<String>();
073: for (int i = 0; i < modelSize; i++) {
074: model.add("element " + i);
075: }
076: }
077:
078: /*
079: * (non-Javadoc)
080: *
081: * @see javax.swing.ListModel#getElementAt(int)
082: */
083: public Object getElementAt(int index) {
084: return model.get(index);
085: }
086:
087: /*
088: * (non-Javadoc)
089: *
090: * @see javax.swing.ListModel#getSize()
091: */
092: public int getSize() {
093: return model.size();
094: }
095:
096: /**
097: * Moves the element at the specified index one position up.
098: *
099: * @param index
100: * Element index.
101: */
102: public void moveUp(int index) {
103: String entry = model.get(index);
104: model.set(index, model.get(index - 1));
105: model.set(index - 1, entry);
106: fireContentsChanged(this , index - 1, index);
107: }
108:
109: /**
110: * Moves the element at the specified index one position down.
111: *
112: * @param index
113: * Element index.
114: */
115: public void moveDown(int index) {
116: String entry = model.get(index);
117: model.set(index, model.get(index + 1));
118: model.set(index + 1, entry);
119: fireContentsChanged(this , index, index + 1);
120: }
121:
122: /**
123: * Deletes the element at the specified index.
124: *
125: * @param index
126: * Element index.
127: */
128: public void delete(int index) {
129: model.remove(index);
130: fireIntervalRemoved(this , index, index);
131: }
132:
133: /*
134: * (non-Javadoc)
135: *
136: * @see org.jvnet.lafwidget.list.MutableListModel#move(int, int)
137: */
138: public void move(int fromIndex, int toIndex) {
139: String from = model.remove(fromIndex);
140: model.add(toIndex, from);
141: fireContentsChanged(this , fromIndex, toIndex);
142: }
143: }
144:
145: /**
146: * List.
147: */
148: private JList list;
149:
150: /**
151: * Button to move the selected element up.
152: */
153: private JButton bUp;
154:
155: /**
156: * Button to move the selected element down.
157: */
158: private JButton bDown;
159:
160: /**
161: * Button to delete the selected element.
162: */
163: private JButton bDelete;
164:
165: /**
166: * Old background color.
167: */
168: private Color oldBackColor;
169:
170: /**
171: * Old list cell renderer.
172: */
173: private ListCellRenderer oldListCellRenderer;
174:
175: /**
176: * Creates a new list panel.
177: */
178: public ListPanel() {
179: super ();
180: setLayout(new BorderLayout());
181: list = new JList(new MoveableListModel(100));
182:
183: final JScrollPane jsp = new JScrollPane(list);
184: this .add(jsp, BorderLayout.CENTER);
185:
186: FormLayout lm = new FormLayout(
187: "right:pref, 4dlu, fill:pref:grow", "");
188: DefaultFormBuilder builder = new DefaultFormBuilder(lm,
189: new ScrollablePanel());
190: builder.appendSeparator("General");
191:
192: final JCheckBox isEnabled = new JCheckBox("is enabled");
193: isEnabled.setSelected(list.isEnabled());
194: isEnabled.addActionListener(new ActionListener() {
195: public void actionPerformed(ActionEvent e) {
196: list.setEnabled(isEnabled.isSelected());
197: }
198: });
199: builder.append("Enabled", isEnabled);
200:
201: final JCheckBox toUseSubstanceRenderer = new JCheckBox(
202: "use substance");
203: toUseSubstanceRenderer.setSelected(true);
204: toUseSubstanceRenderer.addActionListener(new ActionListener() {
205: public void actionPerformed(ActionEvent e) {
206: if (toUseSubstanceRenderer.isSelected())
207: list
208: .setCellRenderer(new SubstanceDefaultListCellRenderer());
209: else
210: list.setCellRenderer(new DefaultListCellRenderer());
211: }
212: });
213: builder.append("Renderer", toUseSubstanceRenderer);
214:
215: final JSlider rowCountSlider = new JSlider(10, 1000, this .list
216: .getModel().getSize());
217: rowCountSlider.setPaintLabels(false);
218: rowCountSlider.setPaintTicks(false);
219: rowCountSlider.addChangeListener(new ChangeListener() {
220: public void stateChanged(ChangeEvent e) {
221: if (rowCountSlider.getValueIsAdjusting())
222: return;
223: list.setModel(new MoveableListModel(rowCountSlider
224: .getValue()));
225: }
226: });
227: builder.append("Row count", rowCountSlider);
228:
229: final JCheckBox watermarkBleed = new JCheckBox(
230: "watermark bleed");
231: watermarkBleed.addActionListener(new ActionListener() {
232: public void actionPerformed(ActionEvent e) {
233: list.putClientProperty(
234: SubstanceLookAndFeel.WATERMARK_TO_BLEED,
235: Boolean.valueOf(watermarkBleed.isSelected()));
236: jsp.putClientProperty(
237: SubstanceLookAndFeel.WATERMARK_TO_BLEED,
238: Boolean.valueOf(watermarkBleed.isSelected()));
239: list.repaint();
240: }
241: });
242: builder.append("Watermark", watermarkBleed);
243: final JComboBox animCombo = new JComboBox(new Object[] {
244: AnimationKind.NONE, AnimationKind.SLOW,
245: AnimationKind.REGULAR, AnimationKind.FAST });
246: animCombo.setSelectedItem(AnimationKind.REGULAR);
247: animCombo.addActionListener(new ActionListener() {
248: public void actionPerformed(ActionEvent e) {
249: list.putClientProperty(LafWidget.ANIMATION_KIND,
250: animCombo.getSelectedItem());
251: }
252: });
253: animCombo.setRenderer(new SubstanceDefaultComboBoxRenderer(
254: animCombo) {
255: @Override
256: public Component getListCellRendererComponent(JList list,
257: Object value, int index, boolean isSelected,
258: boolean cellHasFocus) {
259: AnimationKind ak = (AnimationKind) value;
260: return super .getListCellRendererComponent(list, ak
261: .getName(), index, isSelected, cellHasFocus);
262: }
263: });
264: builder.append("Animation", animCombo);
265:
266: bUp = new JButton("Move selected up");
267: bUp.putClientProperty(SubstanceLookAndFeel.FLAT_PROPERTY,
268: Boolean.TRUE);
269:
270: bDown = new JButton("Move selected down");
271: bDown.putClientProperty(SubstanceLookAndFeel.FLAT_PROPERTY,
272: Boolean.TRUE);
273:
274: bDelete = new JButton("Delete selected");
275: bDelete.putClientProperty(SubstanceLookAndFeel.FLAT_PROPERTY,
276: Boolean.TRUE);
277:
278: builder.append("Actions", bUp);
279: builder.append("", bDown);
280: builder.append("", bDelete);
281:
282: bUp.addActionListener(new ActionListener() {
283: public void actionPerformed(ActionEvent e) {
284: int si = list.getSelectedIndex();
285: MoveableListModel mlm = (MoveableListModel) list
286: .getModel();
287: mlm.moveUp(si);
288: list.setSelectedIndex(si - 1);
289: }
290: });
291:
292: bDown.addActionListener(new ActionListener() {
293: public void actionPerformed(ActionEvent e) {
294: int si = list.getSelectedIndex();
295: MoveableListModel mlm = (MoveableListModel) list
296: .getModel();
297: mlm.moveDown(si);
298: list.setSelectedIndex(si + 1);
299: }
300: });
301:
302: bDelete.addActionListener(new ActionListener() {
303: public void actionPerformed(ActionEvent e) {
304: MoveableListModel mlm = (MoveableListModel) list
305: .getModel();
306: for (int i = list.getMaxSelectionIndex(); i >= list
307: .getMinSelectionIndex(); i--) {
308: if (list.isSelectedIndex(i)) {
309: mlm.delete(i);
310: }
311: }
312: list.clearSelection();
313: }
314: });
315:
316: synchronize();
317:
318: list.getSelectionModel().addListSelectionListener(
319: new ListSelectionListener() {
320: public void valueChanged(ListSelectionEvent e) {
321: SwingUtilities.invokeLater(new Runnable() {
322: public void run() {
323: synchronize();
324: }
325: });
326: }
327: });
328:
329: final JComboBox selectionModelCb = new JComboBox(new Object[] {
330: "single", "single interval", "multiple interval" });
331: selectionModelCb.setSelectedIndex(0);
332: list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
333: selectionModelCb.putClientProperty(
334: SubstanceLookAndFeel.COMBO_POPUP_PROTOTYPE,
335: new WidestComboPopupPrototype());
336: selectionModelCb.addActionListener(new ActionListener() {
337: public void actionPerformed(ActionEvent e) {
338: SwingUtilities.invokeLater(new Runnable() {
339: public void run() {
340: String selected = (String) selectionModelCb
341: .getSelectedItem();
342: if ("single".equals(selected))
343: list
344: .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
345: if ("single interval".equals(selected))
346: list
347: .setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
348: if ("multiple interval".equals(selected))
349: list
350: .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
351: }
352: });
353: }
354: });
355:
356: builder.append("Selection", selectionModelCb);
357:
358: final JCheckBox customBackgroundCb = new JCheckBox(
359: "Has pink background");
360: customBackgroundCb.addActionListener(new ActionListener() {
361: public void actionPerformed(ActionEvent e) {
362: if (customBackgroundCb.isSelected()) {
363: oldBackColor = list.getBackground();
364: list.setBackground(new Color(255, 128, 128));
365: } else {
366: list.setBackground(oldBackColor);
367: }
368: }
369: });
370:
371: builder.append("Background", customBackgroundCb);
372:
373: final JCheckBox customRenderer = new JCheckBox(
374: "Has custom renderer");
375: customRenderer.addActionListener(new ActionListener() {
376: public void actionPerformed(ActionEvent e) {
377: if (customRenderer.isSelected()) {
378: oldListCellRenderer = list.getCellRenderer();
379: list.setCellRenderer(new MyListCellRenderer());
380: } else {
381: list.setCellRenderer(oldListCellRenderer);
382: }
383: }
384: });
385:
386: builder.append("Renderer", customRenderer);
387:
388: controlPanel = builder.getPanel();
389: }
390:
391: /**
392: * Synchronizes the list selection and the enable / disable status of the
393: * control buttons.
394: */
395: public void synchronize() {
396: int sc = list.getSelectedIndices().length;
397: if (sc != 1) {
398: bUp.setEnabled(false);
399: bDown.setEnabled(false);
400: return;
401: }
402: bDelete.setEnabled(sc > 0);
403:
404: int si = list.getSelectedIndex();
405: bUp.setEnabled(si > 0);
406: bDown.setEnabled(si < (list.getModel().getSize() - 1));
407: // this.bDelete.setEnabled(true);
408: }
409: }
|