- Timestamp:
- 2004-10-13T14:48:20+13:00 (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gli/src/org/greenstone/gatherer/cdm/MetadataSetView.java
r8243 r8313 29 29 import java.awt.*; 30 30 import java.awt.event.*; 31 import java.io.File; 31 32 import java.util.*; 32 33 import javax.swing.*; 33 34 import javax.swing.event.*; 35 import javax.swing.filechooser.*; 34 36 import org.greenstone.gatherer.Configuration; 35 37 import org.greenstone.gatherer.DebugStream; … … 37 39 import org.greenstone.gatherer.Gatherer; 38 40 import org.greenstone.gatherer.gui.GLIButton; 39 import org.greenstone.gatherer.mem.MetadataEditorManager; 40 import org.greenstone.gatherer.msm.MetadataSet; 41 import org.greenstone.gatherer.msm.MSMEvent; 42 import org.greenstone.gatherer.msm.MSMListener; 43 import org.w3c.dom.*; 41 import org.greenstone.gatherer.gui.MetadataElementListCellRenderer; 42 import org.greenstone.gatherer.metadata.MetadataElement; 43 import org.greenstone.gatherer.metadata.MetadataSet; 44 import org.greenstone.gatherer.metadata.MetadataSetManager; 45 import org.greenstone.gatherer.metadata.MetadataTools; 46 import org.greenstone.gatherer.metadata.MetadataXMLFileManager; 47 import org.greenstone.gatherer.util.Utility; 48 44 49 45 50 /** This class only knows how to produce a simple visual representation of the currently imported metadata sets. It is also read-only, so should be fairly straight forward. … … 48 53 */ 49 54 public class MetadataSetView 50 extends DynamicListModel 51 implements MSMListener { 55 extends DynamicListModel { 56 52 57 /** The visual contols used to review the metadata sets. */ 53 58 private Control controls = null; … … 55 60 private DynamicListModel model = null; 56 61 57 /** Constructor. 58 */ 59 public MetadataSetView() { 60 DebugStream.println("MetadataSetView: Initialized."); 62 63 public MetadataSetView() 64 { 61 65 model = this; 62 Gatherer.c_man.getCollection().msm.addMSMListener(this); 63 loadMetadataSets(); 66 67 // Initialise the model 68 refreshModel(); 69 64 70 // Build the controls 65 controls = new MetadataSetControl(); 66 } 67 68 /** Destructor. Remove any references of this class from persistant objects. 69 * @see org.greenstone.gatherer.Gatherer 70 * @see org.greenstone.gatherer.collection.CollectionManager 71 */ 72 public void destroy() { 71 controls = new MetadataSetViewControls(); 72 } 73 74 75 public void destroy() 76 { 73 77 controls.destroy(); 74 78 controls = null; 75 Gatherer.c_man.msm.removeMSMListener(this);76 79 model = null; 77 80 } 78 81 79 /** Called when an element is changed within a set in the MSM, prompting us to refresh our list of elements being shown.80 * @param event A <strong>MSMEvent</strong> which encapsulates relevant data about the change.81 * @see org.greenstone.gatherer.cdm.MetadataSetView.MetadataSetControl82 */83 public void elementChanged(MSMEvent event) {84 // Get the controls to refresh element list.85 ((MetadataSetControl)controls).refreshElementList();86 }87 82 88 83 /** A method for retrieve the controls for this manager. 89 * @see org.greenstone.gatherer.Dictionary90 * @see org.greenstone.gatherer.gui.Coloring91 84 */ 92 85 public Control getControls() { … … 94 87 } 95 88 96 /** Called when a metadata value has undergone significant change. 97 * @param event A <strong>MSMEvent</strong> which encapsulates relevant data about the change. 98 */ 99 public void metadataChanged(MSMEvent event) { 100 // Couldn't care less. 101 } 102 103 /** Called when a set is added or removed from the MSM. 104 * @param event A <strong>MSMEvent</strong> which encapsulates relevant data about the change. 105 */ 106 public void setChanged(MSMEvent event) { 107 // Reload model. 108 clear(); 109 loadMetadataSets(); 110 } 111 112 113 /** Prints out the contents of this manager, as they would appear in the collection configuration file. 114 * @return A <strong>String</strong> containing a block of commands. 115 * @see org.greenstone.gatherer.cdm.MetadataSetView.SetWrapper 116 */ 117 public String toString() { 118 String text = ""; 119 for(int i = 0; i < size(); i++) { 120 SetWrapper set = (SetWrapper)get(i); 121 text = text + set.toString() + "\n"; 122 } 123 text = text + "\n"; 124 return text; 125 } 126 127 /** Called when a significant change has occured to a value tree for a certain element, however we take no further action. 128 * @param event A <strong>MSMEvent</strong> containing information relevant to the event. 129 */ 130 public void valueChanged(MSMEvent event) { 131 } 132 133 /** Retrieves the current list of loaded metadata sets, and builds a list model around them. 134 * @see org.greenstone.gatherer.Gatherer 135 * @see org.greenstone.gatherer.cdm.MetadataSetView.SetWrapper 136 * @see org.greenstone.gatherer.collection.CollectionManager 137 */ 138 private void loadMetadataSets() { 139 // We initialize the set_model with wrapped metadata sets. Note that when we call getSets() we also end up adding ourselves as a listener to the metadata set manager. 140 Vector sets = Gatherer.c_man.getCollection().msm.getSets(); 141 for(int i = 0; i < sets.size(); i++) { 142 addElement(new SetWrapper((MetadataSet)sets.get(i))); 143 } 144 } 89 90 public void refreshModel() 91 { 92 // Remove any metadata sets from the model that are no longer loaded 93 ArrayList loaded_metadata_sets = MetadataSetManager.getMetadataSets(); 94 for (int i = size() - 1; i >= 0; i--) { 95 MetadataSet metadata_set = (MetadataSet) get(i); 96 if (loaded_metadata_sets.contains(metadata_set) == false) { 97 // System.err.println("Metadata set in list no longer loaded...removing."); 98 remove(i); 99 } 100 } 101 102 // Add any metadata sets that are loaded but not in the model 103 for (int i = 0; i < loaded_metadata_sets.size(); i++) { 104 MetadataSet loaded_metadata_set = (MetadataSet) loaded_metadata_sets.get(i); 105 boolean in_model = false; 106 for (int j = 0; j < size(); j++) { 107 MetadataSet metadata_set = (MetadataSet) get(j); 108 if (metadata_set.equals(loaded_metadata_set)) { 109 in_model = true; 110 break; 111 } 112 } 113 114 if (in_model == false) { 115 // System.err.println("Metadata set loaded but not in list...adding."); 116 addElement(loaded_metadata_set); 117 } 118 } 119 } 120 145 121 146 122 /** This class creates and lays-out the various controls for reviewing the metadata sets, and their commands as they would appear in the collection configuration file. */ 147 private class MetadataSet Control123 private class MetadataSetViewControls 148 124 extends JPanel 149 125 implements Control { 150 /** Listens for clicks upon the configure button, or double clicks from the metadata set list. */151 private ConfigureActionListener configure_action_listener;152 126 /** Opens the MEM and systematically performs as if the add set button were clicked. */ 153 127 private JButton add_button; 154 /** Opens the MEM with the appropriate set open for editing. */155 private JButton configure_button;156 128 /** Opens the MEM and systematically performs as if the remove set button were clicked. */ 157 129 private JButton remove_button; … … 179 151 private JTextArea instructions = null; 180 152 181 private ListListener list_listener; 182 183 private MultilingualListCellRenderer element_list_cell_renderer; 184 185 /** The element model for the currently selected set. */ 186 private Vector element_model = null; 153 private MetadataElementListCellRenderer element_list_cell_renderer; 154 private MetadataSetListSelectionListener list_listener; 187 155 188 156 /* Constructor. … … 191 159 * @see org.greenstone.gatherer.cdm.MetadataSetView.ListListener 192 160 */ 193 public MetadataSetControl() { 161 public MetadataSetViewControls() 162 { 194 163 // Create visual components 195 164 central_pane = new JPanel(); … … 198 167 element_label.setOpaque(true); 199 168 Dictionary.registerText(element_label, "CDM.MetadataSetManager.Elements"); 169 element_list = new JList(); 200 170 element_list_scroll_pane = new JScrollPane(); 201 element_list_cell_renderer = new MultilingualListCellRenderer(element_list_scroll_pane);202 element_list = new JList();203 171 element_list_scroll_pane.setViewportView(element_list); 172 element_list_cell_renderer = new MetadataElementListCellRenderer(); 204 173 element_list.setCellRenderer(element_list_cell_renderer); 205 174 element_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); … … 218 187 Dictionary.registerText(set_label, "CDM.MetadataSetManager.Sets"); 219 188 set_list = new JList(model); 189 set_list.setCellRenderer(new MetadataSetListCellRenderer()); 220 190 set_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 221 if(model.size() > 0) {222 set_list.setSelectedIndex(0);223 }224 191 225 192 set_pane = new JPanel(); … … 234 201 add_button.setMnemonic(KeyEvent.VK_A); 235 202 Dictionary.registerBoth(add_button, "CDM.MetadataSetManager.Add", "CDM.MetadataSetManager.Add_Tooltip"); 236 configure_button = new GLIButton();237 configure_button.setEnabled(false);238 configure_button.setMnemonic(KeyEvent.VK_C);239 Dictionary.registerBoth(configure_button, "CDM.MetadataSetManager.Configure", "CDM.MetadataSetManager.Configure_Tooltip");240 203 remove_button = new GLIButton(); 241 204 remove_button.setEnabled(false); 242 205 remove_button.setMnemonic(KeyEvent.VK_R); 243 206 Dictionary.registerBoth(remove_button, "CDM.MetadataSetManager.Remove", "CDM.MetadataSetManager.Remove_Tooltip"); 244 configure_action_listener = new ConfigureActionListener(); 245 list_listener = new ListListener(); 207 list_listener = new MetadataSetListSelectionListener(); 246 208 247 209 // Add listeners 248 210 add_button.addActionListener(new AddButtonListener()); 249 configure_button.addActionListener(configure_action_listener);250 211 remove_button.addActionListener(new RemoveButtonListener()); 251 212 set_list.addListSelectionListener(list_listener); 252 set_list.addMouseListener(configure_action_listener);253 213 // Layout 254 214 instructions.setBorder(BorderFactory.createEmptyBorder(2,5,2,5)); … … 273 233 button_pane.setLayout(new GridLayout(1,3,0,0)); 274 234 button_pane.add(add_button); 275 button_pane.add(configure_button);276 235 button_pane.add(remove_button); 277 236 … … 282 241 add(button_pane, BorderLayout.SOUTH); 283 242 } 284 /** Destructor. */ 285 public void destroy() { 286 } 287 /** Update the element list. */ 288 public void refreshElementList() { 289 element_list.updateUI(); 290 } 291 292 /** Overriden to ensure the instruction area is scrolled to top. 293 */ 294 public void gainFocus() { 295 if(instructions != null) { 243 244 245 public void destroy() { } 246 247 248 public void gainFocus() 249 { 250 // Ensure the instructions area is scrolled to the top 251 if (instructions != null) { 296 252 instructions.setCaretPosition(0); 297 253 } 254 298 255 // If no current selection, select first available set 299 if (set_list.isSelectionEmpty() && set_list.getModel().getSize() > 0) {256 if (set_list.isSelectionEmpty() && set_list.getModel().getSize() > 0) { 300 257 set_list.setSelectedIndex(0); 301 258 list_listener.valueChanged(new ListSelectionEvent(set_list, 0, 0, true)); … … 303 260 } 304 261 305 public void loseFocus() { 306 } 307 308 /** Listens for clicks on the add button, and actions them accordingly by opening the MEM and clicking add set. */ 262 263 public void loseFocus() { } 264 265 266 /** Listens for clicks on the add button. */ 309 267 private class AddButtonListener 310 268 implements ActionListener { 269 311 270 /** Called when the add button is clicked. 312 271 * @param event an ActionEvent containing information about the mouse click 313 * @see org.greenstone.gatherer.Gatherer314 * @see org.greenstone.gatherer.collection.Collection315 * @see org.greenstone.gatherer.collection.CollectionManager316 * @see org.greenstone.gatherer.mem.MetadataEditorManager317 272 */ 318 public void actionPerformed(ActionEvent event) { 319 Gatherer.c_man.getCollection().msm.editMDS(null, MetadataEditorManager.ADD_SET); 320 } 321 } 322 323 /** Listens for clicks on the configure button or double clicks upon the metadata set list and chains to the MEM as appropriate. */ 324 private class ConfigureActionListener 325 extends MouseAdapter 273 public void actionPerformed(ActionEvent event) 274 { 275 JFileChooser chooser = new JFileChooser(new File(Utility.METADATA_DIR)); 276 chooser.setFileFilter(new MetadataSet.MetadataSetFileFilter()); 277 int return_val = chooser.showDialog(Gatherer.g_man, Dictionary.get("MSMPrompt.File_Import")); 278 if (return_val == JFileChooser.APPROVE_OPTION) { 279 Gatherer.c_man.importMetadataSet(new MetadataSet(chooser.getSelectedFile())); 280 refreshModel(); 281 282 // The metadata.xml files may possibly contain metadata for this newly added metadata set 283 // Re-read all the metadata.xml files to account for this case 284 MetadataXMLFileManager.clearMetadataXMLFiles(); 285 MetadataXMLFileManager.loadMetadataXMLFiles(new File(Gatherer.c_man.getCollectionImport())); 286 } 287 } 288 } 289 290 291 private class MetadataSetListCellRenderer 292 implements ListCellRenderer 293 { 294 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) 295 { 296 DefaultListCellRenderer default_list_cell_renderer = new DefaultListCellRenderer(); 297 JLabel list_cell_label = (JLabel) default_list_cell_renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 298 299 if (value instanceof MetadataSet) { 300 MetadataSet metadata_set = (MetadataSet) value; 301 String metadata_set_name = MetadataTools.getMetadataSetAttribute(metadata_set, "Name", Configuration.getLanguage(), "en"); 302 list_cell_label.setText("metadataset " + metadata_set.getNamespace() + " \"" + metadata_set_name + "\""); 303 } 304 305 return list_cell_label; 306 } 307 } 308 309 310 private class MetadataSetListSelectionListener 311 implements ListSelectionListener { 312 313 public void valueChanged(ListSelectionEvent event) 314 { 315 // Wait until we get a stable event 316 if (event.getValueIsAdjusting()) { 317 return; 318 } 319 320 // Now we can process it 321 if (!set_list.isSelectionEmpty()) { 322 MetadataSet metadata_set = (MetadataSet) set_list.getSelectedValue(); 323 element_list.setListData(new Vector(metadata_set.getMetadataSetElements())); 324 remove_button.setEnabled(true); 325 326 // Finally check the directionality and scroll as necessary 327 JScrollBar scroll_bar = element_list_scroll_pane.getHorizontalScrollBar(); 328 if (element_list_cell_renderer.getDirectionality() == Character.DIRECTIONALITY_RIGHT_TO_LEFT) { 329 scroll_bar.setValue(scroll_bar.getMaximum()); 330 } 331 else { 332 scroll_bar.setValue(scroll_bar.getMinimum()); 333 } 334 } 335 else { 336 remove_button.setEnabled(false); 337 } 338 } 339 } 340 341 342 /** Listens for clicks on the remove button. */ 343 private class RemoveButtonListener 326 344 implements ActionListener { 327 /** Called when the configure button is clicked. 345 346 /** Called when the remove button is clicked. 328 347 * @param event an ActionEvent containing information about the mouse click 329 348 */ 330 public void actionPerformed(ActionEvent event) { 331 configureSet(); 332 } 333 334 /** Called whenever the mouse is clicked over a registered component, we use this to chain through to the configure prompt. 335 * @param event a MouseEvent containing information about the mouse click 336 */ 337 public void mouseClicked(MouseEvent event) { 338 if(event.getClickCount() == 2 ) { 339 configureSet(); 340 } 341 } 342 /** If some set is selected, then open the metadata set manager with the current set selected and expanded 343 * @see org.greenstone.gatherer.Gatherer 344 * @see org.greenstone.gatherer.collection.Collection 345 * @see org.greenstone.gatherer.collection.CollectionManager 346 * @see org.greenstone.gatherer.cdm.MetadataSetView.SetWrapper 347 * @see org.greenstone.gatherer.mem.MetadataEditorManager 348 */ 349 private void configureSet() { 350 if(!set_list.isSelectionEmpty()) { 351 MetadataSet set = ((SetWrapper)set_list.getSelectedValue()).getSet(); 352 Gatherer.c_man.getCollection().msm.editMDS(set, MetadataEditorManager.NORMAL); 353 } 354 else { 355 configure_button.setEnabled(false); 356 } 357 } 358 } 359 360 private class ListListener 361 implements ListSelectionListener { 362 public void valueChanged(ListSelectionEvent event) { 363 // Wait until we get a stable event 364 if(event.getValueIsAdjusting()) { 365 return; 366 } 367 // Now we can process it 368 if(!set_list.isSelectionEmpty()) { 369 MetadataSet set = ((SetWrapper)set_list.getSelectedValue()).getSet(); 370 NodeList elements = set.getElements(); 371 element_model = new Vector(); 372 for(int i = 0; i < elements.getLength(); i++) { 373 element_model.add(new ElementWrapper(elements.item(i))); 374 } 375 //Collections.sort(element_model); 376 element_list.setListData(element_model); 377 configure_button.setEnabled(true); 378 remove_button.setEnabled(true); 379 380 // Finally check the directionality and scroll as necessary 381 JScrollBar scroll_bar = element_list_scroll_pane.getHorizontalScrollBar(); 382 if(element_list_cell_renderer.getDirectionality() == Character.DIRECTIONALITY_RIGHT_TO_LEFT) { 383 scroll_bar.setValue(scroll_bar.getMaximum()); 384 } 385 else { 386 scroll_bar.setValue(scroll_bar.getMinimum()); 387 } 388 389 } 390 else { 391 configure_button.setEnabled(false); 392 remove_button.setEnabled(false); 393 } 394 } 395 } 396 397 /** Listens for clicks on the remove button, and actions them accordingly by opening the MEM and clicking remove set. */ 398 private class RemoveButtonListener 399 implements ActionListener { 400 /** Called when the remove button is clicked. 401 * @param event an ActionEvent containing information about the mouse click 402 * @see org.greenstone.gatherer.Gatherer 403 * @see org.greenstone.gatherer.collection.Collection 404 * @see org.greenstone.gatherer.collection.CollectionManager 405 * @see org.greenstone.gatherer.cdm.MetadataSetView.SetWrapper 406 * @see org.greenstone.gatherer.mem.MetadataEditorManager 407 */ 408 public void actionPerformed(ActionEvent event) { 409 if(!set_list.isSelectionEmpty()) { 410 MetadataSet set = ((SetWrapper)set_list.getSelectedValue()).getSet(); 411 Gatherer.c_man.getCollection().msm.editMDS(set, MetadataEditorManager.REMOVE_SET); 412 } 413 else { 414 remove_button.setEnabled(false); 415 } 416 } 417 } 418 419 private class MultilingualListCellRenderer 420 extends DefaultListCellRenderer { 421 private byte previous_directionality = Character.DIRECTIONALITY_UNDEFINED; 422 private JScrollPane scroll_pane; 423 public MultilingualListCellRenderer(JScrollPane scroll_pane) { 424 super(); 425 this.scroll_pane = scroll_pane; 426 } 427 428 public byte getDirectionality() { 429 if(previous_directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT || previous_directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC || previous_directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING || previous_directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE) { 430 return Character.DIRECTIONALITY_RIGHT_TO_LEFT; 431 } 432 else { 433 return Character.DIRECTIONALITY_LEFT_TO_RIGHT; 434 } 435 } 436 437 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 438 JLabel component = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 439 // Determine if the text should be left aligned or right aligned 440 String text = value.toString(); 441 int text_index = 0; 442 byte directionality = Character.DIRECTIONALITY_UNDEFINED; 443 while(directionality == Character.DIRECTIONALITY_UNDEFINED && text_index < text.length()) { 444 directionality = Character.getDirectionality(text.charAt(text_index)); 445 text_index++; 446 } 447 if(directionality != previous_directionality) { 448 previous_directionality = directionality; 449 if(directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT || directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC || directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING || directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE) { 450 ///ystem.err.println("R2L for: " + text); 451 component.setHorizontalAlignment(JLabel.TRAILING); 452 component.setHorizontalTextPosition(JLabel.TRAILING); 453 component.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); 454 //scroll_pane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); 455 } 456 else { 457 component.setHorizontalAlignment(JLabel.LEADING); 458 component.setHorizontalTextPosition(JLabel.LEADING); 459 ///ystem.err.println("L2R for: " + text); 460 component.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); 461 //scroll_pane.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); 462 } 463 } 464 465 text = null; 466 return component; 467 } 468 469 } 470 471 } 472 473 /** Provides a convience wrapper around a metadata set, that allows it to appear in the <strong>JList</strong> the same way it would in the collection configuration file. */ 474 private class SetWrapper { 475 private MetadataSet set = null; 476 public SetWrapper(MetadataSet set) { 477 this.set = set; 478 } 479 public MetadataSet getSet() { 480 return set; 481 } 482 public String toString() { 483 String namespace = set.getNamespace(); 484 // Watch out for the greenstone set, with its namespace of "" 485 return "metadataset " + namespace + " \"" + set.getName() + "\""; 349 public void actionPerformed(ActionEvent event) 350 { 351 MetadataSet metadata_set = (MetadataSet) set_list.getSelectedValue(); 352 Gatherer.c_man.removeMetadataSet(metadata_set); 353 refreshModel(); 354 element_list.setListData(new Vector()); 355 } 486 356 } 487 357 }
Note:
See TracChangeset
for help on using the changeset viewer.