001 /* 002 * file BrowserDataModel.java 003 * 004 * Licensed Materials - Property of IBM 005 * Restricted Materials of IBM - you are allowed to copy, modify and 006 * redistribute this file as part of any program that interfaces with 007 * IBM Rational CM API. 008 * 009 * com.ibm.rational.stp.client.samples.BrowserDataModel 010 * 011 * © Copyright IBM Corporation 2004, 2008. All Rights Reserved. 012 * Note to U.S. Government Users Restricted Rights: Use, duplication or 013 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 014 */ 015 package com.ibm.rational.stp.client.samples; 016 017 import java.awt.BorderLayout; 018 import java.awt.FlowLayout; 019 import java.awt.Font; 020 import java.awt.event.ActionEvent; 021 import java.awt.event.ActionListener; 022 import java.awt.event.WindowAdapter; 023 import java.awt.event.WindowEvent; 024 import java.io.File; 025 import java.io.FileReader; 026 import java.util.Vector; 027 028 import javax.swing.JButton; 029 import javax.swing.JComboBox; 030 import javax.swing.JFrame; 031 import javax.swing.JOptionPane; 032 import javax.swing.JPanel; 033 import javax.swing.JScrollPane; 034 import javax.swing.JTable; 035 import javax.swing.JTextArea; 036 import javax.swing.ListSelectionModel; 037 import javax.swing.event.ListSelectionEvent; 038 import javax.swing.event.ListSelectionListener; 039 import javax.swing.plaf.basic.BasicBorders; 040 import javax.swing.table.AbstractTableModel; 041 import javax.wvcm.WvcmException; 042 043 /** 044 * An all-in-one class for displaying a table of browser data 045 */ 046 public abstract class BrowserDataModel 047 extends AbstractTableModel 048 { 049 /** 050 * Returns the object that is viewable at a given index in the table model 051 * 052 * @param index The index into the table model of the item to show 053 * 054 * @return null if the item is not viewable; otherwise an object that 055 * is viewable. 056 */ 057 abstract Object getViewable(int index); 058 059 /** 060 * Displays an object returned by getViewable 061 * 062 * @param viewable The object to display. 063 */ 064 abstract void show(Object viewable) throws WvcmException; 065 066 /** 067 * Displays the content of the object whose properties are displayed in 068 * this table. 069 * @throws Throwable If the content cannot be displayed. 070 */ 071 void showContent() throws Throwable {} 072 073 /** 074 * Returns the label to place on the Hide/Show Errors button 075 * @return If null or empty, the Hide/Show button is not displayed; 076 * otherwise the button will be displayed with the given label. 077 */ 078 String toggleErrorsLabel() { return ""; } 079 080 /** 081 * Rereads the data from the resource and redisplays it 082 * 083 * @throws WvcmException If problems arise during the process. 084 */ 085 void redisplay() throws WvcmException {} 086 087 /** 088 * Processes the Show/Hide Errors button when clicked. 089 * @throws WvcmException if the action cannot be carried out. 090 */ 091 void toggleErrors() throws WvcmException {} 092 093 /** 094 * A specification for the interface between the BrowserDataModel and a 095 * provider of operations to be applied to the object displayed in the 096 * model. 097 */ 098 interface Operations { 099 /** 100 * Returns a list of operations that can be applied to the object displayed 101 * by this data model. 102 * If not null, the list is placed in a combo-box from which the user 103 * may select and execute an operation. 104 * @return A list of possible operations for the resource. If null, no 105 * operations combo-box will be displayed. 106 */ 107 Vector getList(); 108 109 /** 110 * Performs the operation identified by the argument to the object displayed 111 * by this data model. 112 * @param op One of the operations supplied in the list returned by 113 * resourceOperations. 114 */ 115 void execute(Object op, BrowserDataModel model); 116 } 117 118 Operations getOperationsObject() { return null; } 119 120 /** 121 * Generates a display of this table. 122 * @param title The window title 123 * @param hasContent true if the ShowContent button should be displayed 124 */ 125 JFrame showModel( 126 String title, 127 boolean hasContent) 128 { 129 final JFrame frame = new JFrame(title); 130 // Comment this line when using Sun's TableSorter class 131 final JTable table = new JTable(this); 132 // Uncomment these lines when using Sun's TableSorter class 133 // final TableSorter sorter = (m_sorter = new TableSorter(this)); 134 // final JTable table = new JTable(sorter); 135 // 136 // sorter.setTableHeader(table.getTableHeader()); 137 // sorter.setSortingStatus(0, TableSorter.ASCENDING); 138 // 139 final JPanel panel = new JPanel(new BorderLayout()); 140 final JPanel subpanel = new JPanel(new FlowLayout()); 141 final JButton button = new JButton("View"); 142 143 subpanel.add(button, BorderLayout.SOUTH); 144 button.setEnabled(false); 145 button.addActionListener(new ActionListener() { 146 public void actionPerformed(ActionEvent arg0) 147 { 148 int[] selected = selectedRows(table); 149 150 for (int i = 0; i < selected.length; ++i) { 151 try { 152 show(getViewable(selected[i])); 153 } catch (WvcmException ex) { 154 JOptionPane.showMessageDialog(null, ex.getLocalizedMessage()); 155 } 156 } 157 } 158 }); 159 160 if (hasContent) { 161 JButton show = new JButton("Show Content"); 162 subpanel.add(show); 163 show.addActionListener(new ActionListener() { 164 public void actionPerformed(ActionEvent arg0) 165 { 166 try { 167 showContent(); 168 } catch (Throwable ex) { 169 JOptionPane.showMessageDialog(null, ex.getLocalizedMessage()); 170 } 171 } 172 }); 173 } 174 175 String label = toggleErrorsLabel(); 176 177 if (label.length() > 0) { 178 JButton show = new JButton(label); 179 subpanel.add(show); 180 show.addActionListener(new ActionListener() { 181 public void actionPerformed(ActionEvent arg0) 182 { 183 try { 184 toggleErrors(); 185 } catch (Throwable ex) { 186 JOptionPane.showMessageDialog(null, ex.getLocalizedMessage()); 187 } 188 } 189 }); 190 } 191 192 final Operations ops = getOperationsObject(); 193 194 if (ops != null) { 195 Vector list = ops.getList(); 196 197 if (list != null && !list.isEmpty()) { 198 final JComboBox box = new JComboBox(list); 199 JButton exec = new JButton("<<GO!"); 200 subpanel.add(box); 201 subpanel.add(exec); 202 exec.addActionListener(new ActionListener() { 203 public void actionPerformed(ActionEvent arg0) 204 { 205 ops.execute(box.getSelectedItem(), BrowserDataModel.this); 206 } 207 }); 208 } 209 } 210 211 JButton exit = new JButton("Exit"); 212 subpanel.add(exit); 213 exit.addActionListener(new ActionListener() { 214 public void actionPerformed(ActionEvent arg0) 215 { 216 System.exit(0); 217 } 218 }); 219 220 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 221 222 // Ask to be notified of selection changes. 223 ListSelectionModel rowSM = table.getSelectionModel(); 224 rowSM.addListSelectionListener(new ListSelectionListener() { 225 public void valueChanged(ListSelectionEvent e) 226 { 227 if (!e.getValueIsAdjusting()) { 228 int[] selected = selectedRows(table); 229 button.setEnabled(false); 230 231 for (int i = 0; i < selected.length; ++i) { 232 if (getViewable(selected[i]) != null) { 233 button.setEnabled(true); 234 235 break; 236 } 237 } 238 } 239 } 240 }); 241 242 panel.add(new JScrollPane(table), BorderLayout.CENTER); 243 panel.add(subpanel, BorderLayout.SOUTH); 244 frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 245 frame.setContentPane(panel); 246 frame.setBounds(lastX += 3, lastY += 3, 247 600, 17*(5 + table.getRowCount())); 248 frame.addWindowFocusListener(new WindowAdapter(){ 249 public void windowGainedFocus( 250 WindowEvent arg0) 251 { 252 super.windowGainedFocus(arg0); 253 lastX = arg0.getWindow().getX(); 254 lastY = arg0.getWindow().getY(); 255 } 256 }); 257 258 frame.setVisible(true); 259 260 return m_frame = frame; 261 } 262 263 /** 264 * Returns the rows of the table currently selected in the display 265 * @param table The table 266 * @return An int[] containing the index of each row that is highlighted 267 */ 268 int[] selectedRows(JTable table) 269 { 270 int[] selected = table.getSelectedRows(); 271 272 // Uncomment these lines when using Sun's TableSorter class 273 // for (int I = 0; I < selected.length; ++I) 274 // selected[I] = m_sorter.modelIndex(selected[I]); 275 // 276 277 return selected; 278 } 279 280 /** 281 * Displays the content of file in a window. 282 * @param title The title string to appear in the window banner 283 * @param file A File identifying the file whose content is to be displayed 284 * @return A JFrame for the displayed window. 285 * @throws Throwable If the content of the file cannot be displayed. 286 */ 287 static JFrame showFile( 288 String title, 289 File file) throws Throwable 290 { 291 JTextArea text = new JTextArea(680, 400); 292 FileReader reader = new FileReader(file); 293 char[] buf = new char[1000]; 294 int n; 295 296 while ((n=reader.read(buf)) > 0) { 297 text.append(new String(buf,0,n)); 298 } 299 300 reader.close(); 301 file.delete(); 302 303 text.setBorder(BasicBorders.getTextFieldBorder()); 304 text.setCaretPosition(0); 305 text.setFont(new Font("Monospaced", Font.PLAIN, 12)); 306 307 JFrame frame = new JFrame(title); 308 frame.setContentPane(new JScrollPane(text)); 309 frame.setBounds(lastX += 20, lastY += 40, 600, 300); 310 frame.setVisible(true); 311 312 return frame; 313 } 314 315 // Uncomment this line when using a TableSorter 316 // private TableSorter m_sorter; 317 // 318 319 /** The frame containing this data model */ 320 protected JFrame m_frame; 321 322 /** The X offset for the next window displayed */ 323 static int lastX = 180; 324 325 /** The Y offset for the next window displayed */ 326 static int lastY = 360; 327 }