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="https://www.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 }