001 package com.croftsoft.apps.agoracast.c2p;
002
003 import java.awt.*;
004 import java.awt.event.*;
005 import java.beans.*;
006 import java.io.*;
007 import javax.swing.*;
008 import javax.swing.event.*;
009 import javax.swing.table.*;
010 import java.util.*;
011
012 import com.croftsoft.core.gui.ButtonPanel2;
013 import com.croftsoft.core.gui.LabeledFieldsPanel2;
014 import com.croftsoft.core.gui.table.AlternatingRenderer;
015 import com.croftsoft.core.gui.table.TableColumnModelAdapter;
016 import com.croftsoft.core.lang.NullArgumentException;
017 import com.croftsoft.core.util.ArrayLib;
018
019 /*********************************************************************
020 * Displays the downloaded data in a table.
021 *
022 * <p />
023 *
024 * @version
025 * 2001-11-09
026 * @since
027 * 2001-07-31
028 * @author
029 * <a href="http://croftsoft.com/">David Wallace Croft</a>
030 *********************************************************************/
031
032 public final class AgoracastTablePanel
033 extends JPanel
034 implements ActionListener
035 //////////////////////////////////////////////////////////////////////
036 //////////////////////////////////////////////////////////////////////
037 {
038
039 private static final String CATEGORY_ALL = "--- ALL ---";
040
041 //
042
043 private final AgoracastMediator agoracastMediator;
044
045 private final AgoracastBrowsePanel agoracastBrowsePanel;
046
047 private final JButton columnsButton;
048
049 private final JButton downloadButton;
050
051 private final JComboBox jComboBox;
052
053 //
054
055 private AgoracastTableModel agoracastTableModel;
056
057 private JTable jTable;
058
059 private JScrollPane jScrollPane;
060
061 private String category;
062
063 private String [ ] columnNames;
064
065 //////////////////////////////////////////////////////////////////////
066 //////////////////////////////////////////////////////////////////////
067
068 public AgoracastTablePanel (
069 AgoracastMediator agoracastMediator,
070 AgoracastBrowsePanel agoracastBrowsePanel )
071 //////////////////////////////////////////////////////////////////////
072 {
073 super ( new BorderLayout ( ), true ); // isDoubleBuffered
074
075 NullArgumentException.check (
076 this.agoracastMediator = agoracastMediator );
077
078 NullArgumentException.check (
079 this.agoracastBrowsePanel = agoracastBrowsePanel );
080
081 AgoracastLib.setColor ( this, agoracastMediator );
082
083 updateTable ( null );
084
085 columnsButton = new JButton ( "Add and Remove Columns" );
086
087 columnsButton.addActionListener ( this );
088
089 downloadButton = new JButton ( "Download New Data" );
090
091 downloadButton.addActionListener ( this );
092
093 add (
094 new ButtonPanel2 (
095 new JButton [ ] { columnsButton, downloadButton } ),
096 BorderLayout.SOUTH );
097
098 String [ ] categories = ( String [ ] ) ArrayLib.prepend (
099 AgoracastConstants.CHOICES_CATEGORY, CATEGORY_ALL );
100
101 jComboBox = new JComboBox ( categories );
102
103 jComboBox.addActionListener ( this );
104
105 JPanel categoryPanel = new JPanel ( new FlowLayout ( ), true );
106
107 categoryPanel.add ( new JLabel ( "Category: " ) );
108
109 categoryPanel.add ( jComboBox );
110
111 JPanel northPanel = new JPanel ( new BorderLayout ( ), true );
112
113 northPanel.add ( categoryPanel, BorderLayout.NORTH );
114
115 northPanel.add (
116 new JLabel ( AgoracastConstants.TABLE_TEXT ), BorderLayout.SOUTH );
117
118 add ( northPanel, BorderLayout.NORTH );
119 }
120
121 //////////////////////////////////////////////////////////////////////
122 //////////////////////////////////////////////////////////////////////
123
124 public synchronized void actionPerformed ( ActionEvent actionEvent )
125 //////////////////////////////////////////////////////////////////////
126 {
127 Object source = actionEvent.getSource ( );
128
129 if ( source == downloadButton )
130 {
131 agoracastBrowsePanel.download ( );
132 }
133 else if ( source == columnsButton )
134 {
135 agoracastBrowsePanel.showFieldsPanel ( columnNames );
136 }
137 else if ( source == jComboBox )
138 {
139 handleCategorySelection ( );
140 }
141 }
142
143 public synchronized void updateTable ( String [ ] columnNames )
144 //////////////////////////////////////////////////////////////////////
145 {
146 if ( ( columnNames == null )
147 || ( columnNames.length < 1 ) )
148 {
149 // get the default columns for the category
150
151 AgoracastCategory agoracastCategory
152 = agoracastMediator.getAgoracastCategory ( category );
153
154 columnNames = agoracastCategory.getColumnNames ( );
155 }
156
157 this.columnNames = columnNames;
158
159 if ( jScrollPane != null )
160 {
161 remove ( jScrollPane );
162 }
163
164 agoracastTableModel = new AgoracastTableModel (
165 agoracastMediator, category, columnNames );
166
167 jTable = new JTable ( agoracastTableModel );
168
169 // The following hack attempts to size the column widths proportional
170 // to their max String lengths. Should be replaced by a better
171 // algorithm or a method that allows the user to persistently set the
172 // width.
173
174 TableColumnModel tableColumnModel = jTable.getColumnModel ( );
175
176 int columnCount = tableColumnModel.getColumnCount ( );
177
178 int rowCount = agoracastTableModel.getRowCount ( );
179
180 for ( int i = 0; i < columnCount; i++ )
181 {
182 TableColumn tableColumn = tableColumnModel.getColumn ( i );
183
184 int maxCharacterWidth
185 = agoracastTableModel.getColumnName ( i ).length ( );
186
187 for ( int j = 0; j < rowCount; j++ )
188 {
189 String value = ( String )
190 ( agoracastTableModel.getValueAt ( j, i ) );
191
192 if ( value != null )
193 {
194 int length = value.length ( );
195
196 if ( length > maxCharacterWidth )
197 {
198 maxCharacterWidth = length;
199 }
200 }
201 }
202
203 tableColumn.setPreferredWidth ( maxCharacterWidth * 15 );
204 }
205
206 jTable.getSelectionModel ( ).setSelectionMode (
207 ListSelectionModel.SINGLE_SELECTION );
208
209 JTableHeader jTableHeader = jTable.getTableHeader ( );
210
211 jTableHeader.setUpdateTableInRealTime ( false );
212
213 jTableHeader.addMouseListener (
214 new MouseAdapter ( )
215 {
216 public void mouseClicked ( MouseEvent mouseEvent )
217 {
218 handleSortColumn ( mouseEvent );
219 }
220 } );
221
222 jTable.addMouseListener (
223 new MouseAdapter ( )
224 {
225 public void mouseClicked ( MouseEvent mouseEvent )
226 {
227 handleRowSelection ( mouseEvent );
228 }
229 } );
230
231 jTable.setDefaultRenderer (
232 Object.class,
233 new AlternatingRenderer (
234 AgoracastConstants.SELECTED_FOREGROUND_COLOR,
235 AgoracastConstants.SELECTED_BACKGROUND_COLOR,
236 AgoracastConstants.ODD_FOREGROUND_COLOR,
237 AgoracastConstants.ODD_BACKGROUND_COLOR,
238 AgoracastConstants.EVEN_FOREGROUND_COLOR,
239 AgoracastConstants.EVEN_BACKGROUND_COLOR ) );
240
241 jTable.setRequestFocusEnabled ( false );
242
243 // Runs faster if unregistered.
244 // p717, Zukowski, "Definitive Guide to Swing for Java 2, 2nd Ed."
245
246 ToolTipManager.sharedInstance ( ).unregisterComponent ( jTable );
247
248 jScrollPane = new JScrollPane ( jTable );
249
250 add ( jScrollPane, BorderLayout.CENTER );
251
252 revalidate ( );
253 }
254
255 //////////////////////////////////////////////////////////////////////
256 // private methods
257 //////////////////////////////////////////////////////////////////////
258
259 private synchronized void handleRowSelection ( MouseEvent e )
260 //////////////////////////////////////////////////////////////////////
261 {
262 if ( e.getClickCount ( ) == 2 )
263 {
264 agoracastBrowsePanel.viewSource (
265 agoracastTableModel.getAgoracastData (
266 jTable.getSelectedRow ( ) ) );
267 }
268 }
269
270 /*********************************************************************
271 * See Robinson & Vorobiev, "Swing", 2000, p602.
272 *********************************************************************/
273 private synchronized void handleSortColumn ( MouseEvent e )
274 //////////////////////////////////////////////////////////////////////
275 {
276 TableColumnModel tableColumnModel = jTable.getColumnModel ( );
277
278 int columnModelIndex
279 = tableColumnModel.getColumnIndexAtX ( e.getX ( ) );
280
281 int modelIndex = tableColumnModel.getColumn (
282 columnModelIndex ).getModelIndex ( );
283
284 agoracastTableModel.sort ( modelIndex );
285 }
286
287 private synchronized void handleCategorySelection ( )
288 //////////////////////////////////////////////////////////////////////
289 {
290 category = ( String ) jComboBox.getSelectedItem ( );
291
292 if ( CATEGORY_ALL.equals ( category ) )
293 {
294 category = null;
295 }
296
297 AgoracastCategory agoracastCategory
298 = agoracastMediator.getAgoracastCategory ( category );
299
300 updateTable ( agoracastCategory.getColumnNames ( ) );
301 }
302
303 //////////////////////////////////////////////////////////////////////
304 //////////////////////////////////////////////////////////////////////
305 }