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.threads.gui;
020:
021: import java.awt.BorderLayout;
022: import java.awt.Dimension;
023: import java.awt.event.ItemEvent;
024: import java.awt.event.ItemListener;
025: import java.util.Collection;
026: import java.util.Date;
027:
028: import javax.swing.BorderFactory;
029: import javax.swing.Box;
030: import javax.swing.ButtonGroup;
031: import javax.swing.JCheckBox;
032: import javax.swing.JLabel;
033: import javax.swing.JPanel;
034: import javax.swing.JPopupMenu;
035: import javax.swing.JRadioButton;
036: import javax.swing.JTextField;
037:
038: import org.apache.jmeter.control.LoopController;
039: import org.apache.jmeter.control.gui.LoopControlPanel;
040: import org.apache.jmeter.gui.AbstractJMeterGuiComponent;
041: import org.apache.jmeter.gui.action.ActionNames;
042: import org.apache.jmeter.gui.tree.JMeterTreeNode;
043: import org.apache.jmeter.gui.util.FocusRequester;
044: import org.apache.jmeter.gui.util.JDateField;
045: import org.apache.jmeter.gui.util.MenuFactory;
046: import org.apache.jmeter.gui.util.VerticalPanel;
047: import org.apache.jmeter.testelement.TestElement;
048: import org.apache.jmeter.testelement.property.BooleanProperty;
049: import org.apache.jmeter.testelement.property.LongProperty;
050: import org.apache.jmeter.testelement.property.StringProperty;
051: import org.apache.jmeter.threads.ThreadGroup;
052: import org.apache.jmeter.util.JMeterUtils;
053:
054: public class ThreadGroupGui extends AbstractJMeterGuiComponent
055: implements ItemListener {
056: private LoopControlPanel loopPanel;
057:
058: private VerticalPanel mainPanel;
059:
060: private final static String THREAD_NAME = "Thread Field";
061:
062: private final static String RAMP_NAME = "Ramp Up Field";
063:
064: private JTextField threadInput;
065:
066: private JTextField rampInput;
067:
068: private JDateField start;
069:
070: private JDateField end;
071:
072: private JCheckBox scheduler;
073:
074: private JTextField duration;
075:
076: private JTextField delay; // Relative start-up time
077:
078: // Sampler error action buttons
079: private JRadioButton continueBox;
080:
081: private JRadioButton stopThrdBox;
082:
083: private JRadioButton stopTestBox;
084:
085: public ThreadGroupGui() {
086: super ();
087: init();
088: initGui();
089: }
090:
091: public Collection getMenuCategories() {
092: return null;
093: }
094:
095: public TestElement createTestElement() {
096: ThreadGroup tg = new ThreadGroup();
097: modifyTestElement(tg);
098: return tg;
099: }
100:
101: /**
102: * Modifies a given TestElement to mirror the data in the gui components.
103: *
104: * @see org.apache.jmeter.gui.JMeterGUIComponent#modifyTestElement(TestElement)
105: */
106: public void modifyTestElement(TestElement tg) {
107: super .configureTestElement(tg);
108: if (tg instanceof ThreadGroup) {
109: ((ThreadGroup) tg)
110: .setSamplerController((LoopController) loopPanel
111: .createTestElement());
112: }
113:
114: tg.setProperty(ThreadGroup.NUM_THREADS, threadInput.getText());
115: tg.setProperty(ThreadGroup.RAMP_TIME, rampInput.getText());
116: tg.setProperty(new LongProperty(ThreadGroup.START_TIME, start
117: .getDate().getTime()));
118: tg.setProperty(new LongProperty(ThreadGroup.END_TIME, end
119: .getDate().getTime()));
120: tg.setProperty(new BooleanProperty(ThreadGroup.SCHEDULER,
121: scheduler.isSelected()));
122: tg.setProperty(new StringProperty(ThreadGroup.ON_SAMPLE_ERROR,
123: onSampleError()));
124: tg.setProperty(ThreadGroup.DURATION, duration.getText());
125: tg.setProperty(ThreadGroup.DELAY, delay.getText());
126: }
127:
128: private void setSampleErrorBoxes(ThreadGroup te) {
129: stopTestBox.setSelected(te.getOnErrorStopTest());
130: stopThrdBox.setSelected(te.getOnErrorStopThread());
131: continueBox.setSelected(!te.getOnErrorStopThread()
132: && !te.getOnErrorStopTest());
133: }
134:
135: private String onSampleError() {
136: if (stopTestBox.isSelected())
137: return ThreadGroup.ON_SAMPLE_ERROR_STOPTEST;
138: if (stopThrdBox.isSelected())
139: return ThreadGroup.ON_SAMPLE_ERROR_STOPTHREAD;
140:
141: // Defaults to continue
142: return ThreadGroup.ON_SAMPLE_ERROR_CONTINUE;
143: }
144:
145: public void configure(TestElement tg) {
146: super .configure(tg);
147: threadInput.setText(tg
148: .getPropertyAsString(ThreadGroup.NUM_THREADS));
149: rampInput
150: .setText(tg.getPropertyAsString(ThreadGroup.RAMP_TIME));
151: loopPanel.configure((TestElement) tg.getProperty(
152: ThreadGroup.MAIN_CONTROLLER).getObjectValue());
153: scheduler.setSelected(tg
154: .getPropertyAsBoolean(ThreadGroup.SCHEDULER));
155:
156: if (scheduler.isSelected()) {
157: mainPanel.setVisible(true);
158: } else {
159: mainPanel.setVisible(false);
160: }
161:
162: // Check if the property exists
163: String s = tg.getPropertyAsString(ThreadGroup.START_TIME);
164: if (s.length() == 0) {// Must be an old test plan
165: start.setDate(new Date());
166: end.setDate(new Date());
167: } else {
168: start.setDate(new Date(tg
169: .getPropertyAsLong(ThreadGroup.START_TIME)));
170: end.setDate(new Date(tg
171: .getPropertyAsLong(ThreadGroup.END_TIME)));
172: }
173: duration.setText(tg.getPropertyAsString(ThreadGroup.DURATION));
174: delay.setText(tg.getPropertyAsString(ThreadGroup.DELAY));
175:
176: setSampleErrorBoxes((ThreadGroup) tg);
177: }
178:
179: public void itemStateChanged(ItemEvent ie) {
180: if (ie.getItem().equals(scheduler)) {
181: if (scheduler.isSelected()) {
182: mainPanel.setVisible(true);
183: } else {
184: mainPanel.setVisible(false);
185: }
186: }
187: }
188:
189: public JPopupMenu createPopupMenu() {
190: JPopupMenu pop = new JPopupMenu();
191: pop.add(MenuFactory.makeMenus(new String[] {
192: MenuFactory.CONTROLLERS, MenuFactory.CONFIG_ELEMENTS,
193: MenuFactory.TIMERS, MenuFactory.PRE_PROCESSORS,
194: MenuFactory.SAMPLERS, MenuFactory.ASSERTIONS,
195: MenuFactory.POST_PROCESSORS, MenuFactory.LISTENERS, },
196: JMeterUtils.getResString("add"), // $NON-NLS-1$
197: ActionNames.ADD));
198: MenuFactory.addEditMenu(pop, true);
199: MenuFactory.addFileMenu(pop);
200: return pop;
201: }
202:
203: private JPanel createControllerPanel() {
204: loopPanel = new LoopControlPanel(false);
205: LoopController looper = (LoopController) loopPanel
206: .createTestElement();
207: looper.setLoops(1);
208: loopPanel.configure(looper);
209: return loopPanel;
210: }
211:
212: /**
213: * Create a panel containing the StartTime field and corresponding label.
214: *
215: * @return a GUI panel containing the StartTime field
216: */
217: private JPanel createStartTimePanel() {
218: JPanel panel = new JPanel(new BorderLayout(5, 0));
219: JLabel label = new JLabel(JMeterUtils.getResString("starttime")); //$NON-NLS-1$
220: panel.add(label, BorderLayout.WEST);
221: start = new JDateField();
222: panel.add(start, BorderLayout.CENTER);
223: return panel;
224: }
225:
226: /**
227: * Create a panel containing the EndTime field and corresponding label.
228: *
229: * @return a GUI panel containing the EndTime field
230: */
231: private JPanel createEndTimePanel() {
232: JPanel panel = new JPanel(new BorderLayout(5, 0));
233: JLabel label = new JLabel(JMeterUtils.getResString("endtime")); // $NON-NLS-1$
234: panel.add(label, BorderLayout.WEST);
235:
236: end = new JDateField();
237: panel.add(end, BorderLayout.CENTER);
238: return panel;
239: }
240:
241: /**
242: * Create a panel containing the Duration field and corresponding label.
243: *
244: * @return a GUI panel containing the Duration field
245: */
246: private JPanel createDurationPanel() {
247: JPanel panel = new JPanel(new BorderLayout(5, 0));
248: JLabel label = new JLabel(JMeterUtils.getResString("duration")); // $NON-NLS-1$
249: panel.add(label, BorderLayout.WEST);
250: duration = new JTextField();
251: panel.add(duration, BorderLayout.CENTER);
252: return panel;
253: }
254:
255: /**
256: * Create a panel containing the Duration field and corresponding label.
257: *
258: * @return a GUI panel containing the Duration field
259: */
260: private JPanel createDelayPanel() {
261: JPanel panel = new JPanel(new BorderLayout(5, 0));
262: JLabel label = new JLabel(JMeterUtils.getResString("delay")); // $NON-NLS-1$
263: panel.add(label, BorderLayout.WEST);
264: delay = new JTextField();
265: panel.add(delay, BorderLayout.CENTER);
266: return panel;
267: }
268:
269: public String getLabelResource() {
270: return "threadgroup"; // $NON-NLS-1$
271: }
272:
273: private JPanel createOnErrorPanel() {
274: JPanel panel = new JPanel();
275: panel.setBorder(BorderFactory.createTitledBorder(JMeterUtils
276: .getResString("sampler_on_error_action"))); // $NON-NLS-1$
277:
278: ButtonGroup group = new ButtonGroup();
279:
280: continueBox = new JRadioButton(JMeterUtils
281: .getResString("sampler_on_error_continue")); // $NON-NLS-1$
282: group.add(continueBox);
283: panel.add(continueBox);
284:
285: stopThrdBox = new JRadioButton(JMeterUtils
286: .getResString("sampler_on_error_stop_thread")); // $NON-NLS-1$
287: group.add(stopThrdBox);
288: panel.add(stopThrdBox);
289:
290: stopTestBox = new JRadioButton(JMeterUtils
291: .getResString("sampler_on_error_stop_test")); // $NON-NLS-1$
292: group.add(stopTestBox);
293: panel.add(stopTestBox);
294:
295: return panel;
296: }
297:
298: public void clearGui() {
299: super .clearGui();
300: initGui();
301: }
302:
303: // Initialise the gui field values
304: private void initGui() {
305: threadInput.setText("1"); // $NON-NLS-1$
306: rampInput.setText("1"); // $NON-NLS-1$
307: continueBox.setSelected(true);
308: loopPanel.clearGui();
309: scheduler.setSelected(false);
310: Date today = new Date();
311: end.setDate(today);
312: start.setDate(today);
313: delay.setText(""); // $NON-NLS-1$
314: duration.setText(""); // $NON-NLS-1$
315: }
316:
317: private void init() {
318: setLayout(new BorderLayout(0, 5));
319: setBorder(makeBorder());
320:
321: Box box = Box.createVerticalBox();
322: box.add(makeTitlePanel());
323: box.add(createOnErrorPanel());
324: add(box, BorderLayout.NORTH);
325:
326: // JPanel mainPanel = new JPanel(new BorderLayout());
327:
328: // THREAD PROPERTIES
329: VerticalPanel threadPropsPanel = new VerticalPanel();
330: threadPropsPanel.setBorder(BorderFactory.createTitledBorder(
331: BorderFactory.createEtchedBorder(), JMeterUtils
332: .getResString("thread_properties"))); // $NON-NLS-1$
333:
334: // NUMBER OF THREADS
335: JPanel threadPanel = new JPanel(new BorderLayout(5, 0));
336:
337: JLabel threadLabel = new JLabel(JMeterUtils
338: .getResString("number_of_threads")); // $NON-NLS-1$
339: threadPanel.add(threadLabel, BorderLayout.WEST);
340:
341: threadInput = new JTextField(5);
342: threadInput.setName(THREAD_NAME);
343: threadLabel.setLabelFor(threadInput);
344: threadPanel.add(threadInput, BorderLayout.CENTER);
345:
346: threadPropsPanel.add(threadPanel);
347: new FocusRequester(threadInput);
348:
349: // RAMP-UP
350: JPanel rampPanel = new JPanel(new BorderLayout(5, 0));
351: JLabel rampLabel = new JLabel(JMeterUtils
352: .getResString("ramp_up")); // $NON-NLS-1$
353: rampPanel.add(rampLabel, BorderLayout.WEST);
354:
355: rampInput = new JTextField(5);
356: rampInput.setName(RAMP_NAME);
357: rampLabel.setLabelFor(rampInput);
358: rampPanel.add(rampInput, BorderLayout.CENTER);
359:
360: threadPropsPanel.add(rampPanel);
361:
362: // LOOP COUNT
363: threadPropsPanel.add(createControllerPanel());
364:
365: // mainPanel.add(threadPropsPanel, BorderLayout.NORTH);
366: // add(mainPanel, BorderLayout.CENTER);
367:
368: scheduler = new JCheckBox(JMeterUtils.getResString("scheduler")); // $NON-NLS-1$
369: scheduler.addItemListener(this );
370: threadPropsPanel.add(scheduler);
371: mainPanel = new VerticalPanel();
372: mainPanel.setBorder(BorderFactory.createTitledBorder(
373: BorderFactory.createEtchedBorder(), JMeterUtils
374: .getResString("scheduler_configuration"))); // $NON-NLS-1$
375: mainPanel.add(createStartTimePanel());
376: mainPanel.add(createEndTimePanel());
377: mainPanel.add(createDurationPanel());
378: mainPanel.add(createDelayPanel());
379: mainPanel.setVisible(false);
380: VerticalPanel intgrationPanel = new VerticalPanel();
381: intgrationPanel.add(threadPropsPanel);
382: intgrationPanel.add(mainPanel);
383: add(intgrationPanel, BorderLayout.CENTER);
384: }
385:
386: public void setNode(JMeterTreeNode node) {
387: getNamePanel().setNode(node);
388: }
389:
390: public Dimension getPreferredSize() {
391: return getMinimumSize();
392: }
393: }
|