Ticket #2394: templatedialog.patch
File templatedialog.patch, 24.8 KB (added by boyanl, 15 years ago) |
---|
-
modules/org.sophie2.base.commons/src/main/java/org/sophie2/base/commons/gui/TriStateCheckBox.java
### Eclipse Workspace Patch 1.0 #P sophie
1 package org.sophie2.base.commons.gui; 2 3 import java.awt.Color; 4 import java.awt.Graphics; 5 import java.awt.Graphics2D; 6 7 import javax.swing.JCheckBox; 8 import javax.swing.JToggleButton; 9 10 /** 11 * A tri-check box control, extending JCheckBox 12 * 13 * @author boyanl 14 */ 15 public class TriStateCheckBox extends JCheckBox { 16 17 /** 18 * Serial version ID for the class. 19 */ 20 private static final long serialVersionUID = 953941340362829945L; 21 22 /** 23 * Enumerates the possible states of the checkbox 24 */ 25 public static enum State { 26 /** 27 * Represents checked state 28 */ 29 CHECKED, 30 /** 31 * Represents unchecked state 32 */ 33 UNCHECKED, 34 /** 35 * Represents partial state 36 */ 37 PARTIAL 38 } 39 40 /** 41 * Creates an initially unselected check box button with no text, no icon. 42 */ 43 public TriStateCheckBox() { 44 this(null, State.UNCHECKED); 45 } 46 47 /** 48 * Creates a check box with text and icon, 49 * and specifies whether or not it is initially selected. 50 * 51 * @param text 52 * The text of the check box. 53 * @param initial 54 * A value indicating the initial selection state. 55 */ 56 public TriStateCheckBox(String text, State initial) { 57 super.setText(text); 58 setModel(new TriStateModel(initial)); 59 60 //some UI settings 61 setRolloverEnabled( false ); 62 } 63 64 65 /** 66 * Set the new state to either CHECKED, PARTIAL or UNCHECKED. 67 * @param state 68 * The new state to set. 69 */ 70 public void setState(State state) { 71 ((TriStateModel) this.model).setState(state); 72 } 73 74 /** 75 * Return the current state, which is determined by the selection status of 76 * the model. 77 * 78 * @return 79 * The state of the checkbox (gets it from the model). 80 */ 81 public State getState() { 82 return ((TriStateModel) this.model).getState(); 83 } 84 85 @Override 86 public void setSelected(boolean selected) { 87 ((TriStateModel) this.model).setSelected(selected); 88 } 89 90 91 @Override 92 public void paintComponent( Graphics g ) { 93 super.paintComponent( g ); 94 95 if(((TriStateModel) this.model).getState() == State.PARTIAL) { 96 //this.getModel().setArmed(false); 97 Graphics2D g2 = (Graphics2D) g; 98 99 int cx = getWidth()/4, width = getWidth()/2 - 1; 100 int cy = getHeight()/4, height = getHeight()/2 - 1 ; 101 102 g2.setColor(Color.blue); 103 g2.fillRect( cx, cy, width , height ); 104 } 105 } 106 107 /** 108 * The model for the button 109 */ 110 public static class TriStateModel extends JToggleButton.ToggleButtonModel { 111 /** 112 * The serial version ID for this class. 113 */ 114 private static final long serialVersionUID = 1980283253004401043L; 115 /** 116 * Contains the state of the model 117 */ 118 protected State state; 119 120 /** 121 * Creates a new model by a given state. 122 * 123 * @param state 124 * Constructs the model from a given state. 125 */ 126 public TriStateModel(State state) { 127 this.state = state; 128 } 129 130 /** 131 * Gets the state of the model. 132 * 133 * @return 134 * The state of the model. 135 */ 136 public State getState() { 137 return this.state; 138 } 139 140 /** 141 * Sets the state of the model 142 * 143 * @param state 144 * The new state of the model. 145 */ 146 public void setState(State state) { 147 this.state = state; 148 // fireStateChanged(); 149 } 150 151 @Override 152 public void setPressed(boolean pressed) { 153 if (pressed) { 154 switch(this.state) { 155 case UNCHECKED: 156 this.state = State.CHECKED; 157 break; 158 case PARTIAL: 159 this.state = State.UNCHECKED; 160 break; 161 case CHECKED: 162 this.state = State.UNCHECKED; 163 break; 164 } 165 } 166 } 167 168 @Override 169 public boolean isSelected() { 170 return this.state == State.CHECKED; 171 } 172 173 @Override 174 public void setSelected(boolean selected) { 175 if (selected) { 176 this.state = State.CHECKED; 177 } else { 178 this.state = State.UNCHECKED; 179 } 180 } 181 } 182 } 183 No newline at end of file -
modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/dialogs/TemplateDialog.java
9 9 import java.awt.event.ActionListener; 10 10 import java.awt.event.FocusEvent; 11 11 import java.awt.event.FocusListener; 12 import java.awt.event.MouseAdapter; 13 import java.awt.event.MouseEvent; 14 import java.util.Enumeration; 12 15 import java.util.HashMap; 13 16 import java.util.Map; 14 17 import java.util.Set; … … 21 24 import javax.swing.JPanel; 22 25 import javax.swing.JScrollPane; 23 26 import javax.swing.JTextField; 27 import javax.swing.JTree; 28 import javax.swing.tree.DefaultMutableTreeNode; 29 import javax.swing.tree.DefaultTreeModel; 30 import javax.swing.tree.TreeCellRenderer; 31 import javax.swing.tree.TreeModel; 32 import javax.swing.tree.TreePath; 24 33 25 34 import org.sophie2.base.bound.BoundCheckBox; 26 35 import org.sophie2.base.bound.BoundControl; 27 36 import org.sophie2.base.bound.BoundGroupCheckBox; 28 37 import org.sophie2.base.bound.BoundControl.EventIds; 38 import org.sophie2.base.commons.gui.TriStateCheckBox; 29 39 import org.sophie2.base.commons.util.ImmList; 30 40 import org.sophie2.base.commons.util.NaiveImmList; 31 41 import org.sophie2.base.dialogs.Dialog; … … 37 47 import org.sophie2.base.visual.skins.ElementSkinPart; 38 48 import org.sophie2.base.visual.skins.SkinPartDef; 39 49 import org.sophie2.core.mvc.EventFilterBuilder; 40 import org.sophie2.core.mvc.LogicR3;41 50 import org.sophie2.core.mvc.OperationDef; 42 51 import org.sophie2.core.mvc.events.EventR3; 43 52 import org.sophie2.core.prolib.interfaces.RwProp; 53 import org.sophie2.main.app.commons.dialogs.CheckBoxTree.CheckNode; 44 54 45 55 /** 56 * A checkbox tree class which extends (and internally uses) JTree. 57 * 58 * @author boyanl 59 */ 60 class CheckBoxTree extends JTree 61 { 62 /** 63 * Serial version ID for the class. 64 */ 65 private static final long serialVersionUID = -6024233811457619061L; 66 67 /** 68 * A node class for the tree. It contains just the logical data of a node (in this case, a tricheck model), 69 * and a backlink to the container tree (needed for the update logic). 70 * 71 * @author boyanl 72 */ 73 public static class CheckNode extends DefaultMutableTreeNode { 74 /** 75 * Serial version ID for the class. 76 */ 77 private static final long serialVersionUID = 1701971996798985354L; 78 79 /** 80 * A backlink to the containing tree. Needed for the visual update of items 81 * in setState 82 */ 83 private JTree backlink; 84 private TriStateCheckBox.TriStateModel state; 85 /** 86 * Default constructor 87 */ 88 public CheckNode() { 89 this(null); 90 } 91 92 /** 93 * @param link 94 * The backlink value to set to. 95 */ 96 void setBacklink(JTree link) { 97 this.backlink = link; 98 } 99 100 /** 101 * Constructs the node from a user-defined object (just String is used here, for the label text). 102 * 103 * @param userObject 104 * The user-defined object to construct from. 105 */ 106 public CheckNode(Object userObject) { 107 this(userObject, true, false); 108 } 109 110 /** 111 * Constructs the node from a user-defined object and sets whether the node allows children and is selected. 112 * @param userObject 113 * The user-passed object. 114 * @param allowsChildren 115 * A parameter indicating whether the node allows children. 116 * @param isSelected 117 * A parameter indicating whether the node is selected. 118 */ 119 public CheckNode(Object userObject, boolean allowsChildren, 120 boolean isSelected) { 121 super(userObject, allowsChildren); 122 this.state = new TriStateCheckBox.TriStateModel(TriStateCheckBox.State.UNCHECKED); 123 this.state.setSelected(isSelected); 124 } 125 126 /** 127 * Gets the state of the check node. 128 * 129 * @return The state of the node 130 */ 131 public TriStateCheckBox.State getState () { 132 return this.state.getState(); 133 } 134 135 /** 136 * Changes the state of the node to the "next" state. 137 */ 138 public void nextState () { 139 this.state.setPressed(true); 140 this.setState (this.state.getState()); 141 } 142 143 /** 144 * Sets the state of the node. Propagates the changes to children/parent if necessary. 145 * 146 * @param newState 147 * The new state. 148 */ 149 @SuppressWarnings("unchecked") 150 public void setState (TriStateCheckBox.State newState) { 151 this.state.setState (newState); 152 ((DefaultTreeModel) this.backlink.getModel ()).nodeChanged (this); 153 154 // propagate changes to children (if any) 155 if (this.children != null && newState != TriStateCheckBox.State.PARTIAL) { 156 Enumeration<CheckNode> e = this.children.elements(); 157 158 while (e.hasMoreElements()) { 159 CheckNode node = e.nextElement(); 160 161 if (node.getState() != newState) { 162 node.setState(newState); 163 ((DefaultTreeModel) this.backlink.getModel ()).nodeChanged (node); 164 } 165 } 166 } 167 168 //propagate to parent (if any) 169 if (this.getParent() != null) { 170 /* If either all the nodes are selected or all are de-selected, change the state 171 * to selected/de-selected. Otherwise, partial 172 */ 173 boolean allSelected = true, noneSelected = true; 174 Enumeration<CheckNode> e = this.parent.children(); 175 176 while (e.hasMoreElements()) { 177 CheckNode node = e.nextElement(); 178 if (node.getState () != TriStateCheckBox.State.CHECKED) { 179 allSelected = false; 180 } 181 if (node.getState () != TriStateCheckBox.State.UNCHECKED) { 182 noneSelected = false; 183 } 184 if (!allSelected && !noneSelected) { 185 break; 186 } 187 } 188 189 if (allSelected) { 190 ((CheckNode) this.parent).setState (TriStateCheckBox.State.CHECKED); 191 ((DefaultTreeModel) this.backlink.getModel ()).nodeChanged (this.parent); 192 } else if (noneSelected) { 193 ((CheckNode) this.parent).setState (TriStateCheckBox.State.UNCHECKED); 194 ((DefaultTreeModel) this.backlink.getModel ()).nodeChanged (this.parent); 195 } else { 196 ((CheckNode) this.parent).setState (TriStateCheckBox.State.PARTIAL); 197 ((DefaultTreeModel) this.backlink.getModel ()).nodeChanged (this.parent); 198 } 199 } 200 } 201 /** 202 * Changes the node and updates children/parent accordingly 203 * @param isSelected 204 * The new state of the node 205 */ 206 public void setSelected(boolean isSelected) { 207 this.state.setSelected(isSelected); 208 setState (this.state.getState()); 209 } 210 211 /** 212 * Getter for the isSelected field 213 * @return The field 214 * 215 */ 216 public boolean isSelected() { 217 return this.state.isSelected(); 218 } 219 } 220 221 /** 222 * A renderer class for the tree. Contains the checkbox and the label used to 223 * visualize a node in the tree 224 * @author boyanl 225 * 226 */ 227 class CheckRenderer extends JPanel implements TreeCellRenderer { 228 229 /** 230 * Serial Version ID for the class. 231 */ 232 private static final long serialVersionUID = 6223558893132192535L; 233 private TriStateCheckBox check; 234 private JLabel label; 235 236 /** 237 * Default constructor, initializes the checkbox and the label 238 */ 239 CheckRenderer() { 240 setLayout(null); 241 add(this.check = new TriStateCheckBox()); 242 add(this.label = new JLabel ()); 243 } 244 245 public Component getTreeCellRendererComponent( 246 JTree tree, Object value, 247 boolean isSelected, boolean expanded, boolean leaf, int row, 248 boolean hasFocus) { 249 250 String stringValue = tree.convertValueToText(value, isSelected, 251 expanded, leaf, row, hasFocus); 252 setEnabled(tree.isEnabled()); 253 this.label.setText (stringValue); 254 this.check.setState(((CheckNode) value).getState()); 255 return this; 256 } 257 258 @Override 259 public Dimension getPreferredSize() { 260 Dimension d_check = this.check.getPreferredSize(); 261 Dimension d_label = this.label.getPreferredSize(); 262 return new Dimension(d_check.width + d_label.width, 263 (d_check.height < d_label.height ? d_label.height 264 : d_check.height)); 265 } 266 267 /** 268 * Layouts the component, centering the label and the checkbox height-wise 269 */ 270 @Override 271 public void doLayout() { 272 Dimension d_check = this.check.getPreferredSize(); 273 Dimension d_label = this.label.getPreferredSize(); 274 275 int y_check = 0; 276 int y_label = 0; 277 if (d_check.height < d_label.height) { 278 y_check = (d_label.height - d_check.height) / 2; 279 } else { 280 y_label = (d_check.height - d_label.height) / 2; 281 } 282 this.check.setLocation(0, y_check); 283 this.check.setBounds(0, y_check, d_check.width, d_check.height); 284 this.label.setLocation(d_check.width, y_label); 285 this.label.setBounds(d_check.width, y_label, d_label.width, d_label.height); 286 } 287 } 288 289 private class NodeSelectionListener extends MouseAdapter { 290 private JTree tree; 291 292 NodeSelectionListener(final JTree tree) { 293 this.tree = tree; 294 } 295 296 @Override 297 public void mouseClicked (MouseEvent e) { 298 int x = e.getX (); 299 int y = e.getY (); 300 int row = this.tree.getRowForLocation(x, y); 301 TreePath path = this.tree.getPathForRow (row); 302 303 if (path != null) { 304 CheckNode node = (CheckNode) path.getLastPathComponent(); 305 node.nextState(); 306 } 307 } 308 } 309 310 /** 311 * Adds a new node with a given text and parent node to the tree 312 * @param nodeText 313 * The text 314 * @param parent 315 * The parent 316 * @return 317 * The added node 318 */ 319 public CheckNode addNode (String nodeText, CheckNode parent) { 320 CheckNode node = new CheckNode (nodeText); 321 if (parent != null){ 322 parent.add(node); 323 } 324 node.setBacklink(this); 325 return node; 326 } 327 /** 328 * Adds a new node with a given text and parent node to the tree 329 * @param nodeText 330 * The text 331 * @return 332 * The added node 333 */ 334 public CheckNode addNode (String nodeText) { 335 CheckNode node = new CheckNode (nodeText); 336 CheckNode root = ((CheckNode) this.getModel ().getRoot ()); 337 if (root!= null) { 338 root.add(node); 339 } 340 node.setBacklink(this); 341 return node; 342 } 343 344 /** 345 * @return The root node of the tree 346 */ 347 public CheckNode getRootNode () { 348 return (CheckNode) this.getModel().getRoot(); 349 } 350 351 /** 352 * Constructs a tree with a given root name 353 * @param rootName 354 * the root name 355 */ 356 public CheckBoxTree (final String rootName) 357 { 358 super(); 359 CheckNode root = new CheckNode (rootName); 360 TreeModel model = new DefaultTreeModel (root); 361 setModel (model); 362 363 root.setBacklink (this); 364 setCellRenderer (new CheckRenderer()); 365 addMouseListener(new NodeSelectionListener(this)); 366 } 367 } 368 369 370 371 372 /** 46 373 * The dialog which is used to add a page or frame as a template. It generates a 47 374 * tree-like structure of checkboxes which represent the {@link Key}s of the 48 375 * object to create a template from. … … 131 458 private JDialog dialog = null; 132 459 private JPanel mainPanel; 133 460 private JLabel titleLabel = null; 134 private J Panel checkboxPanel= null;461 private JScrollPane treeScrollPane = null; 135 462 private JTextField titleField = null; 136 463 private JButton okButton = null; 137 464 private JButton cancelButton = null; 138 465 private JButton selectAllButton = null; 139 466 private JButton selectNoneButton = null; 140 private BoundGroupCheckBox topLevelCheckBox= null;141 private Map<Key<?>, SubCheckBox> keyMap = null;467 private CheckBoxTree checkBoxTree = null; 468 private Map<Key<?>, CheckBoxTree.CheckNode> keyMap = null; 142 469 private HashMap<Key<?>, Boolean> keyStates = null; 143 private SubCheckBox isDefaultTemplateCheckBox= null;470 private CheckNode isDefaultTemplateNode = null; 144 471 145 472 /** 146 473 * Holds the initial info for the dialog. … … 194 521 JPanel bottom = new JPanel(); 195 522 bottom.add(getOkButton()); 196 523 bottom.add(getCancelButton()); 197 198 JScrollPane scrollPane = new JScrollPane(getCheckboxPanel());199 524 525 this.treeScrollPane = new JScrollPane(); 526 200 527 this.mainPanel.add(top, BorderLayout.NORTH); 201 this.mainPanel.add( scrollPane, BorderLayout.CENTER);528 this.mainPanel.add(this.treeScrollPane, BorderLayout.CENTER); 202 529 this.mainPanel.add(bottom, BorderLayout.SOUTH); 203 530 204 531 this.mainPanel.setSize(PANEL_WIDTH, PANEL_HEIGHT); … … 207 534 } 208 535 209 536 /** 210 * Getter for the check box with the default template value.211 *212 * @return213 * The check box for the default template.214 */215 public SubCheckBox getIsDefaultTemplateCheckBox() {216 if(this.isDefaultTemplateCheckBox == null) {217 this.isDefaultTemplateCheckBox = new SubCheckBox() {218 @Override219 public String computeTitle() {220 return DEFAULT_TEMPLATE_CHECK_BOX_LABEL;221 }222 223 @Override224 public Boolean getDefault() {225 return false;226 }227 };228 }229 return this.isDefaultTemplateCheckBox;230 }231 /**232 537 * Getter for the title field. 233 538 * 234 539 * @return The title {@link JTextField}. … … 285 590 @SuppressWarnings("synthetic-access") 286 591 public void actionPerformed(final ActionEvent e) { 287 592 String title = getTitleField().getText(); 288 boolean isDefault = getIsDefaultTemplateCheckBox().value().get();593 boolean isDefault = SwingDialog.this.isDefaultTemplateNode.isSelected(); 289 594 290 595 SwingDialog.this.keyStates = new HashMap<Key<?>, Boolean>(); 291 for (Entry<Key<?>, SubCheckBox> entry : SwingDialog.this.keyMap.entrySet()) {292 SwingDialog.this.keyStates.put(entry.getKey(), entry.getValue(). value().get());596 for (Entry<Key<?>, CheckNode> entry : SwingDialog.this.keyMap.entrySet()) { 597 SwingDialog.this.keyStates.put(entry.getKey(), entry.getValue().isSelected()); 293 598 } 294 599 295 600 TemplateInfo res = new TemplateInfo(title, SwingDialog.this.keyStates, isDefault); 296 601 297 602 setResultInfo(res); 298 603 SwingDialog.this.dialog.setVisible(false); 299 SwingDialog.this.isDefaultTemplateCheckBox.value().set(false);300 604 } 301 605 302 606 }); … … 338 642 this.selectAllButton.addActionListener(new ActionListener() { 339 643 @SuppressWarnings("synthetic-access") 340 644 public void actionPerformed(final ActionEvent e) { 341 LogicR3.fire(SwingDialog.this.topLevelCheckBox, null, 342 null, null, BoundControl.EventIds.SUBMIT, true); 645 SwingDialog.this.checkBoxTree.getRootNode().setSelected(true); 343 646 } 344 647 }); 345 648 } … … 357 660 this.selectNoneButton.addActionListener(new ActionListener() { 358 661 @SuppressWarnings("synthetic-access") 359 662 public void actionPerformed(final ActionEvent e) { 360 LogicR3.fire(SwingDialog.this.topLevelCheckBox, null, 361 null, null, 362 BoundControl.EventIds.SUBMIT, false); 663 SwingDialog.this.checkBoxTree.getRootNode().setSelected(false); 363 664 } 364 665 }); 365 666 } … … 367 668 } 368 669 369 670 /** 370 * Getter for the panel containing the checkboxes.371 *372 * @return The {@link JPanel} which contains the checkboxes.373 */374 public JPanel getCheckboxPanel() {375 if (this.checkboxPanel == null) {376 this.checkboxPanel = new JPanel();377 }378 return this.checkboxPanel;379 }380 381 /**382 671 * Performs setup of the dialog - sets up the title and the panel with 383 672 * the checkboxes. 384 673 */ 385 @SuppressWarnings("synthetic-access")386 674 private void setup() { 387 675 getTitleField().setText(this.initialInfo.getTitle()); 388 676 389 this.checkboxPanel.removeAll(); 390 this.keyMap = new HashMap<Key<?>, SubCheckBox>(); 677 this.keyMap = new HashMap<Key<?>, CheckNode>(); 391 678 this.keyStates = new HashMap<Key<?>, Boolean>(); 392 679 393 this.topLevelCheckBox = new TopCheckBox() { 394 @Override 395 public String computeTitle() { 396 return SwingDialog.this.initialInfo.getTitle(); 397 } 398 }; 399 getCheckboxPanel().add(this.topLevelCheckBox.swingComponent().get()); 400 401 this.topLevelCheckBox.subControls().add(getIsDefaultTemplateCheckBox()); 680 this.checkBoxTree = new CheckBoxTree (this.initialInfo.getTitle ()); 681 this.isDefaultTemplateNode = this.checkBoxTree.addNode (DEFAULT_TEMPLATE_CHECK_BOX_LABEL); 402 682 683 this.treeScrollPane.setViewportView(this.checkBoxTree); 403 684 Set<Key<?>> keys = this.initialInfo.getKeyStates().keySet(); 404 for (final Key<?> key : keys) { 405 if (key instanceof TemplatedKey && key.getParts().size() == 1) { 406 Boolean state = this.initialInfo.getKeyStates().get(key); 407 addTemplatedKey(this.topLevelCheckBox, (TemplatedKey)key, state, this.keyMap, this.keyStates); 408 } else if (key instanceof CompositeKey) { 409 TopCheckBox composite = new TopCheckBox() { 410 @Override 411 public String computeTitle() { 412 ImmList<String> parts = key.getParts(); 413 return parts.get(parts.size() - 1); 414 } 415 }; 416 this.topLevelCheckBox.subControls().add(composite); 417 418 String prefix = key.getId().concat(Key.SEPARATOR); 419 for (final Key<?> subKey : keys) { 420 String keyId = subKey.getId(); 421 if (subKey instanceof TemplatedKey && keyId.startsWith(prefix)) { 422 Boolean state = this.initialInfo.getKeyStates().get(subKey); 423 addTemplatedKey(composite, (TemplatedKey)subKey, state, this.keyMap, this.keyStates); 424 } 425 } 426 } 685 for (final Key<?> key : keys) { 686 addKey(this.checkBoxTree.getRootNode(), key, this.initialInfo.getKeyStates().get(key), this.keyMap, keys, 1); 427 687 } 688 689 this.checkBoxTree.expandPath(new TreePath (this.checkBoxTree.getRootNode())); 428 690 } 429 691 430 692 /* 431 * Helper method to reduce code duplication. 693 * Helper method to build the tree, 694 * adds the key if he's at the appropriate level 432 695 */ 433 696 @SuppressWarnings("synthetic-access") 434 private static void addTemplatedKey(BoundGroupCheckBox container, 435 final TemplatedKey<?> key, final Boolean state, Map<Key<?>, SubCheckBox> keyMap, HashMap<Key<?>, Boolean> keyStates) { 436 if (!HIDDEN_KEYS.contains(key)) { 437 SubCheckBox subCheckbox = new SubCheckBox() { 438 @Override 439 public String computeTitle() { 440 ImmList<String> parts = key.getParts(); 441 return parts.get(parts.size() - 1); 697 private void addKey (CheckNode parent, final Key<?> key, final Boolean state, Map<Key<?>, CheckNode> keyControlMap, Set<Key<?>> keys, int level) { 698 if (key instanceof TemplatedKey) { 699 if (!HIDDEN_KEYS.contains((TemplatedKey) key) && key.getParts().size() == level) { 700 ImmList<String> parts = key.getParts(); 701 String text = parts.get(parts.size() - 1); 702 703 CheckNode node = this.checkBoxTree.addNode(text, parent); 704 node.setSelected(state); 705 keyControlMap.put(key, node); 706 } 707 } 708 709 else if (key instanceof CompositeKey && key.getParts().size() == level) { 710 ImmList<String> parts = key.getParts(); 711 String text = parts.get(parts.size() - 1); 712 713 CheckNode node = this.checkBoxTree.addNode(text, parent); 714 715 String prefix = key.getId().concat(Key.SEPARATOR); 716 for (final Key<?> subKey : keys) { 717 String keyId = subKey.getId(); 718 if (keyId.startsWith(prefix)) { 719 Boolean subState = this.initialInfo.getKeyStates().get(subKey); 720 addKey(node, subKey, subState, this.keyMap, keys, level + 1); 442 721 } 443 444 @Override 445 public Boolean getDefault() { 446 return state; 447 } 448 }; 449 450 container.subControls().add(subCheckbox); 451 keyMap.put(key, subCheckbox); 452 keyStates.put(key, state); 722 } 723 453 724 } 454 725 } 455 726