001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.sql.framework.ui.view;
042:
043: import java.awt.BorderLayout;
044: import java.awt.GridBagConstraints;
045: import java.awt.GridBagLayout;
046: import java.awt.GridLayout;
047: import java.awt.Insets;
048: import java.awt.event.ActionEvent;
049: import java.awt.event.ActionListener;
050: import java.awt.event.MouseAdapter;
051: import java.awt.event.MouseEvent;
052: import java.util.ArrayList;
053: import java.util.Collection;
054: import java.util.HashSet;
055: import java.util.Iterator;
056: import java.util.List;
057: import java.util.Set;
058:
059: import javax.swing.BorderFactory;
060: import javax.swing.ButtonModel;
061: import javax.swing.DefaultButtonModel;
062: import javax.swing.DefaultListModel;
063: import javax.swing.JButton;
064: import javax.swing.JLabel;
065: import javax.swing.JList;
066: import javax.swing.JPanel;
067: import javax.swing.JScrollPane;
068: import javax.swing.ListCellRenderer;
069: import javax.swing.ListSelectionModel;
070: import javax.swing.event.ChangeEvent;
071: import javax.swing.event.ChangeListener;
072: import javax.swing.event.ListSelectionEvent;
073: import javax.swing.event.ListSelectionListener;
074:
075: /**
076: * A Basic implementation of list transfer panel
077: *
078: * @author Ritesh Adval
079: * @version $Revision$
080: */
081:
082: public class ListTransferPanel extends JPanel implements
083: ActionListener, ListSelectionListener {
084:
085: /**
086: * Container for ListModels associated with source and destination lists of a list
087: * transfer panel. Holds ButtonModels for controls that indicate selected addition and
088: * bulk addition to destination list and selected removal and bulk removal of items
089: * from the destination list.
090: *
091: * @author Jonathan Giron
092: * @author Sanjeeth Duvuru
093: * @version $Revision$
094: */
095: private class ListTransferModel {
096: private ButtonModel addAllButtonModel;
097:
098: private ButtonModel addButtonModel;
099:
100: private HashSet changeListeners;
101: private DefaultListModel dest;
102:
103: private boolean enableButton = true;
104:
105: private String listPrototype;
106: private ButtonModel removeAllButtonModel;
107: private ButtonModel removeButtonModel;
108: private DefaultListModel source;
109:
110: /**
111: * Creates a new instance of ListTransferModel, using the data in the given
112: * collections to initially populate the source and destination lists.
113: *
114: * @param srcColl Collection used to populate source list
115: * @param dstColl Collection used to populate destination list
116: */
117: public ListTransferModel(Collection srcColl, Collection dstColl) {
118:
119: if (srcColl == null || dstColl == null) {
120: throw new IllegalArgumentException(
121: "Must supply non-null collections for srcColl and dstColl");
122: }
123:
124: listPrototype = "";
125:
126: source = new DefaultListModel();
127: dest = new DefaultListModel();
128:
129: addButtonModel = new DefaultButtonModel();
130: addAllButtonModel = new DefaultButtonModel();
131: removeButtonModel = new DefaultButtonModel();
132: removeAllButtonModel = new DefaultButtonModel();
133:
134: setSourceList(srcColl);
135: setDestinationList(dstColl);
136:
137: changeListeners = new HashSet();
138: }
139:
140: /**
141: * Moves indicated items from source to destination list.
142: *
143: * @param selections array of selected items
144: * @param indices array of indices, each element corresponding to the item in
145: * selections array
146: */
147: public void add(Object[] selections, int[] indices) {
148: synchronized (dest) {
149: synchronized (source) {
150: for (int i = 0; i < indices.length; i++) {
151: Object element = selections[i];
152: dest.addElement(element);
153: source.removeElement(element);
154: fireTransferEvent(dest, element,
155: TransferEvent.ADDED);
156: }
157:
158: updateButtonState();
159: }
160:
161: // fire change event so that next button can be enabled as we add new
162: // rows in table
163: fireChangeEvent();
164:
165: }
166:
167: updateButtonState();
168: }
169:
170: /**
171: * Moves all remaining items from source to destination list.
172: */
173: public void addAll() {
174: synchronized (dest) {
175: synchronized (source) {
176: int size = source.getSize();
177: for (int i = 0; i < size; i++) {
178: Object element = source.elementAt(i);
179: dest.addElement(element);
180: fireTransferEvent(dest, element,
181: TransferEvent.ADDED);
182: }
183: source.removeAllElements();
184: }
185: }
186:
187: updateButtonState();
188:
189: // fire change event so that next button can be enabled as we add new rows in
190: // table
191: fireChangeEvent();
192: }
193:
194: /**
195: * @see org.openide.WizardDescriptor.Panel#addChangeListener
196: */
197: public void addChangeListener(ChangeListener l) {
198: synchronized (listeners) {
199: listeners.add(l);
200: }
201: }
202:
203: public void enableButton(boolean enable) {
204: this .enableButton = enable;
205: addButtonModel.setEnabled(enable);
206: addAllButtonModel.setEnabled(enable);
207: removeButtonModel.setEnabled(enable);
208: removeAllButtonModel.setEnabled(enable);
209: }
210:
211: /**
212: * Gets ButtonModel associated with add all button action.
213: *
214: * @return add all ButtonModel
215: */
216: public ButtonModel getAddAllButtonModel() {
217: return addAllButtonModel;
218: }
219:
220: /**
221: * Gets ButtonModel associated with add button action.
222: *
223: * @return add ButtonModel
224: */
225: public ButtonModel getAddButtonModel() {
226: return addButtonModel;
227: }
228:
229: /**
230: * Gets copy of current contents of destination list
231: *
232: * @return List of current destination list contents
233: */
234: public List getDestinationList() {
235: ArrayList dstList = new ArrayList();
236:
237: synchronized (dest) {
238: dest.trimToSize();
239: for (int i = 0; i < dest.size(); i++) {
240: dstList.add(dest.get(i));
241: }
242: }
243:
244: return dstList;
245: }
246:
247: /**
248: * Gets ListModel associated with destination list.
249: *
250: * @return source ListModel
251: */
252: public DefaultListModel getDestinationModel() {
253: return dest;
254: }
255:
256: /**
257: * Gets maximum number of items expected in either the source or destination list.
258: *
259: * @return maximum count of items in any one list
260: */
261: public int getMaximumListSize() {
262: return source.size() + dest.size();
263: }
264:
265: /**
266: * Gets prototype String that has the largest width of an item in either list.
267: *
268: * @return String whose length is the largest among the items in either list
269: */
270: public String getPrototypeCell() {
271: return listPrototype;
272: }
273:
274: /**
275: * Gets ButtonModel associated with remove all button action
276: *
277: * @return remove all ButtonModel
278: */
279: public ButtonModel getRemoveAllButtonModel() {
280: return removeAllButtonModel;
281: }
282:
283: /**
284: * Gets ButtonModel associated with remove button action.
285: *
286: * @return remove ButtonModel
287: */
288: public ButtonModel getRemoveButtonModel() {
289: return removeButtonModel;
290: }
291:
292: /**
293: * Returns index of source item matching the given string.
294: *
295: * @param searchStr string to search for in source list
296: * @param startFrom index from which to start search
297: * @return index of matching item, or -1 if no match exists
298: */
299: public int getSourceIndexFor(String searchStr, int startFrom) {
300: if (startFrom < 0 || startFrom > source.size()) {
301: startFrom = 0;
302: }
303:
304: if (searchStr != null && searchStr.trim().length() != 0) {
305: return source.indexOf(searchStr, startFrom);
306: }
307:
308: return -1;
309: }
310:
311: /**
312: * Gets copy of current contents of source list
313: *
314: * @return List of current source list contents
315: */
316: public List getSourceList() {
317: ArrayList srcList = new ArrayList();
318:
319: synchronized (source) {
320: source.trimToSize();
321: for (int i = 0; i < source.size(); i++) {
322: srcList.add(source.get(i));
323: }
324: }
325:
326: return srcList;
327: }
328:
329: /**
330: * Gets ListModel associated with source list.
331: *
332: * @return source ListModel
333: */
334: public DefaultListModel getSourceModel() {
335: return source;
336: }
337:
338: /**
339: * Moves indicated items from destination to source list.
340: *
341: * @param selections array of selected items
342: * @param indices array of indices, each element corresponding to the item in
343: * selections array
344: */
345: public void remove(Object[] selections, int[] indices) {
346: synchronized (dest) {
347: synchronized (source) {
348: for (int i = 0; i < indices.length; i++) {
349: Object element = selections[i];
350: source.addElement(element);
351: dest.removeElement(element);
352: fireTransferEvent(dest, element,
353: TransferEvent.REMOVED);
354: }
355: }
356: }
357:
358: updateButtonState();
359:
360: // fire change event so that next button can be enabled as we remove new rows
361: // in table
362: fireChangeEvent();
363: }
364:
365: /**
366: * Moves all remaining items from destination to source list.
367: */
368: public void removeAll() {
369: synchronized (dest) {
370: synchronized (source) {
371: int size = dest.getSize();
372: for (int i = 0; i < size; i++) {
373: Object element = dest.elementAt(i);
374: source.addElement(element);
375: }
376: dest.removeAllElements();
377: }
378: }
379:
380: updateButtonState();
381:
382: // fire change event so that next button can be enabled as we remove new rows
383: // in table
384: fireChangeEvent();
385: }
386:
387: /**
388: * @see org.openide.WizardDescriptor.Panel#removeChangeListener
389: */
390: public void removeChangeListener(ChangeListener l) {
391: synchronized (listeners) {
392: listeners.remove(l);
393: }
394: }
395:
396: /**
397: * Sets destination list to include contents of given list. Clears current
398: * contents before adding items from newList.
399: *
400: * @param newList List whose contents will supplant the current contents of the
401: * destination list
402: */
403: public void setDestinationList(Collection newList) {
404: if (newList == null) {
405: throw new IllegalArgumentException(
406: "Must supply non-null Collection for newList");
407: }
408:
409: if (dest == null) {
410: dest = new DefaultListModel();
411: }
412:
413: synchronized (dest) {
414: dest.clear();
415:
416: Iterator it = newList.iterator();
417: while (it.hasNext()) {
418: Object o = it.next();
419: dest.addElement(o);
420: if (o.toString().trim().length() > listPrototype
421: .length()) {
422: listPrototype = o.toString().trim();
423: }
424: }
425: }
426:
427: updateButtonState();
428: }
429:
430: /**
431: * Sets source list to include contents of given list. Clears current contents
432: * before adding items from newList.
433: *
434: * @param newList List whose contents will supplant the current contents of the
435: * source list
436: */
437: public void setSourceList(Collection newList) {
438: if (newList == null) {
439: throw new IllegalArgumentException(
440: "Must supply non-null Collection for newList");
441: }
442:
443: if (source == null) {
444: source = new DefaultListModel();
445: }
446:
447: synchronized (source) {
448: source.clear();
449:
450: Iterator it = newList.iterator();
451: while (it.hasNext()) {
452: Object o = it.next();
453: source.addElement(o);
454: if (o.toString().trim().length() > listPrototype
455: .length()) {
456: listPrototype = o.toString().trim();
457: }
458: }
459: }
460:
461: updateButtonState();
462: }
463:
464: /**
465: * Updates button states
466: */
467: public void updateButtonState() {
468: if (!enableButton) {
469: return;
470: }
471:
472: boolean canAdd = !source.isEmpty();
473: boolean canRemove = !dest.isEmpty();
474:
475: addButtonModel.setEnabled(canAdd);
476: addAllButtonModel.setEnabled(canAdd);
477: removeButtonModel.setEnabled(canRemove);
478: removeAllButtonModel.setEnabled(canRemove);
479: }
480:
481: private void fireTransferEvent(Object src, Object item, int type) {
482: if (src != null && item != null) {
483: TransferEvent e = new TransferEvent(src, item, type);
484: synchronized (changeListeners) {
485: Iterator iter = changeListeners.iterator();
486: while (iter.hasNext()) {
487: ChangeListener l = (ChangeListener) iter.next();
488: l.stateChanged(e);
489: }
490: }
491: }
492: }
493: }
494:
495: /**
496: * Extends ChangeEvent to convey information on an item being transferred to or from
497: * the source of the event.
498: *
499: * @author Jonathan Giron
500: * @version $Revision$
501: */
502: private static class TransferEvent extends ChangeEvent {
503: /** Indicates addition of an item to the source of the event */
504: public static final int ADDED = 0;
505:
506: /** Indicates removal of an item from the source of the event */
507: public static final int REMOVED = 1;
508:
509: private Object item;
510: private int type;
511:
512: /**
513: * Create a new TransferEvent instance with the given source, item and type.
514: *
515: * @param source source of this transfer event
516: * @param item transferred item
517: * @param type transfer type, either ADDED or REMOVED
518: * @see #ADDED
519: * @see #REMOVED
520: */
521: public TransferEvent(Object source, Object item, int type) {
522: super (source);
523: this .item = item;
524: this .type = type;
525: }
526:
527: /**
528: * Gets item that was transferred.
529: *
530: * @return transferred item
531: */
532: public Object getItem() {
533: return item;
534: }
535:
536: /**
537: * Gets type of transfer event.
538: *
539: * @return ADDED or REMOVED
540: */
541: public int getType() {
542: return type;
543: }
544: }
545:
546: /** Indicates addition of item(s). */
547: public static final String LBL_ADD = ">";
548:
549: /** Label indicating that all elements should be moved. */
550: public static final String LBL_ALL = "ALL";
551:
552: /** Indicates addition of all source items. */
553: public static final String LBL_ADD_ALL = LBL_ALL + " " + LBL_ADD;
554:
555: /** Describes destination list */
556: public static final String LBL_DEST_MSG = "Selected Databases:";
557:
558: /** Indicates removal of item(s). */
559: public static final String LBL_REMOVE = "<";
560:
561: /** Indicates removal of all destination items. */
562: public static final String LBL_REMOVE_ALL = LBL_REMOVE + " "
563: + LBL_ALL;
564:
565: /** Describes source list and user task. */
566: public static final String LBL_SOURCE_MSG = "Select Db's from the list:";
567:
568: /** Maximum number of visible items in lists */
569: public static final int MAXIMUM_VISIBLE = 10;
570:
571: /** Minimum number of visible items in lists */
572: public static final int MINIMUM_VISIBLE = 5;
573:
574: /** Tooltip to describe addition of selected item(s). */
575: public static final String TIP_ADD = "Add to selected items";
576:
577: /** Tooltip to describe addition of all source items. */
578: public static final String TIP_ADD_ALL = "Add all items";
579:
580: /** Tooltip to describe addition of selected item(s). */
581: public static final String TIP_REMOVE = "Remove from selected items";
582:
583: /** Tooltip to describe removal of all destination items. */
584: public static final String TIP_REMOVE_ALL = "Remove all items";
585: private Collection destCollection;
586: private JLabel destLabel;
587: private String destLabelStr;
588: private JList destList;
589:
590: /* Set <ChangeListeners> */
591: private final Set listeners = new HashSet(1);
592:
593: private ListTransferModel listModel;
594:
595: private JList sourceList;
596:
597: private Collection srcCollection;
598:
599: private JLabel srcLabel;
600:
601: private String srcLabelStr;
602:
603: public ListTransferPanel(String sLabelStr, String dLabelStr,
604: Collection sCollection, Collection dCollection) {
605:
606: this .srcLabelStr = sLabelStr;
607: this .destLabelStr = dLabelStr;
608: this .srcCollection = sCollection;
609: this .destCollection = dCollection;
610:
611: initGui();
612: }
613:
614: /**
615: * Invoked whenever one of the transfer buttons is clicked.
616: *
617: * @param e ActionEvent to handle
618: */
619: public void actionPerformed(ActionEvent e) {
620: String cmd = e.getActionCommand();
621:
622: if (LBL_ADD.equals(cmd)) {
623: int[] indices = sourceList.getSelectedIndices();
624: Object[] selections = sourceList.getSelectedValues();
625: listModel.add(selections, indices);
626: } else if (LBL_ADD_ALL.equals(cmd)) {
627: listModel.addAll();
628: } else if (LBL_REMOVE.equals(cmd)) {
629: int[] indices = destList.getSelectedIndices();
630: Object[] selections = destList.getSelectedValues();
631: listModel.remove(selections, indices);
632: } else if (LBL_REMOVE_ALL.equals(cmd)) {
633: listModel.removeAll();
634: } else {
635: // Log this as an invalid or unknown command.
636: System.err.println("Unknown cmd: " + cmd);
637: }
638: }
639:
640: /**
641: * Add a ChangeListener to this model.
642: *
643: * @param l ChangeListener to add
644: */
645: public void addChangeListener(ChangeListener l) {
646: if (l != null) {
647: synchronized (listeners) {
648: listeners.add(l);
649: }
650: }
651: }
652:
653: public void addToDestination(Object item) {
654: DefaultListModel dModel = listModel.getDestinationModel();
655: dModel.addElement(item);
656: }
657:
658: public void addToSource(Object item) {
659: DefaultListModel sModel = listModel.getSourceModel();
660: sModel.addElement(item);
661: }
662:
663: public void enableButton(boolean enable) {
664: this .listModel.enableButton(enable);
665: }
666:
667: /**
668: * Fires a ChangeEvent to all interested listeners to indicate a state change in one
669: * or more UI components.
670: */
671: public void fireChangeEvent() {
672: Iterator it;
673:
674: synchronized (listeners) {
675: it = new HashSet(listeners).iterator();
676: }
677:
678: ChangeEvent ev = new ChangeEvent(this );
679: while (it.hasNext()) {
680: ((ChangeListener) it.next()).stateChanged(ev);
681: }
682: }
683:
684: public JList getDestinationJList() {
685: return this .destList;
686: }
687:
688: /**
689: * Gets copy of current contents of destination list
690: *
691: * @return List of current destination list contents
692: */
693: public List getDestinationList() {
694: return listModel.getDestinationList();
695: }
696:
697: public JList getSourceJList() {
698: return this .sourceList;
699: }
700:
701: /**
702: * Gets copy of current contents of source list
703: *
704: * @return List of current source list contents
705: */
706: public List getSourceList() {
707: return listModel.getSourceList();
708: }
709:
710: /**
711: * Remove a ChangeListener from this model.
712: *
713: * @param l ChangeListener to remove
714: */
715: public void removeChangeListener(ChangeListener l) {
716: if (l != null) {
717: synchronized (listeners) {
718: listeners.remove(l);
719: }
720: }
721: }
722:
723: public void removeFromDestination(Object item) {
724: DefaultListModel dModel = listModel.getDestinationModel();
725: dModel.removeElement(item);
726: }
727:
728: public void removeFromSource(Object item) {
729: DefaultListModel sModel = listModel.getSourceModel();
730: sModel.removeElement(item);
731: }
732:
733: public void reset() {
734: this .setSourceList(new ArrayList());
735: this .setDestinationList(new ArrayList());
736: this .enableButton(true);
737: }
738:
739: /**
740: * set the destination list
741: *
742: * @param dList destination list
743: */
744: public void setDestinationList(Collection dList) {
745: listModel.setDestinationList(dList);
746: this .destList.setModel(listModel.getDestinationModel());
747: }
748:
749: /**
750: * set the target list cell renderer
751: *
752: * @param cellRenderer list cell renderer
753: */
754: public void setDestinationListCellRenderer(
755: ListCellRenderer cellRenderer) {
756: this .destList.setCellRenderer(cellRenderer);
757: }
758:
759: /**
760: * set the source list
761: *
762: * @param sList source list
763: */
764: public void setSourceList(Collection sList) {
765: listModel.setSourceList(sList);
766: this .sourceList.setModel(listModel.getSourceModel());
767: }
768:
769: /**
770: * set the source list cell renderer
771: *
772: * @param cellRenderer list cell renderer
773: */
774: public void setSourceListCellRenderer(ListCellRenderer cellRenderer) {
775: this .sourceList.setCellRenderer(cellRenderer);
776: }
777:
778: /**
779: * Called whenever the value of the selection changes.
780: *
781: * @param e the event that characterizes the change.
782: */
783: public void valueChanged(ListSelectionEvent e) {
784: Object src = e.getSource();
785:
786: // Enforce mutually exclusive focus between source and destination
787: // lists.
788: if (sourceList.equals(src)) {
789: if (!destList.isSelectionEmpty()) {
790: destList.clearSelection();
791: }
792: } else if (destList.equals(src)) {
793: if (!sourceList.isSelectionEmpty()) {
794: sourceList.clearSelection();
795: }
796: } else {
797: // TODO: Log unhandled ListSelectionEvent as DEBUG message.
798: }
799: }
800:
801: private void initGui() {
802: listModel = new ListTransferModel(srcCollection, destCollection);
803: String largestString = listModel.getPrototypeCell();
804:
805: if (largestString.length() < srcLabelStr.length()) {
806: largestString = srcLabelStr;
807: } else if (largestString.length() < destLabelStr.length()) {
808: largestString = destLabelStr;
809: }
810:
811: int visibleCt = Math.min(Math.max(MINIMUM_VISIBLE, listModel
812: .getMaximumListSize()), MAXIMUM_VISIBLE);
813:
814: sourceList = new JList(listModel.getSourceModel());
815: sourceList
816: .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
817: sourceList.addMouseListener(new MouseAdapter() {
818: public void mouseClicked(MouseEvent e) {
819: if (e.getClickCount() == 2
820: && e.getSource() instanceof JList) {
821: JList list = (JList) e.getSource();
822: int[] indices = list.getSelectedIndices();
823: Object[] selections = list.getSelectedValues();
824: listModel.add(selections, indices);
825: }
826: }
827: });
828: sourceList.addListSelectionListener(this );
829: sourceList.setPrototypeCellValue(largestString);
830: sourceList.setVisibleRowCount(visibleCt);
831:
832: destList = new JList(listModel.getDestinationModel());
833: destList
834: .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
835: destList.addMouseListener(new MouseAdapter() {
836: public void mouseClicked(MouseEvent e) {
837: if (e.getClickCount() == 2
838: && e.getSource() instanceof JList) {
839: JList list = (JList) e.getSource();
840: int[] indices = list.getSelectedIndices();
841: Object[] selections = list.getSelectedValues();
842: listModel.remove(selections, indices);
843: }
844: }
845: });
846: destList.addListSelectionListener(this );
847: destList.setPrototypeCellValue(largestString);
848: destList.setVisibleRowCount(visibleCt);
849:
850: JPanel searchPanel = new JPanel();
851: searchPanel.setLayout(new BorderLayout());
852: srcLabel = new JLabel(srcLabelStr);
853: srcLabel.getAccessibleContext().setAccessibleName(srcLabelStr);
854: //srcLabel.setDisplayedMnemonic('s');
855: srcLabel.setLabelFor(sourceList);
856:
857: searchPanel.add(srcLabel, BorderLayout.NORTH);
858:
859: JScrollPane sourcepane = new JScrollPane(sourceList);
860: JScrollPane destpane = new JScrollPane(destList);
861: JPanel buttonPanel = new JPanel();
862:
863: JButton addButton = new JButton(LBL_ADD);
864: addButton.setModel(listModel.getAddButtonModel());
865: addButton.setToolTipText(TIP_ADD);
866:
867: JButton removeButton = new JButton(LBL_REMOVE);
868: removeButton.setModel(listModel.getRemoveButtonModel());
869: removeButton.setToolTipText(TIP_REMOVE);
870:
871: JButton removeAllButton = new JButton(LBL_REMOVE_ALL);
872: removeAllButton.setModel(listModel.getRemoveAllButtonModel());
873: removeAllButton.setToolTipText(TIP_REMOVE_ALL);
874:
875: JButton addAllButton = new JButton(LBL_ADD_ALL);
876: addAllButton.setModel(listModel.getAddAllButtonModel());
877: addAllButton.setToolTipText(TIP_ADD_ALL);
878:
879: addButton.setMargin(new Insets(2, 18, 2, 18));
880: removeButton.setMargin(new Insets(2, 18, 2, 18));
881: removeAllButton.setMargin(new Insets(2, 15, 2, 15));
882: addAllButton.setMargin(new Insets(2, 15, 2, 15));
883:
884: buttonPanel.setLayout(new GridLayout(6, 1));
885:
886: buttonPanel.add(new JPanel());
887: buttonPanel.add(addButton);
888: buttonPanel.add(removeButton);
889: buttonPanel.add(new JPanel());
890: buttonPanel.add(removeAllButton);
891: buttonPanel.add(addAllButton);
892:
893: addButton.addActionListener(this );
894: removeButton.addActionListener(this );
895: removeAllButton.addActionListener(this );
896: addAllButton.addActionListener(this );
897:
898: JPanel sourcePanel = new JPanel();
899: sourcePanel.setLayout(new BorderLayout());
900: sourcePanel.add(searchPanel, BorderLayout.NORTH);
901: sourcePanel.add(sourcepane, BorderLayout.CENTER);
902: sourcePanel.setBorder(BorderFactory.createEmptyBorder(10, 10,
903: 10, 5));
904:
905: JPanel ctrPanel = new JPanel();
906: ctrPanel.add(buttonPanel);
907: ctrPanel.setBorder(BorderFactory
908: .createEmptyBorder(10, 5, 10, 5));
909:
910: JPanel destPanel = new JPanel();
911: destLabel = new JLabel(destLabelStr);
912: destLabel.getAccessibleContext()
913: .setAccessibleName(destLabelStr);
914: // DestLabel.setDisplayedMnemonic('o');
915: destLabel.setLabelFor(destList);
916:
917: destPanel.setLayout(new BorderLayout());
918: destPanel.add(destLabel, BorderLayout.NORTH);
919: destPanel.add(destpane, BorderLayout.CENTER);
920: destPanel.setBorder(BorderFactory.createEmptyBorder(10, 5, 10,
921: 10));
922:
923: JPanel listPanel = new JPanel();
924:
925: GridBagLayout gridbag = new GridBagLayout();
926: GridBagConstraints c = new GridBagConstraints();
927: listPanel.setLayout(gridbag);
928:
929: // Allocate half of the resized space to sourcePanel
930: c.fill = GridBagConstraints.BOTH;
931: c.gridx = 0;
932: c.gridy = 0;
933: c.weightx = 1.0;
934: c.weighty = 1.0;
935: listPanel.add(sourcePanel, c);
936: // Make ctrPanel non resizeable
937: c.fill = GridBagConstraints.NONE;
938: c.gridx = 1;
939: c.gridy = 0;
940: c.weightx = 0.0;
941: c.weighty = 0.0;
942: listPanel.add(ctrPanel, c);
943: // Allocate half of the resized space to destPanel
944: c.fill = GridBagConstraints.BOTH;
945: c.gridx = 2;
946: c.gridy = 0;
947: c.weightx = 1.0;
948: c.weighty = 1.0;
949: listPanel.add(destPanel, c);
950:
951: setLayout(new BorderLayout());
952: add(listPanel, BorderLayout.CENTER);
953:
954: }
955: }
|