- Timestamp:
- 2003-07-15T13:55:22+12:00 (21 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gli/src/org/greenstone/gatherer/cdm/FormatManager.java
r4675 r4932 6 6 * University of Waikato, New Zealand. 7 7 * 8 * <BR><BR>9 *10 8 * Author: John Thompson, Greenstone Digital Library, University of Waikato 11 9 * 12 * <BR><BR>13 *14 10 * Copyright (C) 1999 New Zealand Digital Library Project 15 *16 * <BR><BR>17 11 * 18 12 * This program is free software; you can redistribute it and/or modify … … 21 15 * (at your option) any later version. 22 16 * 23 * <BR><BR>24 *25 17 * This program is distributed in the hope that it will be useful, 26 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 27 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 20 * GNU General Public License for more details. 29 *30 * <BR><BR>31 21 * 32 22 * You should have received a copy of the GNU General Public License … … 35 25 *######################################################################## 36 26 */ 37 38 39 40 41 42 43 /* GPL_HEADER */44 27 package org.greenstone.gatherer.cdm; 45 28 /************************************************************************************** 46 * Title: Gatherer 47 * Description: The Gatherer: a tool for gathering and enriching a digital collection. 48 * Company: The University of Waikato 49 * Written: /05/02 50 * Revised: 04/10/02 - Commented 29 * Written: 06/05/02 30 * Revised: 04/10/02 - Commented 31 * 14/07/03 - DOM support 51 32 **************************************************************************************/ 52 import java.awt.BorderLayout; 53 import java.awt.CardLayout; 54 import java.awt.Color; 55 import java.awt.Dimension; 56 import java.awt.GridLayout; 57 import java.awt.event.ActionEvent; 58 import java.awt.event.ActionListener; 59 import java.awt.event.KeyAdapter; 60 import java.awt.event.KeyEvent; 61 import java.util.ArrayList; 62 import java.util.Collections; 63 import java.util.Vector; 64 import javax.swing.BorderFactory; 65 import javax.swing.BoxLayout; 66 import javax.swing.ButtonGroup; 67 import javax.swing.DefaultComboBoxModel; 68 import javax.swing.JButton; 69 import javax.swing.JCheckBox; 70 import javax.swing.JComboBox; 71 import javax.swing.JLabel; 72 import javax.swing.JList; 73 import javax.swing.JPanel; 74 import javax.swing.JScrollPane; 75 import javax.swing.JTabbedPane; 76 import javax.swing.JTextArea; 77 import javax.swing.JTextField; 78 import javax.swing.JToggleButton; 79 import javax.swing.ListSelectionModel; 80 import javax.swing.event.ListSelectionEvent; 81 import javax.swing.event.ListSelectionListener; 33 import java.awt.*; 34 import java.awt.event.*; 35 import java.util.*; 36 import javax.swing.*; 37 import javax.swing.event.*; 82 38 import org.greenstone.gatherer.Gatherer; 83 39 import org.greenstone.gatherer.cdm.Classifier; 84 40 import org.greenstone.gatherer.cdm.ClassifierManager; 41 import org.greenstone.gatherer.cdm.CollectionConfiguration; 85 42 import org.greenstone.gatherer.cdm.CollectionDesignManager; 86 43 import org.greenstone.gatherer.cdm.CommandTokenizer; 87 import org.greenstone.gatherer.cdm.DynamicListModel; 44 import org.greenstone.gatherer.cdm.Control; 45 import org.greenstone.gatherer.cdm.DOMProxyListModel; 88 46 import org.greenstone.gatherer.cdm.Format; 89 47 import org.greenstone.gatherer.msm.ElementWrapper; 90 48 import org.greenstone.gatherer.util.Utility; 49 import org.w3c.dom.*; 91 50 /** This class maintains a list of format statements, and allows the addition and removal of these statements. 92 51 * @author John Thompson, Greenstone Digital Library, University of Waikato … … 94 53 */ 95 54 public class FormatManager 96 extends DynamicListModel { 97 /** The main manager so we can get to ClassifierManager which is needed to turn position reference such as "CL1" into the appropriate Classifier. */ 98 private CollectionDesignManager manager = null; 55 extends DOMProxyListModel { 56 99 57 /** The controls used to edit the format commands. */ 100 58 private Control controls = null; 101 59 /** A reference to ourselves so inner classes can get at the model. */ 102 private DynamicListModel model = null; 103 /** A reference to the Gatherer. */ 104 private Gatherer gatherer = null; 105 /** We may have somehow recieved a format command which references a classifier that hasn't been parsed yet, so this variable holds a list of failed commands which are retried after the loading is complete. */ 106 private Vector unresolved_commands = null; 107 /** Constructor. 108 * @param gatherer A reference to the <strong>Gatherer</strong>. 109 * @param manager A reference to the <strong>CollectionDesignManager</strong> that created this manager. 110 */ 111 public FormatManager(Gatherer gatherer, CollectionDesignManager manager) { 112 super(); 113 this.gatherer = gatherer; 114 this.manager = manager; 60 private DOMProxyListModel model = null; 61 62 /** Constructor. */ 63 public FormatManager() { 64 super(CollectionDesignManager.collect_config.getDocumentElement(), CollectionConfiguration.FORMAT_ELEMENT, new Format()); 115 65 this.model = this; 116 this.unresolved_commands = new Vector(); 66 Gatherer.println("FormatManager: parsed " + getSize() + " format statements."); 67 // Establish all of the format objects, so that classifier indexes are initially correct (subsequent refreshes of the model will be sufficient to keep these up to date, as long as we start with a live reference to a classifier. 68 int size = getSize(); 69 for(int i = 0; i < size; i++) { 70 getElementAt(i); 71 } 117 72 } 118 73 /** Method to add a new format to this manager. … … 120 75 */ 121 76 public void addFormat(Format format) { 122 if(formatExists(format) == null) { 123 addElement(format); 124 gatherer.c_man.configurationChanged(); 125 } 126 } 127 /** Method which determines if a certain format exists, in which case it must be removed before a new format of the same component is added. For general formatting statements this compares types, for 'custom' ones it compares list and part. 128 * @param format The <strong>Format</strong> whose uniqueness we want to check. 129 * @return The <strong>Format</strong> that matches the one given, or <i>null</i> if no such format exists. 130 */ 131 public Format formatExists(Format format) { 132 for(int i = 0; i < size(); i++) { 133 Format current = (Format) get(i); 134 if(format.getPosition().equals(current.getPosition())) { 135 return current; 136 } 137 } 138 return null; 139 } 77 if(!contains(format)) { 78 Element element = format.getElement(); 79 // Locate where we should insert this new classifier. 80 Node target_node = CollectionConfiguration.findInsertionPoint(element); 81 add(root, format, target_node); 82 Gatherer.c_man.configurationChanged(); 83 } 84 } 85 86 public void destroy() { 87 if(controls != null) { 88 controls.destroy(); 89 controls = null; 90 } 91 } 92 140 93 /** Gets the format indicated by the index. 141 142 94 * @param index The location of the desired format, as an <i>int</i>. 95 */ 143 96 public Format getFormat(int index) { 144 return (Format)get(index); 145 } 97 Format result = null; 98 if(0 < index && index < getSize()) { 99 result = (Format) getElementAt(index); 100 } 101 return result; 102 } 103 146 104 /** Method to retrieve this managers controls. 147 * @return The <strong>Control</strong>for this collection.148 105 * @return the Control for this collection. 106 */ 149 107 public Control getControls() { 150 108 if(controls == null) { 151 controls = new Control();109 controls = new FormatControl(); 152 110 } 153 111 return controls; 154 112 } 155 /** Method to invalidate controls when some significant change has occured within the collection. */ 156 public void invalidateControls() { 157 if(controls != null) { 158 controls.destroy(); 159 } 160 controls = null; 161 } 162 /** This method attempts to parse a format command from the given string. If a format is parsed, it is immediately added to this managers list of format commands. 163 * @param command The <strong>String</strong> we are trying to parse a command from. 164 * @param finished A <i>boolean</i> which is <i>true</i> if we are calling this after the the input has been completely parsed (i.e all legal Classifiers are know to exist), or <i>false</i> otherwise. 165 * @return A <i>boolean</i> which is <i>true</i> if we managed to parse a command, <i>false</i> otherwise. 166 * @see org.greenstone.gatherer.cdm.Classifier 167 * @see org.greenstone.gatherer.cdm.CommandTokenizer 168 * @see org.greenstone.gatherer.cdm.Format 169 */ 170 public boolean parse(String command, boolean finished) { 171 String temp = command.toLowerCase(); 172 if(temp.startsWith("format")) { 173 if(finished) { 174 CommandTokenizer ct = new CommandTokenizer(command); 175 ct.nextToken(); // Throw away 'format' 176 String position = ct.nextToken(); 177 String value = ct.nextToken(); 178 // String speech marks. 179 if(value.startsWith("\"") && value.endsWith("\"")) { 180 if(value.equals("\"\"")) { 181 value = ""; 182 } 183 else { 184 value = value.substring(1, value.length() - 1); 185 } 186 } 187 // Ensure we parsed a good command. 188 if(position != null && value != null) { 189 // The trickiest bit of parsing format commands is figuring out how much of the position is feature, and how much part. Since the parts are far less likely to change or be customized in any way, we'll try to match them first (except "" of course). 190 String feature_name = null; 191 String part = null; 192 // If this works, then we're all finished. Yay. 193 for(int i = 1; i < Format.DEFAULT_PARTS.length; i++) { 194 if(position.endsWith(Format.DEFAULT_PARTS[i])) { 195 part = Format.DEFAULT_PARTS[i]; 196 feature_name = position.substring(0, position.length() - part.length()); 197 } 198 } 199 // Otherwise we can attempt to find the default features, but we have less chance of success. 200 if(feature_name == null || part == null) { 201 for(int i = 1; i < Format.DEFAULT_FEATURES.length; i++) { 202 if(position.startsWith(Format.DEFAULT_FEATURES[i])) { 203 feature_name = Format.DEFAULT_FEATURES[i]; 204 if(position.length() > feature_name.length()) { 205 part = position.substring(feature_name.length()); 206 } 207 else { 208 part = ""; 209 } 210 } 211 } 212 } 213 // Otherwise we can assume we are dealing with a classifier and split the position using... 214 // position ::= <classifier_position><part> 215 // classifier_position ::= <alphanum>[0-9]$ 216 // part ::= ^![0-9]<alpha> 217 // But I don't like my chances of this working if someone does a scary like CL4Part8B. I just have 218 // to hope no-one uses numbers, and no-one expects CustomFeatureCustomPart to parse properly. 219 if(feature_name == null || part == null) { 220 part = ""; 221 boolean found = false; 222 int index = position.length() - 1; 223 while(index >= 0 && !found) { 224 if(Character.isDigit(position.charAt(index))) { 225 found = true; 226 } 227 else { 228 part = position.charAt(index) + part; 229 index--; 230 } 231 } 232 if(found) { 233 feature_name = position.substring(0, index + 1); 234 } 235 // We ran out of string. No digits. Arg! 236 else { 237 part = null; 238 } 239 } 240 // And if all else fails, stick it all in feature. 241 if(feature_name == null || part == null) { 242 feature_name = position; 243 part = ""; 244 } 245 // Now try to retrieve a classifier with the feature name. 246 Object feature = null; 247 String feature_name_lc = feature_name.toLowerCase(); 248 if(feature_name_lc.startsWith("cl") && feature_name.length() >= 3) { 249 String raw_index = feature_name.substring(2); // Lose the 'CL' 250 int index = -1; 251 try { 252 index = Integer.parseInt(raw_index); 253 } 254 catch(NumberFormatException nfe) { 255 nfe.printStackTrace(); 256 } 257 feature = manager.classifiers.getClassifier(index - 1); 258 } 259 else { 260 ///ystem.err.println("name to short for classifier."); 261 } 262 if(feature == null) { 263 feature = feature_name; 264 } 265 ///ystem.err.println("Feature name = " + feature_name + "\nPart = " + part); 266 if(feature instanceof Classifier) { 267 ///ystem.err.println("Feature is a classifier."); 268 } 269 else { 270 ///ystem.err.println("Feature is a String."); 271 } 272 // Now we have a quick look at value. If its true or false we create a FLAG type 273 if(value.equalsIgnoreCase("true")) { 274 addFormat(new Format(feature, part, true)); 275 } 276 else if(value.equalsIgnoreCase("false")) { 277 addFormat(new Format(feature, part, false)); 278 } 279 // Otherwise add a plain old value based format 280 else { 281 addFormat(new Format(feature, part, value)); 282 } 283 return true; 284 } 285 // Somethings gone terribly, terribly wrong. 286 return false; 287 } 288 else { 289 // Ensure we have enough tokens for a format command 290 CommandTokenizer ct = new CommandTokenizer(command); 291 while(ct.countTokens() < 3) { 292 command = manager.parseMore(command); 293 ct = new CommandTokenizer(command); 294 } 295 unresolved_commands.add(command); 296 } 297 return true; 298 } 299 return false; 300 } 113 301 114 /** Method to remove a format. 302 303 115 * @param format The <strong>Format</strong> to remove. 116 */ 304 117 public void removeFormat(Format format) { 305 removeElement(format); 306 gatherer.c_man.configurationChanged(); 307 } 308 /** Method which attempts to reparse obvious format commands which previously referenced unresovable Classifiers. 309 */ 310 public void reparseUnresolved() { 311 for(int i = 0; i < unresolved_commands.size(); i++) { 312 if(!parse((String)unresolved_commands.get(i), true)) { 313 ///ystem.err.println("*** Error: Command " + unresolved_commands.get(i)); 314 } 315 } 316 // Regardless of if they work, clear the commands. 317 unresolved_commands.clear(); 318 } 319 /** Method to produce a block of text representing the format commands in this manager, ready to be used in the collection configuration file. 320 * @return A <strong>String</strong> containing a series of format commands. 321 */ 322 public String toString() { 323 StringBuffer text = new StringBuffer(""); 324 for(int i = 0; i < size(); i++) { 325 Format format = (Format) get(i); 326 text.append(format.toString()); 327 text.append("\n"); 328 } 329 text.append("\n"); 330 return text.toString(); 331 } 118 remove(format); 119 Gatherer.c_man.configurationChanged(); 120 } 121 332 122 /** Overloaded to call get with both a key and an empty argument array. 333 334 335 123 * @param key A <strong>String</strong> which is mapped to a initial String within the ResourceBundle. 124 * @return A <strong>String</strong> which has been referenced by the key String and that either contains no argument fields, or has had the argument fields automatiically populated with formatting Strings of with argument String provided in the get call. 125 */ 336 126 private String get(String key) { 337 127 return get(key, null); 338 128 } 129 339 130 /** Used to retrieve a property value from the Locale specific ResourceBundle, based upon the key and arguments supplied. If the key cannot be found or if some other part of the call fails a default (English) error message is returned. <BR> 340 341 342 343 344 345 346 131 * Here the get recieves a second argument which is an array of Strings used to populate argument fields, denoted {<I>n</I>}, within the value String returned. Note that argument numbers greater than or equal to 32 are automatically mapped to the formatting String named Farg<I>n</I>. 132 * @param key A <strong>String</strong> which is mapped to a initial String within the ResourceBundle. 133 * @param args A <strong>String[]</strong> used to populate argument fields within the complete String. 134 * @return A <strong>String</strong> which has been referenced by the key String and that either contains no argument fields, or has had the argument fields automatiically populated with formatting Strings of with argument String provided in the get call. 135 * @see org.greenstone.gatherer.Gatherer 136 * @see org.greenstone.gatherer.Dictionary 137 */ 347 138 private String get(String key, String args[]) { 348 139 if(key.indexOf('.') == -1) { 349 140 key = "CDM.FormatManager." + key; 350 141 } 351 return gatherer.dictionary.get(key, args); 352 } 353 private class Control 354 extends JPanel { 142 return Gatherer.dictionary.get(key, args); 143 } 144 145 private class FormatControl 146 extends JPanel 147 implements Control { 355 148 /** Do we ignore selection changing events (mainly because we're generating them!) */ 356 149 private boolean ignore = false; … … 404 197 private Vector part_model = null; 405 198 private Vector special_model = null; 406 public Control() { 407 ArrayList feature_model = new ArrayList(); 408 // Add the set options 409 for(int i = 0; i < Format.DEFAULT_FEATURES.length; i++) { 410 feature_model.add(new Entry(Format.DEFAULT_FEATURES[i])); 411 } 412 // Now the classifiers. 413 for(int j = 0; j < manager.classifiers.size(); j++) { 414 feature_model.add(new Entry(manager.classifiers.getClassifier(j))); 415 } 416 Collections.sort(feature_model); 199 public FormatControl() { 200 ArrayList feature_model = buildFeatureModel(); 417 201 part_model = new Vector(); 418 202 part_model.add("");//get("Custom")); … … 430 214 special_model.add("[parent(Top):_]"); 431 215 special_model.add("[parent(All'_'):_]"); 432 Vector elements = gatherer.c_man.msm.getAssignedElements();216 Vector elements = Gatherer.c_man.getCollection().msm.getAssignedElements(); 433 217 for(int i = 0; i < elements.size(); i++) { 434 218 special_model.add("[" + ((ElementWrapper)elements.get(i)).toString() + "]"); 435 219 } 436 220 Collections.sort(special_model); 437 221 // Create 438 222 add = new JButton(get("Add")); 439 223 add.setEnabled(false); … … 443 227 control_pane = new JPanel(); 444 228 editor = new JTextArea(); 445 editor.setBackground( Color.white);229 editor.setBackground(Gatherer.config.getColor("coloring.editable", false)); 446 230 editor.setCaretPosition(0); 447 231 editor.setLineWrap(true); 448 editor.setWrapStyleWord( true);232 editor.setWrapStyleWord(false); 449 233 editor_label = new JLabel(get("Editor")); 450 234 editor_label.setHorizontalAlignment(JLabel.CENTER); … … 496 280 value_pane = new JPanel(); 497 281 view_pane = new JPanel(); 498 282 // Connect 499 283 add.addActionListener(new AddListener()); 500 284 button_group.add(on); 501 285 button_group.add(off); 502 editor. addKeyListener(new EditorListener());286 editor.getDocument().addDocumentListener(new EditorListener()); 503 287 feature.addActionListener(new FeatureListener()); 504 288 format_list.addListSelectionListener(new FormatListListener()); … … 596 380 ready = true; 597 381 } 382 598 383 public void destroy() { 599 384 } 385 600 386 /** Overriden to ensure that the instructions pane is scrolled to the top. 601 */ 602 public void updateUI() { 387 */ 388 public void gainFocus() { 389 // This is only necessary if the components have been realized 603 390 if(ready) { 604 // Rebuild feature model. 605 ArrayList feature_model = new ArrayList(); 606 // Add the set options 607 for(int i = 0; i < Format.DEFAULT_FEATURES.length; i++) { 608 feature_model.add(new Entry(Format.DEFAULT_FEATURES[i])); 609 } 610 // Now the classifiers. 611 for(int j = 0; j < manager.classifiers.size(); j++) { 612 feature_model.add(new Entry(manager.classifiers.getClassifier(j))); 613 } 391 model.refresh(); 392 ArrayList feature_model = buildFeatureModel(); 393 // Remember the current selection 394 Object selected_object = feature.getSelectedItem(); 614 395 feature.setModel(new DefaultComboBoxModel(feature_model.toArray())); 396 // Now resotre the selected object as best as possible 397 feature.setSelectedItem(selected_object); 615 398 if(instructions != null) { 616 399 instructions.setCaretPosition(0); 617 400 } 618 } 619 super.updateUI(); 620 } 621 622 401 } 402 } 403 404 public void loseFocus() { 405 // Force all of the Formats to update their names with the correct values. 406 int size = model.getSize(); 407 for(int i = 0; i < size; i++) { 408 Format format = (Format) model.getElementAt(i); 409 format.update(); 410 } 411 } 412 413 private ArrayList buildFeatureModel() { 414 // Rebuild feature model. 415 ArrayList feature_model = new ArrayList(); 416 // Add the set options 417 for(int i = 0; i < Format.DEFAULT_FEATURES.length; i++) { 418 feature_model.add(new Entry(Format.DEFAULT_FEATURES[i])); 419 } 420 // Now the classifiers. 421 for(int j = 0; j < CollectionDesignManager.classifier_manager.getSize(); j++) { 422 feature_model.add(new Entry(CollectionDesignManager.classifier_manager.getClassifier(j))); 423 } 424 Collections.sort(feature_model); 425 return feature_model; 426 } 623 427 624 428 /** Formats the formatting string so that it contains safe characters and isn't enclosed in speech marks etc. (Ironic eh?) 625 626 429 * @see java.lang.StringBuffer 430 */ 627 431 private String format(String raw) { 628 432 String safe = null; … … 665 469 return raw; 666 470 } 471 667 472 /** Listens for clicks on the add button, and if the relevant details are provided adds a new format. */ 668 473 private class AddListener 669 474 implements ActionListener { 670 475 public void actionPerformed(ActionEvent event) { 671 ignore = true;476 //ignore = true; 672 477 Entry entry = (Entry)feature.getSelectedItem(); 673 478 Object f = entry.getFeature(); … … 685 490 format_list.setSelectedValue(current_format, true); 686 491 new_entry = false; 687 ignore = false; 688 } 689 } 492 //ignore = false; 493 } 494 } 495 690 496 private class EditorListener 691 extends KeyAdapter { 692 public void keyReleased(KeyEvent event) { 497 implements DocumentListener { 498 499 public void changedUpdate(DocumentEvent e) { 500 update(); 501 } 502 503 public void insertUpdate(DocumentEvent e) { 504 update(); 505 } 506 507 public void removeUpdate(DocumentEvent e) { 508 update(); 509 } 510 511 public void update() { 693 512 String safe = format(editor.getText()); 694 513 if(!ignore && current_format != null) { … … 700 519 current_format.setValue(""); 701 520 } 702 gatherer.c_man.configurationChanged();703 model.refresh( );521 Gatherer.c_man.configurationChanged(); 522 model.refresh(current_format); 704 523 } 705 524 Entry entry = (Entry) feature.getSelectedItem(); … … 713 532 } 714 533 } 534 715 535 /** This object provides a wrapping around an entry in the format target control, which is tranparent as to whether it is backed by a String or a Classifier. */ 716 536 private class Entry … … 781 601 } 782 602 } 603 783 604 private class FeatureListener 784 605 implements ActionListener { … … 788 609 Entry entry = (Entry) feature.getSelectedItem(); 789 610 String name = entry.toString(); 790 int type = Format.getType(name); 791 switch(type) { 792 case Format.FLAG: 611 if(Format.isParamType(name)) { 793 612 // Flags first. 794 613 part.setEnabled(false); … … 797 616 view_type = FLAG; 798 617 add.setEnabled(true); // One of the options must be selected. 799 break;800 default:618 } 619 else { 801 620 part.setEnabled(true); 802 621 part_pane.add(part, BorderLayout.CENTER); … … 815 634 } 816 635 } 636 817 637 private class FormatListListener 818 638 implements ListSelectionListener { … … 825 645 Entry an_entry = new Entry(current_format.getFeature()); 826 646 feature.setSelectedItem(an_entry); 827 // Try to match the part. 828 part.setSelectedItem(current_format.getPart()); 647 // If we didn't match anything, add it and select it again 648 Entry result_entry = (Entry) feature.getSelectedItem(); 649 if(!an_entry.equals(result_entry)) { 650 feature.insertItemAt(an_entry, feature.getItemCount()); 651 feature.setSelectedItem(an_entry); 652 } 653 654 if(current_format.canHavePart()) { 655 part.setEnabled(true); 656 // Try to match the part. 657 String part_entry = current_format.getPart(); 658 part.setSelectedItem(part_entry); 659 // If we didn't match anything, add it and select it again 660 String selected_part = (String)part.getSelectedItem(); 661 if(!part_entry.equals(selected_part)) { 662 part.insertItemAt(part_entry, part.getItemCount()); 663 feature.setSelectedItem(part_entry); 664 } 665 } 666 else { 667 part.setEnabled(false); 668 } 829 669 // Now use type to determine what controls are visible, and what have initial values. 830 switch(current_format.getType()) { 831 case Format.FLAG: 670 if(current_format.isParamType()) { 832 671 // Flags first. 833 672 part.setEnabled(false); … … 839 678 off.setSelected(!current_format.getState()); 840 679 add.setEnabled(false); // Can only update 841 break;842 default:680 } 681 else { 843 682 part.setEnabled(true); 844 683 part_pane.add(part, BorderLayout.CENTER); … … 907 746 // We have just performed an edit. Immediately update the format and model. 908 747 current_format.setState(on.isSelected()); 909 model.refresh( );748 model.refresh(current_format); 910 749 } 911 750 } … … 917 756 // We have just performed an edit. Immediately update the format and model. 918 757 current_format.setValue(value.getText()); 919 model.refresh( );758 model.refresh(current_format); 920 759 } 921 760 }
Note:
See TracChangeset
for help on using the changeset viewer.