/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.jmeter.threads.gui;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Collection;
import java.util.Date;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import org.apache.jmeter.control.LoopController;
import org.apache.jmeter.control.gui.LoopControlPanel;
import org.apache.jmeter.gui.AbstractJMeterGuiComponent;
import org.apache.jmeter.gui.action.ActionNames;
import org.apache.jmeter.gui.tree.JMeterTreeNode;
import org.apache.jmeter.gui.util.FocusRequester;
import org.apache.jmeter.gui.util.JDateField;
import org.apache.jmeter.gui.util.MenuFactory;
import org.apache.jmeter.gui.util.VerticalPanel;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.testelement.property.BooleanProperty;
import org.apache.jmeter.testelement.property.LongProperty;
import org.apache.jmeter.testelement.property.StringProperty;
import org.apache.jmeter.threads.ThreadGroup;
import org.apache.jmeter.util.JMeterUtils;
public class ThreadGroupGui extends AbstractJMeterGuiComponent implements ItemListener {
private LoopControlPanel loopPanel;
private VerticalPanel mainPanel;
private final static String THREAD_NAME = "Thread Field";
private final static String RAMP_NAME = "Ramp Up Field";
private JTextField threadInput;
private JTextField rampInput;
private JDateField start;
private JDateField end;
private JCheckBox scheduler;
private JTextField duration;
private JTextField delay; // Relative start-up time
// Sampler error action buttons
private JRadioButton continueBox;
private JRadioButton stopThrdBox;
private JRadioButton stopTestBox;
public ThreadGroupGui() {
super();
init();
initGui();
}
public Collection getMenuCategories() {
return null;
}
public TestElement createTestElement() {
ThreadGroup tg = new ThreadGroup();
modifyTestElement(tg);
return tg;
}
/**
* Modifies a given TestElement to mirror the data in the gui components.
*
* @see org.apache.jmeter.gui.JMeterGUIComponent#modifyTestElement(TestElement)
*/
public void modifyTestElement(TestElement tg) {
super.configureTestElement(tg);
if (tg instanceof ThreadGroup) {
((ThreadGroup) tg).setSamplerController((LoopController) loopPanel.createTestElement());
}
tg.setProperty(ThreadGroup.NUM_THREADS, threadInput.getText());
tg.setProperty(ThreadGroup.RAMP_TIME, rampInput.getText());
tg.setProperty(new LongProperty(ThreadGroup.START_TIME, start.getDate().getTime()));
tg.setProperty(new LongProperty(ThreadGroup.END_TIME, end.getDate().getTime()));
tg.setProperty(new BooleanProperty(ThreadGroup.SCHEDULER, scheduler.isSelected()));
tg.setProperty(new StringProperty(ThreadGroup.ON_SAMPLE_ERROR, onSampleError()));
tg.setProperty(ThreadGroup.DURATION, duration.getText());
tg.setProperty(ThreadGroup.DELAY, delay.getText());
}
private void setSampleErrorBoxes(ThreadGroup te) {
stopTestBox.setSelected(te.getOnErrorStopTest());
stopThrdBox.setSelected(te.getOnErrorStopThread());
continueBox.setSelected(!te.getOnErrorStopThread() && !te.getOnErrorStopTest());
}
private String onSampleError() {
if (stopTestBox.isSelected()) {
return ThreadGroup.ON_SAMPLE_ERROR_STOPTEST;
}
if (stopThrdBox.isSelected()) {
return ThreadGroup.ON_SAMPLE_ERROR_STOPTHREAD;
}
// Defaults to continue
return ThreadGroup.ON_SAMPLE_ERROR_CONTINUE;
}
public void configure(TestElement tg) {
super.configure(tg);
threadInput.setText(tg.getPropertyAsString(ThreadGroup.NUM_THREADS));
rampInput.setText(tg.getPropertyAsString(ThreadGroup.RAMP_TIME));
loopPanel.configure((TestElement) tg.getProperty(ThreadGroup.MAIN_CONTROLLER).getObjectValue());
scheduler.setSelected(tg.getPropertyAsBoolean(ThreadGroup.SCHEDULER));
if (scheduler.isSelected()) {
mainPanel.setVisible(true);
} else {
mainPanel.setVisible(false);
}
// Check if the property exists
String s = tg.getPropertyAsString(ThreadGroup.START_TIME);
if (s.length() == 0) {// Must be an old test plan
start.setDate(new Date());
end.setDate(new Date());
} else {
start.setDate(new Date(tg.getPropertyAsLong(ThreadGroup.START_TIME)));
end.setDate(new Date(tg.getPropertyAsLong(ThreadGroup.END_TIME)));
}
duration.setText(tg.getPropertyAsString(ThreadGroup.DURATION));
delay.setText(tg.getPropertyAsString(ThreadGroup.DELAY));
setSampleErrorBoxes((ThreadGroup) tg);
}
public void itemStateChanged(ItemEvent ie) {
if (ie.getItem().equals(scheduler)) {
if (scheduler.isSelected()) {
mainPanel.setVisible(true);
} else {
mainPanel.setVisible(false);
}
}
}
public JPopupMenu createPopupMenu() {
JPopupMenu pop = new JPopupMenu();
pop.add(MenuFactory.makeMenus(new String[] {
MenuFactory.CONTROLLERS,
MenuFactory.CONFIG_ELEMENTS,
MenuFactory.TIMERS,
MenuFactory.PRE_PROCESSORS,
MenuFactory.SAMPLERS,
MenuFactory.ASSERTIONS,
MenuFactory.POST_PROCESSORS,
MenuFactory.LISTENERS,
},
JMeterUtils.getResString("add"), // $NON-NLS-1$
ActionNames.ADD));
MenuFactory.addEditMenu(pop, true);
MenuFactory.addFileMenu(pop);
return pop;
}
private JPanel createControllerPanel() {
loopPanel = new LoopControlPanel(false);
LoopController looper = (LoopController) loopPanel.createTestElement();
looper.setLoops(1);
loopPanel.configure(looper);
return loopPanel;
}
/**
* Create a panel containing the StartTime field and corresponding label.
*
* @return a GUI panel containing the StartTime field
*/
private JPanel createStartTimePanel() {
JPanel panel = new JPanel(new BorderLayout(5, 0));
JLabel label = new JLabel(JMeterUtils.getResString("starttime")); //$NON-NLS-1$
panel.add(label, BorderLayout.WEST);
start = new JDateField();
panel.add(start, BorderLayout.CENTER);
return panel;
}
/**
* Create a panel containing the EndTime field and corresponding label.
*
* @return a GUI panel containing the EndTime field
*/
private JPanel createEndTimePanel() {
JPanel panel = new JPanel(new BorderLayout(5, 0));
JLabel label = new JLabel(JMeterUtils.getResString("endtime")); // $NON-NLS-1$
panel.add(label, BorderLayout.WEST);
end = new JDateField();
panel.add(end, BorderLayout.CENTER);
return panel;
}
/**
* Create a panel containing the Duration field and corresponding label.
*
* @return a GUI panel containing the Duration field
*/
private JPanel createDurationPanel() {
JPanel panel = new JPanel(new BorderLayout(5, 0));
JLabel label = new JLabel(JMeterUtils.getResString("duration")); // $NON-NLS-1$
panel.add(label, BorderLayout.WEST);
duration = new JTextField();
panel.add(duration, BorderLayout.CENTER);
return panel;
}
/**
* Create a panel containing the Duration field and corresponding label.
*
* @return a GUI panel containing the Duration field
*/
private JPanel createDelayPanel() {
JPanel panel = new JPanel(new BorderLayout(5, 0));
JLabel label = new JLabel(JMeterUtils.getResString("delay")); // $NON-NLS-1$
panel.add(label, BorderLayout.WEST);
delay = new JTextField();
panel.add(delay, BorderLayout.CENTER);
return panel;
}
public String getLabelResource() {
return "threadgroup"; // $NON-NLS-1$
}
private JPanel createOnErrorPanel() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder(JMeterUtils.getResString("sampler_on_error_action"))); // $NON-NLS-1$
ButtonGroup group = new ButtonGroup();
continueBox = new JRadioButton(JMeterUtils.getResString("sampler_on_error_continue")); // $NON-NLS-1$
group.add(continueBox);
panel.add(continueBox);
stopThrdBox = new JRadioButton(JMeterUtils.getResString("sampler_on_error_stop_thread")); // $NON-NLS-1$
group.add(stopThrdBox);
panel.add(stopThrdBox);
stopTestBox = new JRadioButton(JMeterUtils.getResString("sampler_on_error_stop_test")); // $NON-NLS-1$
group.add(stopTestBox);
panel.add(stopTestBox);
return panel;
}
public void clearGui(){
super.clearGui();
initGui();
}
// Initialise the gui field values
private void initGui(){
threadInput.setText("1"); // $NON-NLS-1$
rampInput.setText("1"); // $NON-NLS-1$
continueBox.setSelected(true);
loopPanel.clearGui();
scheduler.setSelected(false);
Date today = new Date();
end.setDate(today);
start.setDate(today);
delay.setText(""); // $NON-NLS-1$
duration.setText(""); // $NON-NLS-1$
}
private void init() {
setLayout(new BorderLayout(0, 5));
setBorder(makeBorder());
Box box = Box.createVerticalBox();
box.add(makeTitlePanel());
box.add(createOnErrorPanel());
add(box, BorderLayout.NORTH);
// JPanel mainPanel = new JPanel(new BorderLayout());
// THREAD PROPERTIES
VerticalPanel threadPropsPanel = new VerticalPanel();
threadPropsPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
JMeterUtils.getResString("thread_properties"))); // $NON-NLS-1$
// NUMBER OF THREADS
JPanel threadPanel = new JPanel(new BorderLayout(5, 0));
JLabel threadLabel = new JLabel(JMeterUtils.getResString("number_of_threads")); // $NON-NLS-1$
threadPanel.add(threadLabel, BorderLayout.WEST);
threadInput = new JTextField(5);
threadInput.setName(THREAD_NAME);
threadLabel.setLabelFor(threadInput);
threadPanel.add(threadInput, BorderLayout.CENTER);
threadPropsPanel.add(threadPanel);
new FocusRequester(threadInput);
// RAMP-UP
JPanel rampPanel = new JPanel(new BorderLayout(5, 0));
JLabel rampLabel = new JLabel(JMeterUtils.getResString("ramp_up")); // $NON-NLS-1$
rampPanel.add(rampLabel, BorderLayout.WEST);
rampInput = new JTextField(5);
rampInput.setName(RAMP_NAME);
rampLabel.setLabelFor(rampInput);
rampPanel.add(rampInput, BorderLayout.CENTER);
threadPropsPanel.add(rampPanel);
// LOOP COUNT
threadPropsPanel.add(createControllerPanel());
// mainPanel.add(threadPropsPanel, BorderLayout.NORTH);
// add(mainPanel, BorderLayout.CENTER);
scheduler = new JCheckBox(JMeterUtils.getResString("scheduler")); // $NON-NLS-1$
scheduler.addItemListener(this);
threadPropsPanel.add(scheduler);
mainPanel = new VerticalPanel();
mainPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
JMeterUtils.getResString("scheduler_configuration"))); // $NON-NLS-1$
mainPanel.add(createStartTimePanel());
mainPanel.add(createEndTimePanel());
mainPanel.add(createDurationPanel());
mainPanel.add(createDelayPanel());
mainPanel.setVisible(false);
VerticalPanel intgrationPanel = new VerticalPanel();
intgrationPanel.add(threadPropsPanel);
intgrationPanel.add(mainPanel);
add(intgrationPanel, BorderLayout.CENTER);
}
public void setNode(JMeterTreeNode node) {
getNamePanel().setNode(node);
}
public Dimension getPreferredSize() {
return getMinimumSize();
}
}