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 }