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;
032:
033: import java.awt.Component;
034: import java.awt.Dimension;
035: import java.awt.event.ActionEvent;
036: import java.beans.PropertyChangeEvent;
037: import java.beans.PropertyChangeListener;
038: import java.lang.ref.WeakReference;
039: import java.util.LinkedList;
040: import java.util.List;
041:
042: import javax.swing.*;
043: import javax.swing.table.TableModel;
044:
045: import com.jgoodies.binding.adapter.AbstractTableAdapter;
046:
047: /**
048: * Consists only of static methods that return instances
049: * reused in multiple examples of the JGoodies Binding tutorial.
050: *
051: * @author Karsten Lentzsch
052: * @version $Revision: 1.21 $
053: */
054: public final class TutorialUtils {
055:
056: private TutorialUtils() {
057: // Suppresses default constructor, ensuring non-instantiability.
058: }
059:
060: /**
061: * Creates and returns a renderer for Albums in a list.
062: *
063: * @return a renderer for Albums in lists.
064: */
065: public static ListCellRenderer createAlbumListCellRenderer() {
066: return new AlbumListCellRenderer();
067: }
068:
069: /**
070: * Creates and returns a TableModel for Albums with columns
071: * for the title, artist, classical and composer.
072: *
073: * @param listModel the ListModel of Albums to display in the table
074: * @return a TableModel on the list of Albums
075: */
076: public static TableModel createAlbumTableModel(ListModel listModel) {
077: return new AlbumTableModel(listModel);
078: }
079:
080: /**
081: * Returns a listener that writes bean property changes to the console.
082: * The log entry includes the PropertyChangeEvent's source, property name,
083: * old value, and new value.
084: *
085: * @return a debug listener that logs bean changes to the console
086: */
087: public static PropertyChangeListener createDebugPropertyChangeListener() {
088: PropertyChangeListener listener = new DebugPropertyChangeListener();
089: debugListeners.add(listener);
090: return listener;
091: }
092:
093: /**
094: * Creates and returns an Action that exists the system if performed.
095: *
096: * @return an Action that exists the system if performed
097: *
098: * @see System#exit(int)
099: */
100: public static Action getCloseAction() {
101: return new CloseAction();
102: }
103:
104: /**
105: * Locates the given component on the screen's center.
106: *
107: * @param component the component to be centered
108: */
109: public static void locateOnOpticalScreenCenter(Component component) {
110: Dimension paneSize = component.getSize();
111: Dimension screenSize = component.getToolkit().getScreenSize();
112: component.setLocation((screenSize.width - paneSize.width) / 2,
113: (int) ((screenSize.height - paneSize.height) * 0.45));
114: }
115:
116: // Renderer ***************************************************************
117:
118: /**
119: * Used to renders Albums in JLists and JComboBoxes. If the combo box
120: * selection is null, an empty text <code>""</code> is rendered.
121: */
122: private static final class AlbumListCellRenderer extends
123: DefaultListCellRenderer {
124:
125: @Override
126: public Component getListCellRendererComponent(JList list,
127: Object value, int index, boolean isSelected,
128: boolean cellHasFocus) {
129: Component component = super .getListCellRendererComponent(
130: list, value, index, isSelected, cellHasFocus);
131:
132: Album album = (Album) value;
133: setText(album == null ? "" : (" " + album.getTitle()));
134: return component;
135: }
136: }
137:
138: // TableModel *************************************************************
139:
140: /**
141: * Describes how to present an Album in a JTable.
142: */
143: private static final class AlbumTableModel extends
144: AbstractTableAdapter<Album> {
145:
146: private static final String[] COLUMNS = { "Artist", "Title",
147: "Classical", "Composer" };
148:
149: private AlbumTableModel(ListModel listModel) {
150: super (listModel, COLUMNS);
151: }
152:
153: public Object getValueAt(int rowIndex, int columnIndex) {
154: Album album = getRow(rowIndex);
155: switch (columnIndex) {
156: case 0:
157: return album.getArtist();
158: case 1:
159: return album.getTitle();
160: case 2:
161: return Boolean.valueOf(album.isClassical());
162: case 3:
163: return album.isClassical() ? album.getComposer() : "";
164: default:
165: throw new IllegalStateException("Unknown column");
166: }
167: }
168:
169: }
170:
171: // Debug Listener *********************************************************
172:
173: /**
174: * Used to hold debug listeners, so they won't be removed by
175: * the garbage collector, even if registered by a listener list
176: * that is based on weak references.
177: *
178: * @see #createDebugPropertyChangeListener()
179: * @see WeakReference
180: */
181: private static List<PropertyChangeListener> debugListeners = new LinkedList<PropertyChangeListener>();
182:
183: /**
184: * Writes the source, property name, old/new value to the system console.
185: */
186: private static final class DebugPropertyChangeListener implements
187: PropertyChangeListener {
188:
189: public void propertyChange(PropertyChangeEvent evt) {
190: System.out.println();
191: System.out.println("The source: " + evt.getSource());
192: System.out.println("changed '" + evt.getPropertyName()
193: + "' from '" + evt.getOldValue() + "' to '"
194: + evt.getNewValue() + "'.");
195: }
196: }
197:
198: // Actions ****************************************************************
199:
200: /**
201: * An Action that exists the System.
202: */
203: private static final class CloseAction extends AbstractAction {
204:
205: private CloseAction() {
206: super ("Close");
207: }
208:
209: public void actionPerformed(ActionEvent e) {
210: System.exit(0);
211: }
212: }
213:
214: }
|