KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > console > views > InfoViewer


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2004 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: c-jdbc@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Emmanuel Cecchet.
22  * Contributor(s): Mathieu Peltier.
23  */

24
25 package org.objectweb.cjdbc.console.views;
26
27 import java.awt.Dimension JavaDoc;
28 import java.awt.GridLayout JavaDoc;
29 import java.awt.event.ActionEvent JavaDoc;
30 import java.io.File JavaDoc;
31 import java.io.FileOutputStream JavaDoc;
32 import java.io.PrintStream JavaDoc;
33
34 import javax.swing.AbstractAction JavaDoc;
35 import javax.swing.JFileChooser JavaDoc;
36 import javax.swing.JFrame JavaDoc;
37 import javax.swing.JMenu JavaDoc;
38 import javax.swing.JMenuBar JavaDoc;
39 import javax.swing.JMenuItem JavaDoc;
40 import javax.swing.JOptionPane JavaDoc;
41 import javax.swing.JPanel JavaDoc;
42 import javax.swing.JScrollPane JavaDoc;
43 import javax.swing.JTable JavaDoc;
44 import javax.swing.KeyStroke JavaDoc;
45 import javax.swing.WindowConstants JavaDoc;
46 import javax.swing.table.AbstractTableModel JavaDoc;
47
48 import org.objectweb.cjdbc.common.i18n.Translate;
49
50 /**
51  * Graphical SQL statistics viewer. Quick and dirty implementation.
52  *
53  * @author <a HREF="mailto:Mathieu.Peltier@inrialpes.fr">Mathieu Peltier </a>
54  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
55  * @version 1.0
56  */

57 public abstract class InfoViewer
58 {
59
60   private InfoTableSorter sorter;
61   private JPanel JavaDoc panel;
62   private JFrame JavaDoc frame;
63   private InfoTableModel model;
64
65   // Info Options
66
private String JavaDoc[] columnNames;
67   protected String JavaDoc frameTitle;
68   protected String JavaDoc infoViewerMenuBarString;
69   protected String JavaDoc actionToolTipText;
70   protected String JavaDoc actionErrorMessage;
71   protected String JavaDoc actionSuccessMessage;
72   protected String JavaDoc tableHeaderToolTipText;
73
74   private Object JavaDoc[][] data;
75
76   /**
77    * Create a InfoViewer
78    *
79    * @param data Stats to display in the table
80    */

81   public InfoViewer(Object JavaDoc[][] data)
82   {
83     if (data != null)
84     {
85       this.data = getDataTypes(data);
86       columnNames = getColumnNames();
87       setLabels();
88     }
89   }
90
91   /**
92    * Subclasses should overide this method to get coherent sorting
93    *
94    * @param stats to display
95    * @return same sized objects array but with proper types default is strings
96    * only
97    */

98   protected abstract Object JavaDoc[][] getDataTypes(Object JavaDoc[][] stats);
99
100   /**
101    * Get column names
102    *
103    * @return a array of strings
104    */

105   public abstract String JavaDoc[] getColumnNames();
106
107   /**
108    * Return the list of traceable data for this viewer
109    *
110    * @return an array of names
111    */

112   public int[] getTraceableColumns()
113   {
114     return new int[0];
115   }
116
117   /**
118    * Set the labels for the frame
119    */

120   public abstract void setLabels();
121
122   /**
123    * Update the data in the InfoTableModel and refresh the frame
124    *
125    * @param data fresh and new
126    */

127   public void updateData(Object JavaDoc[][] data)
128   {
129     this.data = getDataTypes(data);
130     if (frame != null)
131     {
132       frame.repaint();
133       frame.setVisible(true);
134       model.setData(data);
135     }
136     else
137     {
138       createAndShowGUI();
139     }
140   }
141
142   /**
143    * For thread safety, this method should be invoked from the event-dispatching
144    * thread.
145    */

146   private void createAndShowGUI()
147   {
148     panel = new JPanel JavaDoc(new GridLayout JavaDoc(1, 0));
149     model = new InfoTableModel(data);
150
151     sorter = new InfoTableSorter(model);
152     JTable JavaDoc table = new JTable JavaDoc(sorter); //NEW
153
sorter.addMouseListenerToHeaderInTable(table); //ADDED
154
// THIS
155
table.setPreferredScrollableViewportSize(new Dimension JavaDoc(640, 200));
156     table.getColumnModel().getColumn(0).setPreferredWidth(340);
157     for (int i = 1; i < columnNames.length; i++)
158       table.getColumnModel().getColumn(i).setPreferredWidth(50);
159
160     //Set up tool tips for column headers.
161
table.getTableHeader().setToolTipText(tableHeaderToolTipText);
162
163     //Create the scroll pane and add the table to it.
164
JScrollPane JavaDoc scrollPane = new JScrollPane JavaDoc(table);
165
166     //Add the scroll pane to this panel.
167
panel.add(scrollPane);
168
169     //Create and set up the window.
170
frame = new JFrame JavaDoc(frameTitle);
171     frame.setJMenuBar(new InfoViewerMenuBar());
172     frame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
173     panel.setOpaque(true); // content panes must be opaque
174
frame.setContentPane(panel);
175
176     //Display the window.
177
frame.pack();
178     frame.setVisible(true);
179   }
180
181   /**
182    * Display text. This allows to show text without loading graphic contents
183    *
184    * @param data to display
185    * @return a formatted <code>String</code>
186    */

187   public String JavaDoc displayText(Object JavaDoc[][] data)
188   {
189     this.data = getDataTypes(data);
190     columnNames = getColumnNames();
191     setLabels();
192     return displayText(getDataTypes(data));
193   }
194
195   /**
196    * Format data for text consoles
197    *
198    * @param data to display
199    * @return a formatted string with tabs and end of line
200    */

201   public String JavaDoc displayText(String JavaDoc[][] data)
202   {
203     if (data == null)
204     {
205       return "";
206     }
207
208     /* Lasse's version starts here */
209
210     // constants used for formatting the output
211
final String JavaDoc columnPadding = " ";
212     final String JavaDoc nameValueSeparator = ": ";
213
214     // holds the column names
215
String JavaDoc[] columns = getColumnNames();
216
217     // solve the maximum length for column names
218
// TODO: refactor this into its own method
219
int maxNameLength = 0;
220     for (int i = 0; i < columns.length; i++)
221     {
222       maxNameLength = Math.max(maxNameLength, columns[i].length());
223     }
224
225     // solve the maximum length for column values
226
// TODO: refactor this into its own method
227
int maxValueLength = 0;
228     for (int i = 0; i < data.length; i++)
229     {
230       for (int j = 0; j < data[i].length; j++)
231       {
232         maxValueLength = Math.max(maxValueLength, data[i][j].length());
233       }
234     }
235
236     // construct a separator line based on maximum column and value lengths
237
// TODO: extract numbers into constants and this block into a new method
238
char[] separator = new char[columnPadding.length() + maxNameLength
239         + nameValueSeparator.length() + maxValueLength + 1]; /*
240                                                               * the newline
241                                                               * character
242                                                               */

243     for (int i = 0; i < separator.length; i++)
244     {
245       separator[i] = '-';
246     }
247     separator[separator.length - 1] = '\n';
248
249     // loop through all the data and print padded lines into the StringBuffer
250
StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
251     for (int i = 0; i < data.length; i++)
252     {
253       sb.append(separator);
254       for (int j = 0; j < data[i].length; j++)
255       {
256         // create the padding needed for this particular column
257
// TODO: extract this into its own method
258
char[] namePadding = new char[maxNameLength - columns[j].length()];
259         for (int x = 0; x < namePadding.length; x++)
260         {
261           namePadding[x] = ' ';
262         }
263
264         sb.append(columnPadding);
265         sb.append(columns[j]);
266         sb.append(nameValueSeparator);
267         sb.append(namePadding);
268         sb.append(data[i][j]);
269         sb.append("\n");
270       }
271       if (i + 1 == data.length)
272       {
273         sb.append(separator);
274       }
275     }
276     return sb.toString();
277   }
278
279   /**
280    * Create the GUI and show it.
281    */

282   public void display()
283   {
284     //Schedule a job for the event-dispatching thread:
285
//creating and showing this application's GUI.
286
javax.swing.SwingUtilities.invokeLater(new Runnable JavaDoc()
287     {
288       public void run()
289       {
290         createAndShowGUI();
291       }
292     });
293   }
294
295   /** <code>SQLStatViewer</code> menu bar. */
296   protected final class InfoViewerMenuBar extends JMenuBar JavaDoc
297   {
298
299     /** Creates an new <code>SQLStatViewerMenuBar</code> menu bar. */
300     private InfoViewerMenuBar()
301     {
302       JMenu JavaDoc menu = new JMenu JavaDoc(infoViewerMenuBarString);
303       JMenuItem JavaDoc menuItem = new JMenuItem JavaDoc(new ExportAction());
304       menuItem.setText("Save As...");
305       menuItem.setMnemonic('S');
306       menuItem.setAccelerator(KeyStroke
307           .getKeyStroke('s', ActionEvent.CTRL_MASK));
308       menu.add(menuItem);
309       add(menu);
310     }
311   }
312
313   /** <code>InfoViewer</code> export action. */
314   protected class ExportAction extends AbstractAction JavaDoc
315   {
316
317     protected static final String JavaDoc SEPARATOR = "\t";
318     protected File JavaDoc outputFile;
319
320     /**
321      * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
322      */

323     public void actionPerformed(ActionEvent JavaDoc e)
324     {
325       // Open file
326
JFileChooser JavaDoc chooser = new JFileChooser JavaDoc(outputFile);
327       chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
328       chooser.setApproveButtonText("Export");
329       chooser.setApproveButtonMnemonic('s');
330       chooser.setApproveButtonToolTipText(actionToolTipText);
331       chooser.setDialogTitle("Choose the file name");
332
333       if (chooser.showSaveDialog(frame) == JFileChooser.APPROVE_OPTION)
334       {
335         outputFile = chooser.getSelectedFile();
336         if (outputFile != null)
337         {
338           // Export data
339
try
340           {
341             PrintStream JavaDoc out = new PrintStream JavaDoc(new FileOutputStream JavaDoc(outputFile));
342             int columnNumber, rowNumber;
343             columnNumber = sorter.getColumnCount();
344             rowNumber = sorter.getRowCount();
345             for (int i = 0; i < rowNumber; i++)
346             {
347               for (int j = 0; j < columnNumber; j++)
348               {
349                 out.print(sorter.getValueAt(i, j));
350                 out.print(SEPARATOR);
351               }
352               out.println();
353             }
354             out.close();
355           }
356           catch (Exception JavaDoc ex)
357           {
358             JOptionPane.showMessageDialog(frame, Translate.get(
359                 actionErrorMessage, ex), "Unexpected Error",
360                 JOptionPane.ERROR_MESSAGE);
361             return;
362           }
363           JOptionPane.showMessageDialog(frame, Translate.get(
364               actionSuccessMessage, outputFile), "Action Performed",
365               JOptionPane.INFORMATION_MESSAGE);
366         }
367       }
368     }
369   }
370
371   /**
372    * This class defines a InfoTableModel
373    *
374    * @version 1.0
375    */

376   class InfoTableModel extends AbstractTableModel JavaDoc
377   {
378     private Object JavaDoc[][] data;
379
380     /**
381      * Creates a new <code>InfoTableModel</code> object
382      *
383      * @param stats <code>Object[][]</code> instance with data
384      */

385     public InfoTableModel(Object JavaDoc[][] stats)
386     {
387       this.data = stats;
388     }
389
390     /**
391      * Set the data of this <tt>InfoTableModel</tt>
392      *
393      * @param data <code>Object[][]</code> instance with data
394      */

395     public void setData(Object JavaDoc[][] data)
396     {
397       this.data = data;
398     }
399
400     /**
401      * @see javax.swing.table.TableModel#getColumnCount()
402      */

403     public int getColumnCount()
404     {
405       return columnNames.length;
406     }
407
408     /**
409      * @see javax.swing.table.TableModel#getRowCount()
410      */

411     public int getRowCount()
412     {
413       return data.length;
414     }
415
416     /**
417      * @see javax.swing.table.TableModel#getColumnName(int)
418      */

419     public String JavaDoc getColumnName(int col)
420     {
421       return columnNames[col];
422     }
423
424     /**
425      * @see javax.swing.table.TableModel#getValueAt(int, int)
426      */

427     public Object JavaDoc getValueAt(int row, int col)
428     {
429       return data[row][col];
430     }
431
432     /**
433      * JTable uses this method to determine the default renderer/ editor for
434      * each cell. If we didn't implement this method, then the last column would
435      * contain text ("true"/"false"), rather than a check box.
436      */

437     public Class JavaDoc getColumnClass(int c)
438     {
439       return getValueAt(0, c).getClass();
440     }
441
442     /**
443      * Don't need to implement this method unless your table's editable.
444      */

445     public boolean isCellEditable(int row, int col)
446     {
447       return false;
448     }
449   }
450
451   /**
452    * @return Returns the frameTitle.
453    */

454   public String JavaDoc getFrameTitle()
455   {
456     return frameTitle;
457   }
458
459   /**
460    * @return Returns the data.
461    */

462   public Object JavaDoc[][] getData()
463   {
464     return data;
465   }
466 }
Popular Tags