001: /*
002: * Copyright (c) 2002-2007 JGoodies Karsten Lentzsch. 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 JGoodies Karsten Lentzsch 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:
031: package com.jgoodies.binding.tutorial.basics;
032:
033: import java.util.List;
034:
035: import javax.swing.*;
036: import javax.swing.event.ListSelectionEvent;
037: import javax.swing.event.ListSelectionListener;
038: import javax.swing.text.JTextComponent;
039:
040: import com.jgoodies.binding.tutorial.Album;
041: import com.jgoodies.binding.tutorial.TutorialUtils;
042: import com.jgoodies.forms.builder.PanelBuilder;
043: import com.jgoodies.forms.factories.ButtonBarFactory;
044: import com.jgoodies.forms.layout.CellConstraints;
045: import com.jgoodies.forms.layout.FormLayout;
046:
047: /**
048: * Demonstrates how to connect a master list with a copying details view.
049: * It builds a JList of Albums with an attached Album details panel
050: * that presents the current Album selection. The details data
051: * is copied back and forth from the domain to the details UI components.<p>
052: *
053: * A bound variant of this example is the MasterDetailsBoundExample
054: * that binds the details UI components to the ValueModels provided
055: * by a details PresentationModel. An even simpler variant is the
056: * MasterDetailsSelectionInListExample that uses the SelectionInList
057: * as bean channel for the details PresentationModel.
058: *
059: * @author Karsten Lentzsch
060: * @version $Revision: 1.15 $
061: *
062: * @see com.jgoodies.binding.tutorial.basics.MasterDetailsBoundExample
063: * @see com.jgoodies.binding.tutorial.basics.MasterDetailsSelectionInListExample
064: */
065: public final class MasterDetailsCopyingExample {
066:
067: /**
068: * The Albums displayed in the overview list.
069: */
070: private final List<Album> albums;
071:
072: /**
073: * Holds the list selection, which is the currently edited Album.
074: */
075: private Album editedAlbum;
076:
077: private JList albumsList;
078: private JTextComponent titleField;
079: private JTextComponent artistField;
080: private JTextComponent classicalField;
081: private JTextComponent composerField;
082: private JButton closeButton;
083:
084: // Launching **************************************************************
085:
086: public static void main(String[] args) {
087: try {
088: UIManager
089: .setLookAndFeel("com.jgoodies.looks.plastic.PlasticXPLookAndFeel");
090: } catch (Exception e) {
091: // Likely PlasticXP is not in the class path; ignore.
092: }
093: JFrame frame = new JFrame();
094: frame.setTitle("Binding Tutorial :: Master/Details (Copying)");
095: frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
096: JComponent panel = new MasterDetailsCopyingExample()
097: .buildPanel();
098: frame.getContentPane().add(panel);
099: frame.pack();
100: TutorialUtils.locateOnOpticalScreenCenter(frame);
101: frame.setVisible(true);
102: }
103:
104: // Instance Creation ******************************************************
105:
106: /**
107: * Constructs a list editor using a example Album list.
108: */
109: public MasterDetailsCopyingExample() {
110: this (Album.ALBUMS);
111: }
112:
113: /**
114: * Constructs a list editor for editing the given list of Albums.
115: *
116: * @param albums the list of Albums to edit
117: */
118: public MasterDetailsCopyingExample(List<Album> albums) {
119: this .albums = albums;
120: }
121:
122: // Component Creation and Initialization **********************************
123:
124: /**
125: * Creates and initializes the UI components.
126: * All components in the details view are read-only.
127: */
128: private void initComponents() {
129: albumsList = new JList(albums.toArray());
130: albumsList
131: .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
132: albumsList.setCellRenderer(TutorialUtils
133: .createAlbumListCellRenderer());
134:
135: titleField = new JTextField();
136: titleField.setEditable(false);
137: artistField = new JTextField();
138: artistField.setEditable(false);
139: classicalField = new JTextField();
140: classicalField.setEditable(false);
141: composerField = new JTextField();
142: composerField.setEditable(false);
143: closeButton = new JButton(TutorialUtils.getCloseAction());
144: }
145:
146: private void initEventHandling() {
147: albumsList
148: .addListSelectionListener(new AlbumSelectionHandler());
149: }
150:
151: // Copying Data Back and Forth ********************************************
152:
153: /**
154: * Reads the property values from the edited Album
155: * and sets them in this editor's components.
156: *
157: * @param album the Album to read property values from
158: */
159: private void updateView(Album album) {
160: titleField.setText(album.getTitle());
161: artistField.setText(album.getArtist());
162: classicalField.setText(album.isClassical() ? "Yes" : "No");
163: composerField.setText(album.getComposer());
164: }
165:
166: // Building ***************************************************************
167:
168: /**
169: * Builds and returns a panel that consists of
170: * a master list and a details form.
171: *
172: * @return the built panel
173: */
174: public JComponent buildPanel() {
175: initComponents();
176: initEventHandling();
177:
178: FormLayout layout = new FormLayout(
179: "right:pref, 3dlu, 150dlu:grow",
180: "p, 1dlu, p, 9dlu, p, 1dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 9dlu, p");
181:
182: PanelBuilder builder = new PanelBuilder(layout);
183: builder.setDefaultDialogBorder();
184: CellConstraints cc = new CellConstraints();
185:
186: builder.addSeparator("Albums", cc.xyw(1, 1, 3));
187: builder.add(new JScrollPane(albumsList), cc.xy(3, 3));
188:
189: builder.addSeparator("Details", cc.xyw(1, 5, 3));
190: builder.addLabel("Artist", cc.xy(1, 7));
191: builder.add(artistField, cc.xy(3, 7));
192: builder.addLabel("Title", cc.xy(1, 9));
193: builder.add(titleField, cc.xy(3, 9));
194: builder.addLabel("Classical", cc.xy(1, 11));
195: builder.add(classicalField, cc.xy(3, 11));
196: builder.addLabel("Composer", cc.xy(1, 13));
197: builder.add(composerField, cc.xy(3, 13));
198: builder.add(buildButtonBar(), cc.xyw(1, 15, 3));
199:
200: return builder.getPanel();
201: }
202:
203: private JComponent buildButtonBar() {
204: return ButtonBarFactory.buildRightAlignedBar(closeButton);
205: }
206:
207: // Event Handling *********************************************************
208:
209: /**
210: * Updates the view using the selected album.
211: */
212: private final class AlbumSelectionHandler implements
213: ListSelectionListener {
214:
215: public void valueChanged(ListSelectionEvent e) {
216: if (e.getValueIsAdjusting())
217: return;
218: // Now set the current selection as edited album.
219: editedAlbum = (Album) albumsList.getSelectedValue();
220: // Then copy the album data to the component values.
221: updateView(editedAlbum);
222: }
223: }
224:
225: }
|