[6840] | 1 | /**
|
---|
[9856] | 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
|
---|
[6840] | 5 | * University of Waikato, New Zealand.
|
---|
| 6 | *
|
---|
[9856] | 7 | * Author: Michael Dewsnip, NZDL Project, University of Waikato, NZ
|
---|
| 8 | * Based on code by John Thompson
|
---|
[6840] | 9 | *
|
---|
[9856] | 10 | * Copyright (C) 2005 New Zealand Digital Library Project
|
---|
[6840] | 11 | *
|
---|
| 12 | * This program is free software; you can redistribute it and/or modify
|
---|
| 13 | * it under the terms of the GNU General Public License as published by
|
---|
| 14 | * the Free Software Foundation; either version 2 of the License, or
|
---|
| 15 | * (at your option) any later version.
|
---|
| 16 | *
|
---|
| 17 | * This program is distributed in the hope that it will be useful,
|
---|
| 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
| 20 | * GNU General Public License for more details.
|
---|
| 21 | *
|
---|
| 22 | * You should have received a copy of the GNU General Public License
|
---|
| 23 | * along with this program; if not, write to the Free Software
|
---|
| 24 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
---|
[9856] | 25 | *############################################################################
|
---|
[6840] | 26 | */
|
---|
[9856] | 27 |
|
---|
[6840] | 28 | package org.greenstone.gatherer.gui;
|
---|
| 29 |
|
---|
[8313] | 30 |
|
---|
[6840] | 31 | import java.awt.*;
|
---|
| 32 | import java.awt.event.*;
|
---|
| 33 | import java.io.*;
|
---|
| 34 | import java.util.*;
|
---|
| 35 | import javax.swing.*;
|
---|
| 36 | import javax.swing.event.*;
|
---|
[9856] | 37 | import javax.swing.text.*;
|
---|
[6840] | 38 | import javax.swing.tree.*;
|
---|
| 39 | import org.greenstone.gatherer.Configuration;
|
---|
[8236] | 40 | import org.greenstone.gatherer.DebugStream;
|
---|
[6840] | 41 | import org.greenstone.gatherer.Dictionary;
|
---|
| 42 | import org.greenstone.gatherer.Gatherer;
|
---|
[8846] | 43 | import org.greenstone.gatherer.collection.CollectionTree;
|
---|
[8783] | 44 | import org.greenstone.gatherer.collection.CollectionTreeNode;
|
---|
[6840] | 45 | import org.greenstone.gatherer.gui.tree.DragTree;
|
---|
[23433] | 46 | import org.greenstone.gatherer.metadata.FilenameEncoding;
|
---|
[8313] | 47 | import org.greenstone.gatherer.metadata.MetadataElement;
|
---|
| 48 | import org.greenstone.gatherer.metadata.MetadataValue;
|
---|
| 49 | import org.greenstone.gatherer.metadata.MetadataValueTableEntry;
|
---|
| 50 | import org.greenstone.gatherer.metadata.MetadataValueTreeNode;
|
---|
[10547] | 51 | import org.greenstone.gatherer.metadata.MetadataXMLFileManager;
|
---|
[8313] | 52 |
|
---|
| 53 |
|
---|
[8695] | 54 | /** Provides a view of controls for the editing of metadata.
|
---|
[8313] | 55 | */
|
---|
[6840] | 56 | public class EnrichPane
|
---|
| 57 | extends JPanel
|
---|
[9856] | 58 | implements TreeSelectionListener
|
---|
[8802] | 59 | {
|
---|
[6840] | 60 | static private Dimension MINIMUM_SIZE = new Dimension(100, 100);
|
---|
[9856] | 61 | static private Dimension COLLECTION_TREE_SIZE = new Dimension(250, 500);
|
---|
[6840] | 62 |
|
---|
[13801] | 63 | private boolean has_focus = false;
|
---|
[9856] | 64 | /** The collection tree. */
|
---|
| 65 | private CollectionTree collection_tree = null;
|
---|
[8313] | 66 | /** The currently reported selection. */
|
---|
[8783] | 67 | private CollectionTreeNode[] file_nodes = null;
|
---|
[11622] | 68 | /** Used to dynamically filter the collection tree. */
|
---|
[9856] | 69 | private Filter collection_filter = null;
|
---|
[6840] | 70 | /** The label at the top of the collection tree, which shows the collection name. */
|
---|
| 71 | private JLabel collection_label;
|
---|
[11626] | 72 | /** The panel that contains the collection tree. */
|
---|
| 73 | private JPanel collection_pane = null;
|
---|
| 74 | /** The scrollable area into which the collection tree is placed. */
|
---|
| 75 | private JScrollPane collection_scroll = null;
|
---|
[9856] | 76 | /** The splitpane dividing the collection tree and the metadata editing controls. */
|
---|
[6840] | 77 | private JSplitPane external_split;
|
---|
[9856] | 78 | /** The metadata value table shows the metadata values that are currently assigned to a file. */
|
---|
| 79 | private MetadataValueTablePane metadata_value_table_pane = null;
|
---|
| 80 | /** The metadata value tree shows the metadata values that are currently assigned to a metadata element. */
|
---|
| 81 | private MetadataValueTreePane metadata_value_tree_pane = null;
|
---|
[6840] | 82 |
|
---|
[8313] | 83 |
|
---|
[11629] | 84 | public EnrichPane()
|
---|
[6840] | 85 | {
|
---|
[18370] | 86 | this.setComponentOrientation(Dictionary.getOrientation());
|
---|
| 87 | // Create the metadata value tree pane
|
---|
| 88 | metadata_value_tree_pane = new MetadataValueTreePane();
|
---|
[9856] | 89 | metadata_value_tree_pane.addMetadataValueTreeSelectionListener(new MetadataValueTreeSelectionListener());
|
---|
[6840] | 90 |
|
---|
[9856] | 91 | // Create metadata value table pane
|
---|
[18370] | 92 | metadata_value_table_pane = new MetadataValueTablePane();
|
---|
[9856] | 93 | metadata_value_table_pane.addMetadataValueTableListSelectionListener(new MetadataValueTableListSelectionListener());
|
---|
| 94 | metadata_value_table_pane.addMetadataValueTableMouseListener(new MetadataValueTableMouseListener());
|
---|
| 95 | metadata_value_table_pane.addMetadataValueTextFieldDocumentListener(new MetadataValueTextFieldDocumentListener());
|
---|
| 96 | metadata_value_table_pane.addMetadataValueTextFieldKeyListener(new MetadataValueTextFieldKeyListener());
|
---|
[6840] | 97 | }
|
---|
| 98 |
|
---|
| 99 |
|
---|
| 100 | /** Some actions can only occur after this panel has been displayed on-screen, so this method is provided to do exactly that. Such actions include the proportioning of the split panes and the setting of table column widths.
|
---|
| 101 | */
|
---|
[8313] | 102 | public void afterDisplay()
|
---|
| 103 | {
|
---|
[18370] | 104 | if (Dictionary.getOrientation().isLeftToRight()){
|
---|
| 105 | external_split.setDividerLocation(0.3);
|
---|
| 106 | }else{
|
---|
| 107 | external_split.setDividerLocation(0.7);
|
---|
| 108 | }
|
---|
[6840] | 109 | }
|
---|
[8313] | 110 |
|
---|
| 111 |
|
---|
[6840] | 112 | /** Used to create, connect and layout the components to be shown on this control panel.
|
---|
| 113 | * @see org.greenstone.gatherer.Gatherer
|
---|
| 114 | * @see org.greenstone.gatherer.file.FileOpenActionListener
|
---|
| 115 | * @see org.greenstone.gatherer.gui.Filter
|
---|
| 116 | */
|
---|
[8313] | 117 | public void display()
|
---|
| 118 | {
|
---|
[12145] | 119 | JPanel left_hand_pane = new JPanel(new BorderLayout());
|
---|
[18370] | 120 | left_hand_pane.setComponentOrientation(Dictionary.getOrientation());
|
---|
[12145] | 121 | GLIButton metadata_set_button = new GLIButton(Dictionary.get("EnrichPane.ManageMetadataSets"), Dictionary.get("EnrichPane.ManageMetadataSets_Tooltip"));
|
---|
| 122 | metadata_set_button.addActionListener(new ActionListener() {
|
---|
| 123 | public void actionPerformed(ActionEvent event) {
|
---|
| 124 | MetadataSetDialog msd = new MetadataSetDialog();
|
---|
| 125 | if (msd.setsChanged()) {
|
---|
| 126 | valueChanged(null);
|
---|
| 127 | }
|
---|
| 128 | }
|
---|
| 129 | });
|
---|
| 130 |
|
---|
[11761] | 131 | // Collection Tree
|
---|
[11626] | 132 | collection_pane = new JPanel(new BorderLayout());
|
---|
[18370] | 133 | // collection_pane.setComponentOrientation(Dictionary.getOrientation());
|
---|
[6840] | 134 | collection_pane.setMinimumSize(MINIMUM_SIZE);
|
---|
[9856] | 135 | collection_pane.setPreferredSize(COLLECTION_TREE_SIZE);
|
---|
[6840] | 136 |
|
---|
[12119] | 137 | collection_label = new JLabel(Dictionary.get("Collection.No_Collection"));
|
---|
[18370] | 138 | collection_label.setComponentOrientation(Dictionary.getOrientation());
|
---|
[6840] | 139 | collection_label.setOpaque(true);
|
---|
| 140 |
|
---|
[11627] | 141 | collection_tree = Gatherer.c_man.getCollectionTree();
|
---|
[6840] | 142 | collection_tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
|
---|
[18370] | 143 | collection_tree.addTreeSelectionListener(this);
|
---|
| 144 | collection_tree.setComponentOrientation(Dictionary.getOrientation());
|
---|
[11619] | 145 | collection_filter = collection_tree.getFilter();
|
---|
[11761] | 146 | external_split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
|
---|
[18370] | 147 | external_split.setComponentOrientation(Dictionary.getOrientation());
|
---|
[6840] | 148 | // Layout
|
---|
| 149 | collection_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(3,3,3,3), BorderFactory.createLoweredBevelBorder()));
|
---|
| 150 | collection_pane.setMinimumSize(MINIMUM_SIZE);
|
---|
| 151 | collection_pane.setPreferredSize(new Dimension(Gatherer.g_man.getSize().width / 3, Gatherer.g_man.getSize().height));
|
---|
[18370] | 152 | collection_pane.setComponentOrientation(Dictionary.getOrientation());
|
---|
[6840] | 153 | // Collection Pane
|
---|
| 154 | collection_pane.add(collection_label, BorderLayout.NORTH);
|
---|
| 155 |
|
---|
[9856] | 156 | JSplitPane metadata_editing_pane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
|
---|
| 157 | metadata_editing_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
|
---|
| 158 | metadata_editing_pane.setDividerSize(8);
|
---|
[18370] | 159 | metadata_editing_pane.setComponentOrientation(Dictionary.getOrientation());
|
---|
| 160 |
|
---|
[9856] | 161 | metadata_editing_pane.add(metadata_value_table_pane, JSplitPane.TOP);
|
---|
| 162 | metadata_editing_pane.add(metadata_value_tree_pane, JSplitPane.BOTTOM);
|
---|
| 163 | metadata_editing_pane.setDividerLocation(250);
|
---|
[6840] | 164 |
|
---|
[12145] | 165 | left_hand_pane.add(collection_pane, BorderLayout.CENTER);
|
---|
| 166 | left_hand_pane.add(metadata_set_button, BorderLayout.SOUTH);
|
---|
[18370] | 167 | if (Dictionary.getOrientation().isLeftToRight()){
|
---|
| 168 | external_split.add(left_hand_pane, JSplitPane.LEFT);
|
---|
| 169 | external_split.add(metadata_editing_pane, JSplitPane.RIGHT);
|
---|
| 170 | }else{
|
---|
| 171 | external_split.add(left_hand_pane, JSplitPane.RIGHT);
|
---|
| 172 | external_split.add(metadata_editing_pane, JSplitPane.LEFT);
|
---|
| 173 | }
|
---|
[6840] | 174 |
|
---|
[12145] | 175 |
|
---|
| 176 |
|
---|
[6840] | 177 | this.setLayout(new BorderLayout());
|
---|
| 178 | this.add(external_split, BorderLayout.CENTER);
|
---|
| 179 | }
|
---|
| 180 |
|
---|
| 181 |
|
---|
[9856] | 182 | /** Called to inform this pane that it has just gained focus as an effect of the user clicking on its tab
|
---|
[6840] | 183 | */
|
---|
[8313] | 184 | public void gainFocus()
|
---|
| 185 | {
|
---|
[13801] | 186 | // Remember that we currently have focus
|
---|
| 187 | has_focus = true;
|
---|
| 188 |
|
---|
[11626] | 189 | // Add the collection tree and filter back into this pane
|
---|
| 190 | collection_scroll = new JScrollPane(collection_tree);
|
---|
| 191 | collection_pane.add(collection_scroll, BorderLayout.CENTER);
|
---|
| 192 | collection_pane.add(collection_filter, BorderLayout.SOUTH);
|
---|
| 193 |
|
---|
[8313] | 194 | // Select the first node in the tree if nothing is already selected
|
---|
[11825] | 195 | if (collection_tree.getSelectionPaths() == null && collection_tree.getRowCount() > 0) {
|
---|
[8313] | 196 | collection_tree.setImmediate(true);
|
---|
| 197 | collection_tree.setSelectionRow(0);
|
---|
| 198 | collection_tree.setImmediate(false);
|
---|
[8359] | 199 | return;
|
---|
[6840] | 200 | }
|
---|
| 201 |
|
---|
[8313] | 202 | // Force all of the controls to be updated
|
---|
[9856] | 203 | valueChanged(null);
|
---|
[6840] | 204 | }
|
---|
| 205 |
|
---|
| 206 |
|
---|
[10387] | 207 | /** Called to inform this pane that it has just lost focus as an effect of the user clicking on another tab
|
---|
| 208 | */
|
---|
| 209 | public void loseFocus()
|
---|
| 210 | {
|
---|
[10604] | 211 | // Very important: make sure metadata value is saved before leaving the pane
|
---|
| 212 | metadata_value_table_pane.stopEditingAndRebuild(file_nodes);
|
---|
| 213 |
|
---|
[13705] | 214 | // Make sure all the metadata has been saved to file
|
---|
| 215 | MetadataXMLFileManager.saveMetadataXMLFiles();
|
---|
[11626] | 216 |
|
---|
| 217 | // Remove the collection tree and filter from this pane so it can be added to the Gather pane
|
---|
| 218 | collection_pane.remove(collection_scroll);
|
---|
| 219 | collection_pane.remove(collection_filter);
|
---|
[13801] | 220 |
|
---|
| 221 | // Remember that we no longer have focus
|
---|
| 222 | has_focus = false;
|
---|
[10387] | 223 | }
|
---|
| 224 |
|
---|
| 225 |
|
---|
[6840] | 226 | /** Called whenever the detail mode changes to ensure the filters are at an appropriate level (ie only editable by those that understand regular expression matching)
|
---|
| 227 | * @param mode the mode level as an int
|
---|
| 228 | */
|
---|
[8313] | 229 | public void modeChanged(int mode)
|
---|
| 230 | {
|
---|
[18593] | 231 | collection_filter.setEditable(mode >= Configuration.LIBRARIAN_MODE);
|
---|
[6840] | 232 | }
|
---|
| 233 |
|
---|
| 234 |
|
---|
[8813] | 235 | /** Refresh this pane, depending on what has just happened (refresh_reason). */
|
---|
| 236 | public void refresh(int refresh_reason, boolean collection_loaded)
|
---|
[8353] | 237 | {
|
---|
[8813] | 238 | if (collection_loaded) {
|
---|
| 239 | // Update collection label
|
---|
[12119] | 240 | collection_label.setText(Dictionary.get("Collection.Collection"));
|
---|
[8353] | 241 | collection_label.setBackground(Configuration.getColor("coloring.collection_heading_background", false));
|
---|
| 242 | collection_label.setForeground(Configuration.getColor("coloring.collection_heading_foreground", false));
|
---|
| 243 |
|
---|
[8813] | 244 | // Update collection tree
|
---|
| 245 | if (refresh_reason == Gatherer.COLLECTION_OPENED) {
|
---|
[8846] | 246 | collection_tree.setModel(Gatherer.c_man.getCollectionTreeModel());
|
---|
[8354] | 247 | }
|
---|
[8813] | 248 |
|
---|
| 249 | // Update collection filter
|
---|
| 250 | collection_filter.setBackground(Configuration.getColor("coloring.collection_heading_background", false));
|
---|
[8353] | 251 | }
|
---|
| 252 | else {
|
---|
[8813] | 253 | // Update collection label
|
---|
[12119] | 254 | collection_label.setText(Dictionary.get("Collection.No_Collection"));
|
---|
[8353] | 255 | collection_label.setBackground(Color.lightGray);
|
---|
| 256 | collection_label.setForeground(Color.black);
|
---|
[8354] | 257 |
|
---|
[8813] | 258 | // Update collection tree
|
---|
| 259 | collection_tree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode("Error")));
|
---|
| 260 |
|
---|
| 261 | // Update collection filter
|
---|
| 262 | collection_filter.setBackground(Color.lightGray);
|
---|
[8353] | 263 | }
|
---|
| 264 |
|
---|
[8813] | 265 | // Enable or disable the controls
|
---|
| 266 | collection_tree.setEnabled(collection_loaded);
|
---|
| 267 | collection_filter.setEnabled(collection_loaded);
|
---|
| 268 |
|
---|
| 269 | // Force the metadata table to be rebuilt (for switching extracted metadata on or off)
|
---|
| 270 | if (refresh_reason == Gatherer.PREFERENCES_CHANGED) {
|
---|
[9856] | 271 | metadata_value_table_pane.stopEditingAndRebuild(file_nodes);
|
---|
[8813] | 272 | }
|
---|
[8353] | 273 | }
|
---|
| 274 |
|
---|
| 275 |
|
---|
[18199] | 276 | /** Allows other classes to request the enrich pane to prepare for metadata
|
---|
| 277 | * saving.
|
---|
| 278 | * @author John Thompson, DL Consulting Ltd
|
---|
| 279 | */
|
---|
| 280 | public void stopEditingAndRebuild()
|
---|
| 281 | {
|
---|
| 282 | // Update the metadata value table (and consequently, the metadata value tree)
|
---|
| 283 | metadata_value_table_pane.stopEditingAndRebuild(file_nodes);
|
---|
| 284 | }
|
---|
| 285 | /** stopEditingAndRebuild() **/
|
---|
| 286 |
|
---|
| 287 | /** Called whenever the collection tree selection changes. This causes the metadata value table to be rebuilt. */
|
---|
| 288 | public void valueChanged(TreeSelectionEvent event)
|
---|
[8313] | 289 | {
|
---|
[23433] | 290 | if(FilenameEncoding.isRefreshRequired()) {
|
---|
| 291 | // The CollectionTree is in the process of being re-built to deal with filename-encodings,
|
---|
| 292 | // so don't mess up the table during that time.
|
---|
| 293 | // (CollectionTreeNode.refreshDescendantEncodings() doesn't cope well if this method
|
---|
| 294 | // responds on Tree selection changes while the tree is updating its encodings, resulting in lost
|
---|
| 295 | // and misplaced metadata values in the table and thereby in the metadata.xml files themselves).
|
---|
| 296 | return;
|
---|
| 297 | }
|
---|
| 298 |
|
---|
| 299 |
|
---|
[13801] | 300 | // If we haven't got focus then it must have been a selection in the Gather pane, so don't bother rebuilding
|
---|
| 301 | if (has_focus == false) {
|
---|
| 302 | return;
|
---|
| 303 | }
|
---|
| 304 |
|
---|
[8313] | 305 | // Nothing selected in the collection tree
|
---|
| 306 | if (collection_tree.getSelectionCount() == 0) {
|
---|
| 307 | file_nodes = null;
|
---|
[6840] | 308 | }
|
---|
| 309 |
|
---|
[8313] | 310 | // Some files selected in the collection tree
|
---|
[6840] | 311 | else {
|
---|
[8313] | 312 | TreePath paths[] = collection_tree.getSelectionPaths();
|
---|
[8783] | 313 | file_nodes = new CollectionTreeNode[paths.length];
|
---|
[8313] | 314 | for (int i = 0; i < paths.length; i++) {
|
---|
[8783] | 315 | file_nodes[i] = (CollectionTreeNode) paths[i].getLastPathComponent();
|
---|
[6840] | 316 | }
|
---|
| 317 | }
|
---|
[8313] | 318 |
|
---|
| 319 | // Update the metadata value table (and consequently, the metadata value tree)
|
---|
[9856] | 320 | metadata_value_table_pane.stopEditingAndRebuild(file_nodes);
|
---|
[6840] | 321 | }
|
---|
| 322 |
|
---|
[8313] | 323 |
|
---|
[9856] | 324 | private class MetadataValueTableListSelectionListener
|
---|
| 325 | implements ListSelectionListener
|
---|
[8313] | 326 | {
|
---|
[9856] | 327 | public void valueChanged(ListSelectionEvent list_selection_event)
|
---|
[8313] | 328 | {
|
---|
[9856] | 329 | // We only want to handle one event per selection, so wait for the value to stabilise
|
---|
| 330 | if (list_selection_event.getValueIsAdjusting()) {
|
---|
| 331 | return;
|
---|
[9334] | 332 | }
|
---|
[9331] | 333 |
|
---|
[9856] | 334 | // Update the metadata value tree for the current table selection
|
---|
| 335 | metadata_value_tree_pane.rebuild(metadata_value_table_pane.getSelectedMetadataValueTableEntry());
|
---|
[6840] | 336 | }
|
---|
| 337 | }
|
---|
| 338 |
|
---|
| 339 |
|
---|
[9856] | 340 | private class MetadataValueTableMouseListener
|
---|
| 341 | extends MouseAdapter
|
---|
[8313] | 342 | {
|
---|
[9856] | 343 | public void mouseClicked(MouseEvent mouse_event)
|
---|
[8313] | 344 | {
|
---|
[9856] | 345 | // We're only interested in clicks on the inherited column
|
---|
| 346 | if (metadata_value_table_pane.isMouseEventForInheritedMetadataValueTableColumn(mouse_event) == false) {
|
---|
| 347 | return;
|
---|
| 348 | }
|
---|
[6840] | 349 |
|
---|
[9856] | 350 | // If the selected metadata is inherited, switch to the folder it came from
|
---|
| 351 | MetadataValueTableEntry selected_metadata_value_table_entry = metadata_value_table_pane.getSelectedMetadataValueTableEntry();
|
---|
| 352 | if (selected_metadata_value_table_entry.isInheritedMetadata()) {
|
---|
| 353 | collection_tree.setSelection(selected_metadata_value_table_entry.getFolderMetadataInheritedFrom());
|
---|
[9334] | 354 | }
|
---|
[8313] | 355 | }
|
---|
| 356 | }
|
---|
[6840] | 357 |
|
---|
| 358 |
|
---|
[9856] | 359 | private class MetadataValueTextFieldDocumentListener
|
---|
| 360 | implements DocumentListener
|
---|
[8313] | 361 | {
|
---|
[9856] | 362 | /** Gives notification that an attribute or set of attributes changed */
|
---|
| 363 | public void changedUpdate(DocumentEvent document_event) {
|
---|
| 364 | validate(document_event);
|
---|
| 365 | }
|
---|
[9331] | 366 |
|
---|
[9856] | 367 | /** Gives notification that there was an insert into the document */
|
---|
| 368 | public void insertUpdate(DocumentEvent document_event) {
|
---|
| 369 | validate(document_event);
|
---|
[9331] | 370 | }
|
---|
| 371 |
|
---|
[9856] | 372 | /** Gives notification that a portion of the document has been removed */
|
---|
| 373 | public void removeUpdate(DocumentEvent document_event) {
|
---|
| 374 | validate(document_event);
|
---|
| 375 | }
|
---|
| 376 |
|
---|
| 377 |
|
---|
| 378 | /** Ensures that the value tree is updated in response to changes in the value text field */
|
---|
| 379 | private void validate(DocumentEvent document_event)
|
---|
[8313] | 380 | {
|
---|
[9334] | 381 | try {
|
---|
[9856] | 382 | Document document = document_event.getDocument();
|
---|
| 383 | String metadata_value_string = document.getText(0, document.getLength());
|
---|
| 384 | metadata_value_tree_pane.selectBestPathForMetadataValue(metadata_value_string);
|
---|
[9334] | 385 | }
|
---|
| 386 | catch (Exception exception) {
|
---|
| 387 | DebugStream.printStackTrace(exception);
|
---|
| 388 | }
|
---|
[6840] | 389 | }
|
---|
[8313] | 390 | }
|
---|
[6840] | 391 |
|
---|
[8313] | 392 |
|
---|
[9856] | 393 | private class MetadataValueTextFieldKeyListener
|
---|
| 394 | extends KeyAdapter
|
---|
[8313] | 395 | {
|
---|
[9856] | 396 | /** Gives notification of key events on the text field */
|
---|
| 397 | public void keyPressed(KeyEvent key_event)
|
---|
[8313] | 398 | {
|
---|
[9856] | 399 | // Tab: Auto-complete what is selected in the metadata value tree
|
---|
| 400 | if (key_event.getKeyCode() == KeyEvent.VK_TAB) {
|
---|
| 401 | MetadataValueTreeNode selected_metadata_value_tree_node = metadata_value_tree_pane.getSelectedMetadataValueTreeNode();
|
---|
| 402 | if (selected_metadata_value_tree_node != null) {
|
---|
| 403 | metadata_value_table_pane.setMetadataValueTextFieldValue(selected_metadata_value_tree_node.getFullValue());
|
---|
[8313] | 404 | }
|
---|
[6840] | 405 |
|
---|
[9856] | 406 | // We do not want this event to be processed by the table also
|
---|
| 407 | key_event.consume();
|
---|
[8313] | 408 | }
|
---|
[6840] | 409 |
|
---|
[9856] | 410 | // Enter: save the current value then add a blank row for the selected metadata element
|
---|
| 411 | if (key_event.getKeyCode() == KeyEvent.VK_ENTER) {
|
---|
| 412 | metadata_value_table_pane.stopEditingAndAddBlankRowForSelectedMetadataElement();
|
---|
[8364] | 413 | }
|
---|
| 414 | }
|
---|
[7098] | 415 | }
|
---|
| 416 |
|
---|
| 417 |
|
---|
[9856] | 418 | private class MetadataValueTreeSelectionListener
|
---|
| 419 | implements TreeSelectionListener
|
---|
[8313] | 420 | {
|
---|
[9856] | 421 | public void valueChanged(TreeSelectionEvent tree_selection_event)
|
---|
[6840] | 422 | {
|
---|
[9856] | 423 | // When a node is selected in the tree, fill the metadata value text field with the selected node's value
|
---|
| 424 | MetadataValueTreeNode selected_metadata_value_tree_node = metadata_value_tree_pane.getSelectedMetadataValueTreeNode();
|
---|
| 425 | if (selected_metadata_value_tree_node != null) {
|
---|
| 426 | metadata_value_table_pane.setMetadataValueTextFieldValue(selected_metadata_value_tree_node.getFullValue());
|
---|
[6840] | 427 | }
|
---|
| 428 | }
|
---|
| 429 | }
|
---|
| 430 | }
|
---|