001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.jmeter.control.gui;
020:
021: import java.awt.BorderLayout;
022: import java.awt.event.ActionEvent;
023: import java.awt.event.ActionListener;
024:
025: import javax.swing.Box;
026: import javax.swing.JCheckBox;
027: import javax.swing.JLabel;
028: import javax.swing.JPanel;
029: import javax.swing.JTextField;
030:
031: import org.apache.jmeter.control.LoopController;
032: import org.apache.jmeter.gui.util.FocusRequester;
033: import org.apache.jmeter.testelement.TestElement;
034: import org.apache.jmeter.util.JMeterUtils;
035:
036: /**
037: * The user interface for a controller which specifies that its subcomponents
038: * should be executed some number of times in a loop. This component can be used
039: * standalone or embedded into some other component.
040: *
041: */
042:
043: public class LoopControlPanel extends AbstractControllerGui implements
044: ActionListener {
045: /**
046: * A checkbox allowing the user to specify whether or not the controller
047: * should loop forever.
048: */
049: private JCheckBox infinite;
050:
051: /**
052: * A field allowing the user to specify the number of times the controller
053: * should loop.
054: */
055: private JTextField loops;
056:
057: /**
058: * Boolean indicating whether or not this component should display its name.
059: * If true, this is a standalone component. If false, this component is
060: * intended to be used as a subpanel for another component.
061: */
062: private boolean displayName = true;
063:
064: /** The name of the infinite checkbox component. */
065: private static final String INFINITE = "Infinite Field"; // $NON-NLS-1$
066:
067: /** The name of the loops field component. */
068: private static final String LOOPS = "Loops Field"; // $NON-NLS-1$
069:
070: /**
071: * Create a new LoopControlPanel as a standalone component.
072: */
073: public LoopControlPanel() {
074: this (true);
075: }
076:
077: /**
078: * Create a new LoopControlPanel as either a standalone or an embedded
079: * component.
080: *
081: * @param displayName
082: * indicates whether or not this component should display its
083: * name. If true, this is a standalone component. If false, this
084: * component is intended to be used as a subpanel for another
085: * component.
086: */
087: public LoopControlPanel(boolean displayName) {
088: this .displayName = displayName;
089: init();
090: setState(1);
091: }
092:
093: /**
094: * A newly created component can be initialized with the contents of a Test
095: * Element object by calling this method. The component is responsible for
096: * querying the Test Element object for the relevant information to display
097: * in its GUI.
098: *
099: * @param element
100: * the TestElement to configure
101: */
102: public void configure(TestElement element) {
103: super .configure(element);
104: if (element instanceof LoopController) {
105: setState(((LoopController) element).getLoopString());
106: } else {
107: setState(1);
108: }
109: }
110:
111: /* Implements JMeterGUIComponent.createTestElement() */
112: public TestElement createTestElement() {
113: LoopController lc = new LoopController();
114: modifyTestElement(lc);
115: return lc;
116: }
117:
118: /* Implements JMeterGUIComponent.modifyTestElement(TestElement) */
119: public void modifyTestElement(TestElement lc) {
120: configureTestElement(lc);
121: if (lc instanceof LoopController) {
122: if (loops.getText().length() > 0) {
123: ((LoopController) lc).setLoops(loops.getText());
124: } else {
125: ((LoopController) lc).setLoops(-1);
126: }
127: }
128: }
129:
130: /**
131: * Implements JMeterGUIComponent.clearGui
132: */
133: public void clearGui() {
134: super .clearGui();
135:
136: loops.setText("1"); // $NON-NLS-1$
137: infinite.setSelected(false);
138: }
139:
140: /**
141: * Invoked when an action occurs. This implementation assumes that the
142: * target component is the infinite loops checkbox.
143: *
144: * @param event
145: * the event that has occurred
146: */
147: public void actionPerformed(ActionEvent event) {
148: if (infinite.isSelected()) {
149: loops.setText(""); // $NON-NLS-1$
150: loops.setEnabled(false);
151: } else {
152: loops.setEnabled(true);
153: new FocusRequester(loops);
154: }
155: }
156:
157: public String getLabelResource() {
158: return "loop_controller_title"; // $NON-NLS-1$
159: }
160:
161: /**
162: * Initialize the GUI components and layout for this component.
163: */
164: private void init() {
165: // The Loop Controller panel can be displayed standalone or inside
166: // another panel. For standalone, we want to display the TITLE, NAME,
167: // etc. (everything). However, if we want to display it within another
168: // panel, we just display the Loop Count fields (not the TITLE and
169: // NAME).
170:
171: // Standalone
172: if (displayName) {
173: setLayout(new BorderLayout(0, 5));
174: setBorder(makeBorder());
175: add(makeTitlePanel(), BorderLayout.NORTH);
176:
177: JPanel mainPanel = new JPanel(new BorderLayout());
178: mainPanel.add(createLoopCountPanel(), BorderLayout.NORTH);
179: add(mainPanel, BorderLayout.CENTER);
180: } else {
181: // Embedded
182: setLayout(new BorderLayout());
183: add(createLoopCountPanel(), BorderLayout.NORTH);
184: }
185: }
186:
187: /**
188: * Create a GUI panel containing the components related to the number of
189: * loops which should be executed.
190: *
191: * @return a GUI panel containing the loop count components
192: */
193: private JPanel createLoopCountPanel() {
194: JPanel loopPanel = new JPanel(new BorderLayout(5, 0));
195:
196: // LOOP LABEL
197: JLabel loopsLabel = new JLabel(JMeterUtils
198: .getResString("iterator_num")); // $NON-NLS-1$
199: loopPanel.add(loopsLabel, BorderLayout.WEST);
200:
201: JPanel loopSubPanel = new JPanel(new BorderLayout(5, 0));
202:
203: // TEXT FIELD
204: loops = new JTextField("1", 5); // $NON-NLS-1$
205: loops.setName(LOOPS);
206: loopsLabel.setLabelFor(loops);
207: loopSubPanel.add(loops, BorderLayout.CENTER);
208:
209: // FOREVER CHECKBOX
210: infinite = new JCheckBox(JMeterUtils.getResString("infinite")); // $NON-NLS-1$
211: infinite.setActionCommand(INFINITE);
212: infinite.addActionListener(this );
213: loopSubPanel.add(infinite, BorderLayout.WEST);
214:
215: loopPanel.add(loopSubPanel, BorderLayout.CENTER);
216:
217: loopPanel.add(Box.createHorizontalStrut(loopsLabel
218: .getPreferredSize().width
219: + loops.getPreferredSize().width
220: + infinite.getPreferredSize().width),
221: BorderLayout.NORTH);
222:
223: return loopPanel;
224: }
225:
226: /**
227: * Set the number of loops which should be reflected in the GUI. The
228: * loopCount parameter should contain the String representation of an
229: * integer. This integer will be treated as the number of loops. If this
230: * integer is less than 0, the number of loops will be assumed to be
231: * infinity.
232: *
233: * @param loopCount
234: * the String representation of the number of loops
235: */
236: private void setState(String loopCount) {
237: if (loopCount.startsWith("-")) { // $NON-NLS-1$
238: setState(-1);
239: } else {
240: loops.setText(loopCount);
241: infinite.setSelected(false);
242: loops.setEnabled(true);
243: }
244: }
245:
246: /**
247: * Set the number of loops which should be reflected in the GUI. If the
248: * loopCount is less than 0, the number of loops will be assumed to be
249: * infinity.
250: *
251: * @param loopCount
252: * the number of loops
253: */
254: private void setState(int loopCount) {
255: if (loopCount <= -1) {
256: infinite.setSelected(true);
257: loops.setEnabled(false);
258: loops.setText(""); // $NON-NLS-1$
259: } else {
260: infinite.setSelected(false);
261: loops.setEnabled(true);
262: loops.setText(Integer.toString(loopCount));
263: }
264: }
265: }
|