001: package org.osbl.agent.gui;
002:
003: import java.awt.event.ActionEvent;
004: import java.awt.event.ActionListener;
005: import java.awt.*;
006: import java.util.List;
007:
008: import org.wings.*;
009:
010: /**
011: * Represents a line (slot) in the {@link RuleEditorPanel} with controls to visually manipulate
012: * Conditions or Actions.
013: *
014: * @author Sebastian Nozzi.
015: */
016: abstract public class OperationPanel extends SPanel {
017:
018: /** The component count. */
019: private int componentCount;
020:
021: /** The first field, the combo with all OperationControllers. */
022: protected SComboBox controllerCombo;
023:
024: private final GridBagConstraints layoutConstraints = new GridBagConstraints(
025: -1, -1, 1, 1, 0, 0, SConstants.RIGHT,
026: GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0);
027:
028: /** The Rule Editor. */
029: protected RuleEditorPanel ruleEditorPanel;
030:
031: /**
032: * Instantiates a new OperationPanel for the given editor.
033: *
034: * @param ruleEditorPanel the Rule Editor object.
035: */
036: public OperationPanel(RuleEditorPanel ruleEditorPanel) {
037: this (ruleEditorPanel, null);
038: }
039:
040: /**
041: * Instantiates a new OperationPanel, with a pre-existing OperationController as a candidate.
042: * This candidate controller will be shown as the selected element. Eventually this means
043: * that one of the existing controllers in the combo will get replaced with the candidate
044: * controller. For this, the replacement mechanism of OperationController is used.
045: *
046: *
047: * @param ruleEditorPanel the rule controller
048: * @param candidateController the candidate controller
049: * @see OperationController#canBeReplacedBy(OperationController)
050: */
051: public OperationPanel(RuleEditorPanel ruleEditorPanel,
052: OperationController candidateController) {
053: super (new SGridBagLayout());
054:
055: this .ruleEditorPanel = ruleEditorPanel;
056: componentCount = 0;
057:
058: controllerCombo = new SComboBox();
059: controllerCombo.setHorizontalAlignment(SConstants.LEFT_ALIGN);
060:
061: // Let the panel be as wide as possible
062: setPreferredSize(SDimension.FULLWIDTH);
063:
064: int initialSelectedIndex = 0;
065: int comboItemIndex = 0;
066:
067: // Get a list of Controllers (overriden by subclasses) and iterate over them...
068: for (OperationController opc : getControllers()) {
069:
070: // If we have been given an already existing Controller (in case we want
071: // to re-create the UI for an existing Rule) ...
072: if (candidateController != null) {
073: // ... we should prefer using that controller than the default one
074: // since the candidateController correctly reflects the state of the
075: // Operation that is part of the Rule we want to re-create.
076:
077: // If a match is found...
078: if (opc.canBeReplacedBy(candidateController)) {
079: // make sure we use the candidateController instead of the one in list...
080: opc = candidateController;
081: // and remember in which position it was on the list (used below)
082: initialSelectedIndex = comboItemIndex;
083: }
084: }
085:
086: // Add the Controller to the combo-box.
087: controllerCombo.addItem(opc);
088: comboItemIndex++;
089: }
090:
091: // Add the combo-box of Controllers to ourself (SPanel)
092: layoutConstraints.weightx = .3;
093: add(controllerCombo, layoutConstraints);
094:
095: // In case candidateController found a match,
096: // make the combo-box point to it
097: controllerCombo.setSelectedIndex(initialSelectedIndex);
098:
099: // IMPORTANT: we add the action-listener AFTER changing the selected of
100: // index of the combo-box. Otherwise we would automatically trigger an
101: // unwanted ActionEvent...
102: controllerCombo.addActionListener(new ActionListener() {
103: public void actionPerformed(ActionEvent e) {
104: // This will update the other components depending on the currently
105: // selected Controller.
106: updateParameters();
107: }
108: });
109:
110: // Update parameters according to the currently selected Controller.
111: updateParameters();
112: }
113:
114: /**
115: * Gets the all the OperationControllers supported by this OperationPanel in this Context.
116: *
117: * @return the OperationControllers for this panel in this context.
118: */
119: protected abstract List<OperationController> getControllers();
120:
121: /**
122: * Populates this panel with the controls provided by the selected OperationController.
123: * These controls are put right to the OperationController combo-box (first field).
124: */
125: private void populateParameters() {
126:
127: // Get currently selected Controller
128: OperationController currentController = (OperationController) controllerCombo
129: .getSelectedItem();
130:
131: List<SComponent> components = currentController.getComponents();
132:
133: layoutConstraints.weightx = .7 / components.size();
134:
135: // Ask the Controller for parameter components (used to further refine and
136: // set-up the Action/Condition it represents) and
137: // iterate over them...
138: for (SComponent comp : components) {
139: // Remember how many components we added, so that we know
140: // how many to remove, should we need to do so.
141: componentCount++;
142:
143: // Make every of them full width
144: comp.setPreferredSize(SDimension.FULLWIDTH);
145: // Add it to ourselves (SPanel)
146: add(comp, layoutConstraints);
147: }
148: }
149:
150: /**
151: * Removes the controls (that were once provided by the selected OperationController),
152: * from this panel.
153: */
154: private void removeParameters() {
155: // For every extra component we added...
156: while (componentCount > 0) {
157: // ... remove the component next to the controllerCombo
158: // (which never gets, nor should it be, deleted)
159: remove(1);
160: // Update our component count accordingly.
161: componentCount--;
162: }
163: }
164:
165: /**
166: * Update parameters, to reflect the selected OperationController.
167: */
168: public void updateParameters() {
169:
170: // Remove all parameter components...
171: removeParameters();
172:
173: // ... and re-populate them using the selected Controller.
174: populateParameters();
175: }
176:
177: /**
178: * Enables or disables this panel, effectively allowing or preventing edition.
179: *
180: * @see org.wings.SComponent#setEnabled(boolean)
181: */
182: public void setEnabled(boolean enabled) {
183: // Call superclass implementation for the SPanel, but...
184: super .setEnabled(enabled);
185:
186: // ...also invalidate all our child components so that, for
187: // example, no editing is possible.
188: for (SComponent comp : getComponents()) {
189: comp.setEnabled(enabled);
190: }
191: }
192:
193: }
|