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

Last change on this file since 10593 was 10593, checked in by mdewsnip, 19 years ago

The text field when editing metadata values on Windows had a border which was hiding a small part of the text -- this border has been removed.

  • Property svn:keywords set to Author Date Id Revision
File size: 15.2 KB
RevLine 
[9856]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;
[10011]46import org.greenstone.gatherer.util.JarTools;
[9856]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();
79 no_metadata_available_label.setHorizontalAlignment(JLabel.CENTER);
80 no_metadata_available_label.setOpaque(false);
81 no_metadata_available_label.setVerticalAlignment(JLabel.CENTER);
82 Dictionary.registerText(no_metadata_available_label, "EnrichPane.No_Metadata");
83
84 JPanel no_metadata_available_pane = new JPanel();
85 no_metadata_available_pane.setLayout(new BorderLayout());
86 no_metadata_available_pane.add(no_metadata_available_label, BorderLayout.CENTER);
87
88 JLabel no_files_selected_label = new JLabel();
89 no_files_selected_label.setHorizontalAlignment(JLabel.CENTER);
90 no_files_selected_label.setOpaque(false);
91 no_files_selected_label.setVerticalAlignment(JLabel.CENTER);
92 Dictionary.registerText(no_files_selected_label, "EnrichPane.No_File");
93
94 JPanel no_files_selected_pane = new JPanel();
95 no_files_selected_pane.setLayout(new BorderLayout());
96 no_files_selected_pane.add(no_files_selected_label, BorderLayout.CENTER);
97
98 card_layout = new CardLayout();
99
100 this.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
101 this.setFont(Configuration.getFont("general.font", false));
102 this.setLayout(card_layout);
103 this.add(metadata_value_table_pane, METADATA_VALUE_TABLE_CARD);
104 this.add(no_metadata_available_pane, NO_METADATA_AVAILABLE_CARD);
105 this.add(no_files_selected_pane, NO_FILES_SELECTED_CARD);
106 }
107
108
109 public void addMetadataValueTableListSelectionListener(ListSelectionListener list_selection_listener)
110 {
111 metadata_value_table.getSelectionModel().addListSelectionListener(list_selection_listener);
112 }
113
114
115 public void addMetadataValueTableMouseListener(MouseListener mouse_listener)
116 {
117 metadata_value_table.addMouseListener(mouse_listener);
118 }
119
120
121 public void addMetadataValueTextFieldDocumentListener(DocumentListener document_listener)
122 {
123 metadata_value_table.getMetadataValueTextField().getDocument().addDocumentListener(document_listener);
124 }
125
126
127 public void addMetadataValueTextFieldKeyListener(KeyListener key_listener)
128 {
129 metadata_value_table.getMetadataValueTextField().addKeyListener(key_listener);
130 }
131
132
133 public MetadataValueTableEntry getSelectedMetadataValueTableEntry()
134 {
135 return metadata_value_table.getSelectedMetadataValueTableEntry();
136 }
137
138
139 public boolean isMouseEventForInheritedMetadataValueTableColumn(MouseEvent mouse_event)
140 {
141 return metadata_value_table.isMouseEventForInheritedMetadataValueTableColumn(mouse_event);
142 }
143
144
145 public void setMetadataValueTextFieldValue(String metadata_value_string)
146 {
147 metadata_value_table.setMetadataValueTextFieldValue(metadata_value_string);
148 }
149
150
151 public void stopEditingAndAddBlankRowForSelectedMetadataElement()
152 {
153 metadata_value_table.stopEditing();
154 metadata_value_table.addBlankRowForSelectedMetadataElement();
155 }
156
157
158 public void stopEditingAndRebuild(CollectionTreeNode[] file_nodes)
159 {
160 metadata_value_table.stopEditing();
161 metadata_value_table.rebuild(file_nodes);
162
163 // If no files are selected display the "no file selected" card
164 if (file_nodes == null) {
165 card_layout.show(this, NO_FILES_SELECTED_CARD);
166 }
167 // If the metadata value table is empty display the "no metadata available" card
168 else if (metadata_value_table.getRowCount() == 0) {
169 card_layout.show(this, NO_METADATA_AVAILABLE_CARD);
170 }
171 // Otherwise display the card with the metadata value table
172 else {
173 card_layout.show(this, METADATA_VALUE_TABLE_CARD);
174 }
175 }
176
177
178 private class MetadataValueTable
179 extends JTable
180 implements MetadataChangedListener
181 {
182 private int MINIMUM_TABLE_HEADER_SIZE = 15;
183
184 private MetadataValueTableModel metadata_value_table_model = null;
185 private JTextField metadata_value_text_field = new JTextField();
186
187
188 public MetadataValueTable()
189 {
190 // Create the model for the table
191 metadata_value_table_model = new MetadataValueTableModel();
192 setModel(metadata_value_table_model);
193
194 // We allow only one row in the table to be selected at a time
195 setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
196
197 // We use our own editor for the value column so we have easy access to the underlying text field
198 setDefaultEditor(String.class, new DefaultCellEditor(metadata_value_text_field));
199
200 // We need to listen for double clicks on the text field to open the editor dialog
201 metadata_value_text_field.addMouseListener(new MetadataValueTextFieldMouseListener());
[10593]202 metadata_value_text_field.setBorder(null);
[9856]203
204 // We need to listen for key presses so we can catch Enter presses
205 addKeyListener(new MetadataValueTableKeyListener());
206
207 // We need to listen for metadata changes so we can rebuild the table
208 MetadataXMLFileManager.addMetadataChangedListener(this);
209
210 // 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
211 JTableHeader table_header = getTableHeader();
212 Dimension table_header_preferred_size = table_header.getPreferredSize();
213 if (table_header_preferred_size.height < MINIMUM_TABLE_HEADER_SIZE) {
214 table_header_preferred_size.setSize(table_header_preferred_size.width, MINIMUM_TABLE_HEADER_SIZE);
215 table_header.setPreferredSize(table_header_preferred_size);
216 }
217
218 // Set the size of the table columns: 2/7 for element, 5/7 for value (actual numbers don't matter)
219 TableColumnModel column_model = getColumnModel();
220 TableColumn inherited_column = column_model.getColumn(0);
221 inherited_column.setMinWidth(25);
222 inherited_column.setPreferredWidth(25);
223 inherited_column.setMaxWidth(25);
224 TableColumn element_column = column_model.getColumn(1);
225 element_column.setPreferredWidth(200);
226 TableColumn value_column = column_model.getColumn(2);
227 value_column.setPreferredWidth(500);
228
229 // Use our own renderer for the table cells
230 MetadataValueTableCellRenderer metadata_value_table_cell_renderer = new MetadataValueTableCellRenderer();
231 inherited_column.setCellRenderer(metadata_value_table_cell_renderer);
232 element_column.setCellRenderer(metadata_value_table_cell_renderer);
233 value_column.setCellRenderer(metadata_value_table_cell_renderer);
234 }
235
236
237 private void addBlankRowForSelectedMetadataElement()
238 {
239 // Add a blank entry for the selected metadata element, then switch to it
240 MetadataElement selected_metadata_element = getSelectedMetadataValueTableEntry().getMetadataElement();
241 int blank_row = metadata_value_table_model.addBlankRowForMetadataElement(selected_metadata_element);
242 changeSelection(blank_row, 2, false, false);
243 }
244
245
246 private JTextField getMetadataValueTextField()
247 {
248 return metadata_value_text_field;
249 }
250
251
252 private MetadataValueTableEntry getSelectedMetadataValueTableEntry()
253 {
254 return metadata_value_table_model.getMetadataValueTableEntry(getSelectedRow());
255 }
256
257
258 private boolean isMouseEventForInheritedMetadataValueTableColumn(MouseEvent mouse_event)
259 {
260 return (columnAtPoint(mouse_event.getPoint()) == 0);
261 }
262
263
264 public void metadataChanged(CollectionTreeNode[] file_nodes)
265 {
266 rebuild(file_nodes);
267 }
268
269
270 private void rebuild(CollectionTreeNode[] file_nodes)
271 {
272 // Note the metadata value table entry currently selected
273 MetadataValueTableEntry selected_metadata_value_table_entry = getSelectedMetadataValueTableEntry();
274
275 // We don't want a lot of ListSelectionEvents while the table is rebuilding
276 clearSelection();
277
278 // Rebuild the metadata value table model
279 metadata_value_table_model.rebuild(file_nodes);
280
281 // Restore the metadata value table entry selection
282 if (selected_metadata_value_table_entry != null) {
283 int row_to_select = metadata_value_table_model.findMetadataValueTableEntryToSelect(selected_metadata_value_table_entry);
284 changeSelection(row_to_select, 2, false, false);
285 }
286 }
287
288
289 private void setMetadataValueTextFieldValue(String metadata_value_string)
290 {
291 metadata_value_text_field.setText(metadata_value_string);
292 metadata_value_text_field.requestFocus();
293 }
294
295
296 private void stopEditing()
297 {
298 // Save the current value in the text field, then remove the editor so it doesn't get saved again
299 TableCellEditor table_cell_editor = getCellEditor();
300 if (table_cell_editor != null) {
301 Object new_metadata_value = table_cell_editor.getCellEditorValue();
302 setValueAt(new_metadata_value, editingRow, editingColumn);
303 removeEditor();
304 }
305 }
306
307
308 private class MetadataValueTableCellRenderer
309 extends DefaultTableCellRenderer
310 {
311 /** Returns the default table cell renderer.
312 * @param table The <strong>JTable</strong>.
313 * @param value The value to assign to the cell at [row, column] as an <strong>Object</strong>.
314 * @param isSelected <i>true</i> if cell is selected.
315 * @param hasFocus <i>true</i> if cell has focus.
316 * @param row The row of the cell to render as an <i>int</i>.
317 * @param column The column of the cell to render as an <i>int</i>.
318 * @return The default table cell renderer <strong>Component</strong>.
319 */
320 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
321 {
322 JComponent component = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
323
324 // First column: inherited metadata icon
325 if (column == 0 && value != null) {
[10011]326 component = new JLabel(JarTools.getImage("upfolder.gif"));
[9856]327 }
328
329 // Make sure the focus always stay in the value cell of the selected row
330 if (column == 2 && isSelected) {
331 table.editCellAt(row, column);
332 if (table.isEditing()) {
333 table.getEditorComponent().requestFocus();
334 }
335 }
336
337 // Set up the component
338 component.setOpaque(true);
339
340 // Foreground
341 if (metadata_value_table_model.isCommon(row)) {
342 component.setForeground(Color.black);
343 }
344 else {
345 component.setForeground(Color.gray);
346 }
347
348 // Background
349 if (isSelected) {
350 component.setBackground(Configuration.getColor("coloring.workspace_heading_background", true));
351 }
352 else {
353 if (column < 2) {
354 component.setBackground(Configuration.getColor("coloring.collection_heading_background", true));
355 }
356 else {
357 component.setBackground(Configuration.getColor("coloring.collection_tree_background", true));
358 }
359 }
360
361 // The value column of cells never paints focus
362 if (column == 2) {
363 component.setBorder(BorderFactory.createEmptyBorder(0,2,0,0));
364 }
365
366 // We set a tooltip over the element column containing the definition of the element
367 if (value instanceof MetadataElement) {
368 String interface_language_code = Configuration.getLanguage();
369 String metadata_element_definition = MetadataTools.getMetadataElementAttribute((MetadataElement) value, "definition", interface_language_code, "en");
370 if (metadata_element_definition != null) {
371 component.setToolTipText(Utility.formatHTMLWidth(metadata_element_definition, 60));
372 }
373 }
374
375 return component;
376 }
377 }
378
379
380 private class MetadataValueTableKeyListener
381 extends KeyAdapter
382 {
383 /** Gives notification of key events on the text field */
384 public void keyPressed(KeyEvent key_event)
385 {
386 // Enter: save the current value then add a blank row for the selected metadata element
387 if (key_event.getKeyCode() == KeyEvent.VK_ENTER) {
388 // ...but not for extracted metadata elements of course
389 MetadataValueTableEntry metadata_value_table_entry = getSelectedMetadataValueTableEntry();
390 if (!metadata_value_table_entry.getMetadataElement().isExtractedMetadataElement()) {
391 addBlankRowForSelectedMetadataElement();
392 }
393
394 // We do not want this event to be processed by the table also
395 key_event.consume();
396 }
397 }
398 }
399
400
401 private class MetadataValueTextFieldMouseListener
402 extends MouseAdapter
403 {
404 public void mouseClicked(MouseEvent mouse_event)
405 {
406 // Double-click: pop up an editor dialog for large metadata values
407 if (mouse_event.getClickCount() == 2) {
408 EditorDialog editor_dialog = new EditorDialog();
409 String new_metadata_value_string = editor_dialog.display(metadata_value_text_field.getText());
410 if (new_metadata_value_string != null) {
411 setMetadataValueTextFieldValue(new_metadata_value_string);
412 }
413 }
414 }
415 }
416 }
417}
Note: See TracBrowser for help on using the repository browser.