source: trunk/gli/src/org/greenstone/gatherer/gui/MetadataValueTablePane.java@ 12119

Last change on this file since 12119 was 12119, checked in by kjdon, 18 years ago

Changed text handling to use Dictionary.get rather than Dictionary.setText or Dictionary.registerBoth etc. also removed mnemonics cos they suck for other languages

  • Property svn:keywords set to Author Date Id Revision
File size: 15.2 KB
Line 
1/**
2 *############################################################################
3 * A component of the Greenstone Librarian Interface, part of the Greenstone
4 * digital library suite from the New Zealand Digital Library Project at the
5 * University of Waikato, New Zealand.
6 *
7 * Author: Michael Dewsnip, NZDL Project, University of Waikato, NZ
8 *
9 * Copyright (C) 2005 New Zealand Digital Library Project
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *############################################################################
25 */
26
27package org.greenstone.gatherer.gui;
28
29
30import java.awt.*;
31import java.awt.event.*;
32import java.io.*;
33import javax.swing.*;
34import javax.swing.event.*;
35import javax.swing.table.*;
36import org.greenstone.gatherer.Configuration;
37import org.greenstone.gatherer.Dictionary;
38import org.greenstone.gatherer.collection.CollectionTreeNode;
39import org.greenstone.gatherer.metadata.MetadataChangedListener;
40import org.greenstone.gatherer.metadata.MetadataElement;
41import org.greenstone.gatherer.metadata.MetadataTools;
42import org.greenstone.gatherer.metadata.MetadataValue;
43import org.greenstone.gatherer.metadata.MetadataValueTableEntry;
44import org.greenstone.gatherer.metadata.MetadataValueTableModel;
45import org.greenstone.gatherer.metadata.MetadataXMLFileManager;
46import org.greenstone.gatherer.util.JarTools;
47import org.greenstone.gatherer.util.Utility;
48
49
50public class MetadataValueTablePane
51 extends JPanel
52{
53 private MetadataValueTable metadata_value_table = null;
54 /** Used to display either the MetadataValueTable (when files are selected) or a placeholder panel */
55 private CardLayout card_layout = null;
56 /** The name of the panel containing the metadata value table */
57 private String METADATA_VALUE_TABLE_CARD = "";
58 /** The name of the panel containing the "no metadata available" placeholder */
59 private String NO_METADATA_AVAILABLE_CARD = "No metadata available";
60 /** The name of the panel containing the "no files selected" placeholder */
61 private String NO_FILES_SELECTED_CARD = "No files selected";
62
63
64 public MetadataValueTablePane()
65 {
66 super();
67
68 metadata_value_table = new MetadataValueTable();
69
70 JScrollPane metadata_value_table_scroll = new JScrollPane(metadata_value_table);
71 metadata_value_table_scroll.getViewport().setBackground(Configuration.getColor("coloring.collection_tree_background", false));
72 metadata_value_table_scroll.setOpaque(true);
73
74 JPanel metadata_value_table_pane = new JPanel();
75 metadata_value_table_pane.setLayout(new BorderLayout());
76 metadata_value_table_pane.add(metadata_value_table_scroll, BorderLayout.CENTER);
77
78 JLabel no_metadata_available_label = new JLabel(Dictionary.get("EnrichPane.No_Metadata"));
79 no_metadata_available_label.setHorizontalAlignment(JLabel.CENTER);
80 no_metadata_available_label.setOpaque(false);
81 no_metadata_available_label.setVerticalAlignment(JLabel.CENTER);
82
83 JPanel no_metadata_available_pane = new JPanel();
84 no_metadata_available_pane.setLayout(new BorderLayout());
85 no_metadata_available_pane.add(no_metadata_available_label, BorderLayout.CENTER);
86
87 JLabel no_files_selected_label = new JLabel(Dictionary.get("EnrichPane.No_File"));
88 no_files_selected_label.setHorizontalAlignment(JLabel.CENTER);
89 no_files_selected_label.setOpaque(false);
90 no_files_selected_label.setVerticalAlignment(JLabel.CENTER);
91
92 JPanel no_files_selected_pane = new JPanel();
93 no_files_selected_pane.setLayout(new BorderLayout());
94 no_files_selected_pane.add(no_files_selected_label, BorderLayout.CENTER);
95
96 card_layout = new CardLayout();
97
98 this.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
99 this.setFont(Configuration.getFont("general.font", false));
100 this.setLayout(card_layout);
101 this.add(metadata_value_table_pane, METADATA_VALUE_TABLE_CARD);
102 this.add(no_metadata_available_pane, NO_METADATA_AVAILABLE_CARD);
103 this.add(no_files_selected_pane, NO_FILES_SELECTED_CARD);
104 }
105
106
107 public void addMetadataValueTableListSelectionListener(ListSelectionListener list_selection_listener)
108 {
109 metadata_value_table.getSelectionModel().addListSelectionListener(list_selection_listener);
110 }
111
112
113 public void addMetadataValueTableMouseListener(MouseListener mouse_listener)
114 {
115 metadata_value_table.addMouseListener(mouse_listener);
116 }
117
118
119 public void addMetadataValueTextFieldDocumentListener(DocumentListener document_listener)
120 {
121 metadata_value_table.getMetadataValueTextField().getDocument().addDocumentListener(document_listener);
122 }
123
124
125 public void addMetadataValueTextFieldKeyListener(KeyListener key_listener)
126 {
127 metadata_value_table.getMetadataValueTextField().addKeyListener(key_listener);
128 }
129
130
131 public MetadataValueTableEntry getSelectedMetadataValueTableEntry()
132 {
133 return metadata_value_table.getSelectedMetadataValueTableEntry();
134 }
135
136
137 public boolean isMouseEventForInheritedMetadataValueTableColumn(MouseEvent mouse_event)
138 {
139 return metadata_value_table.isMouseEventForInheritedMetadataValueTableColumn(mouse_event);
140 }
141
142
143 public void setMetadataValueTextFieldValue(String metadata_value_string)
144 {
145 metadata_value_table.setMetadataValueTextFieldValue(metadata_value_string);
146 }
147
148
149 public void stopEditingAndAddBlankRowForSelectedMetadataElement()
150 {
151 metadata_value_table.stopEditing();
152 metadata_value_table.addBlankRowForSelectedMetadataElement();
153 }
154
155
156 public void stopEditingAndRebuild(CollectionTreeNode[] file_nodes)
157 {
158 metadata_value_table.stopEditing();
159 metadata_value_table.rebuild(file_nodes);
160
161 // If no files are selected display the "no file selected" card
162 if (file_nodes == null) {
163 card_layout.show(this, NO_FILES_SELECTED_CARD);
164 }
165 // If the metadata value table is empty display the "no metadata available" card
166 else if (metadata_value_table.getRowCount() == 0) {
167 card_layout.show(this, NO_METADATA_AVAILABLE_CARD);
168 }
169 // Otherwise display the card with the metadata value table
170 else {
171 card_layout.show(this, METADATA_VALUE_TABLE_CARD);
172 }
173 }
174
175
176 private class MetadataValueTable
177 extends JTable
178 implements MetadataChangedListener
179 {
180 private int MINIMUM_TABLE_HEADER_SIZE = 15;
181
182 private MetadataValueTableModel metadata_value_table_model = null;
183 private JTextField metadata_value_text_field = new JTextField();
184
185
186 public MetadataValueTable()
187 {
188 // Create the model for the table
189 metadata_value_table_model = new MetadataValueTableModel();
190 setModel(metadata_value_table_model);
191
192 // We allow only one row in the table to be selected at a time
193 setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
194
195 // We use our own editor for the value column so we have easy access to the underlying text field
196 setDefaultEditor(String.class, new DefaultCellEditor(metadata_value_text_field));
197
198 // We need to listen for double clicks on the text field to open the editor dialog
199 metadata_value_text_field.addMouseListener(new MetadataValueTextFieldMouseListener());
200 metadata_value_text_field.setBorder(null);
201
202 // We need to listen for key presses so we can catch Enter presses
203 addKeyListener(new MetadataValueTableKeyListener());
204
205 // We need to listen for metadata changes so we can rebuild the table
206 MetadataXMLFileManager.addMetadataChangedListener(this);
207
208 // We also have to ensure that the table column header hasn't gone on a severe Jenny Craig binge and has somehow lost 7/8th of its component size
209 JTableHeader table_header = getTableHeader();
210 Dimension table_header_preferred_size = table_header.getPreferredSize();
211 if (table_header_preferred_size.height < MINIMUM_TABLE_HEADER_SIZE) {
212 table_header_preferred_size.setSize(table_header_preferred_size.width, MINIMUM_TABLE_HEADER_SIZE);
213 table_header.setPreferredSize(table_header_preferred_size);
214 }
215
216 // Set the size of the table columns: 2/7 for element, 5/7 for value (actual numbers don't matter)
217 TableColumnModel column_model = getColumnModel();
218 TableColumn inherited_column = column_model.getColumn(0);
219 inherited_column.setMinWidth(25);
220 inherited_column.setPreferredWidth(25);
221 inherited_column.setMaxWidth(25);
222 TableColumn element_column = column_model.getColumn(1);
223 element_column.setPreferredWidth(200);
224 TableColumn value_column = column_model.getColumn(2);
225 value_column.setPreferredWidth(500);
226
227 // Use our own renderer for the table cells
228 MetadataValueTableCellRenderer metadata_value_table_cell_renderer = new MetadataValueTableCellRenderer();
229 inherited_column.setCellRenderer(metadata_value_table_cell_renderer);
230 element_column.setCellRenderer(metadata_value_table_cell_renderer);
231 value_column.setCellRenderer(metadata_value_table_cell_renderer);
232 }
233
234
235 private void addBlankRowForSelectedMetadataElement()
236 {
237 // Add a blank entry for the selected metadata element, then switch to it
238 MetadataElement selected_metadata_element = getSelectedMetadataValueTableEntry().getMetadataElement();
239 int blank_row = metadata_value_table_model.addBlankRowForMetadataElement(selected_metadata_element);
240 changeSelection(blank_row, 2, false, false);
241 }
242
243
244 private JTextField getMetadataValueTextField()
245 {
246 return metadata_value_text_field;
247 }
248
249
250 private MetadataValueTableEntry getSelectedMetadataValueTableEntry()
251 {
252 return metadata_value_table_model.getMetadataValueTableEntry(getSelectedRow());
253 }
254
255
256 private boolean isMouseEventForInheritedMetadataValueTableColumn(MouseEvent mouse_event)
257 {
258 return (columnAtPoint(mouse_event.getPoint()) == 0);
259 }
260
261
262 public void metadataChanged(CollectionTreeNode[] file_nodes)
263 {
264 rebuild(file_nodes);
265 }
266
267
268 private void rebuild(CollectionTreeNode[] file_nodes)
269 {
270 // Note the metadata value table entry currently selected
271 MetadataValueTableEntry selected_metadata_value_table_entry = getSelectedMetadataValueTableEntry();
272
273 // We don't want a lot of ListSelectionEvents while the table is rebuilding
274 clearSelection();
275
276 // Rebuild the metadata value table model
277 metadata_value_table_model.rebuild(file_nodes);
278
279 // Restore the metadata value table entry selection
280 if (selected_metadata_value_table_entry != null) {
281 int row_to_select = metadata_value_table_model.findMetadataValueTableEntryToSelect(selected_metadata_value_table_entry);
282 changeSelection(row_to_select, 2, false, false);
283 }
284 }
285
286
287 private void setMetadataValueTextFieldValue(String metadata_value_string)
288 {
289 metadata_value_text_field.setText(metadata_value_string);
290 metadata_value_text_field.requestFocus();
291 }
292
293
294 private void stopEditing()
295 {
296 // Save the current value in the text field, then remove the editor so it doesn't get saved again
297 TableCellEditor table_cell_editor = getCellEditor();
298 if (table_cell_editor != null) {
299 Object new_metadata_value = table_cell_editor.getCellEditorValue();
300 setValueAt(new_metadata_value, editingRow, editingColumn);
301 removeEditor();
302 }
303 }
304
305
306 private class MetadataValueTableCellRenderer
307 extends DefaultTableCellRenderer
308 {
309 /** Returns the default table cell renderer.
310 * @param table The <strong>JTable</strong>.
311 * @param value The value to assign to the cell at [row, column] as an <strong>Object</strong>.
312 * @param isSelected <i>true</i> if cell is selected.
313 * @param hasFocus <i>true</i> if cell has focus.
314 * @param row The row of the cell to render as an <i>int</i>.
315 * @param column The column of the cell to render as an <i>int</i>.
316 * @return The default table cell renderer <strong>Component</strong>.
317 */
318 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
319 {
320 JComponent component = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
321
322 int real_column = table.convertColumnIndexToModel(column);
323 // First column: inherited metadata icon
324 if (real_column == 0 && value != null) {
325 component = new JLabel(JarTools.getImage("upfolder.gif"));
326 }
327
328 // Make sure the focus always stay in the value cell of the selected row
329 if (real_column == 2 && isSelected) {
330 table.editCellAt(row, column);
331 if (table.isEditing()) {
332 table.getEditorComponent().requestFocus();
333 }
334 }
335
336 // Set up the component
337 component.setOpaque(true);
338
339 // Foreground
340 if (metadata_value_table_model.isCommon(row)) {
341 component.setForeground(Color.black);
342 }
343 else {
344 component.setForeground(Color.gray);
345 }
346
347 // Background
348 if (isSelected) {
349 component.setBackground(Configuration.getColor("coloring.workspace_heading_background", true));
350 }
351 else {
352 if (real_column < 2) {
353 component.setBackground(Configuration.getColor("coloring.collection_heading_background", true));
354 }
355 else {
356 component.setBackground(Configuration.getColor("coloring.collection_tree_background", true));
357 }
358 }
359
360 // The value column of cells never paints focus
361 if (real_column == 2) {
362 component.setBorder(BorderFactory.createEmptyBorder(0,2,0,0));
363 }
364
365 // We set a tooltip over the element column containing the definition of the element
366 if (value instanceof MetadataElement) {
367 String interface_language_code = Configuration.getLanguage();
368 String metadata_element_definition = MetadataTools.getMetadataElementAttribute((MetadataElement) value, "definition", interface_language_code, "en");
369 if (metadata_element_definition != null) {
370 component.setToolTipText(Utility.formatHTMLWidth(metadata_element_definition, 60));
371 }
372 }
373
374 return component;
375 }
376 }
377
378
379 private class MetadataValueTableKeyListener
380 extends KeyAdapter
381 {
382 /** Gives notification of key events on the text field */
383 public void keyPressed(KeyEvent key_event)
384 {
385 // Enter: save the current value then add a blank row for the selected metadata element
386 if (key_event.getKeyCode() == KeyEvent.VK_ENTER) {
387 // ...but not for extracted metadata elements of course
388 MetadataValueTableEntry metadata_value_table_entry = getSelectedMetadataValueTableEntry();
389 if (!metadata_value_table_entry.getMetadataElement().isExtractedMetadataElement()) {
390 addBlankRowForSelectedMetadataElement();
391 }
392
393 // We do not want this event to be processed by the table also
394 key_event.consume();
395 }
396 }
397 }
398
399
400 private class MetadataValueTextFieldMouseListener
401 extends MouseAdapter
402 {
403 public void mouseClicked(MouseEvent mouse_event)
404 {
405 // Double-click: pop up an editor dialog for large metadata values
406 if (mouse_event.getClickCount() == 2) {
407 EditorDialog editor_dialog = new EditorDialog();
408 String new_metadata_value_string = editor_dialog.display(metadata_value_text_field.getText());
409 if (new_metadata_value_string != null) {
410 setMetadataValueTextFieldValue(new_metadata_value_string);
411 }
412 }
413 }
414 }
415 }
416}
Note: See TracBrowser for help on using the repository browser.