📄 guipackage.java
字号:
/*
* 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.gui;
import java.awt.Component;
import java.awt.event.MouseEvent;
import java.beans.Introspector;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import org.apache.jmeter.engine.util.ValueReplacer;
import org.apache.jmeter.exceptions.IllegalUserActionException;
import org.apache.jmeter.gui.tree.JMeterTreeListener;
import org.apache.jmeter.gui.tree.JMeterTreeModel;
import org.apache.jmeter.gui.tree.JMeterTreeNode;
import org.apache.jmeter.services.FileServer;
import org.apache.jmeter.testbeans.TestBean;
import org.apache.jmeter.testbeans.gui.TestBeanGUI;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.testelement.TestPlan;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jmeter.util.LocaleChangeEvent;
import org.apache.jmeter.util.LocaleChangeListener;
import org.apache.jorphan.collections.HashTree;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;
/**
* GuiPackage is a static class that provides convenient access to information
* about the current state of JMeter's GUI. Any GUI class can grab a handle to
* GuiPackage by calling the static method {@link #getInstance()} and then use
* it to query the GUI about it's state. When actions, for instance, need to
* affect the GUI, they typically use GuiPackage to get access to different
* parts of the GUI.
*
*/
public final class GuiPackage implements LocaleChangeListener {
/** Logging. */
private static final Logger log = LoggingManager.getLoggerForClass();
/** Singleton instance. */
private static GuiPackage guiPack;
/**
* Flag indicating whether or not parts of the tree have changed since they
* were last saved.
*/
private boolean dirty = false;
/**
* Map from TestElement to JMeterGUIComponent, mapping the nodes in the tree
* to their corresponding GUI components.
*/
private Map nodesToGui = new HashMap();
/**
* Map from Class to JMeterGUIComponent, mapping the Class of a GUI
* component to an instance of that component.
*/
private Map guis = new HashMap();
/**
* Map from Class to TestBeanGUI, mapping the Class of a TestBean to an
* instance of TestBeanGUI to be used to edit such components.
*/
private Map testBeanGUIs = new HashMap();
/** The currently selected node in the tree. */
private JMeterTreeNode currentNode = null;
private boolean currentNodeUpdated = false;
/** The model for JMeter's test tree. */
private JMeterTreeModel treeModel;
/** The listener for JMeter's test tree. */
private JMeterTreeListener treeListener;
/** The main JMeter frame. */
private MainFrame mainFrame;
/**
* Private constructor to permit instantiation only from within this class.
* Use {@link #getInstance()} to retrieve a singleton instance.
*/
private GuiPackage() {
JMeterUtils.addLocaleChangeListener(this);
}
/**
* Retrieve the singleton GuiPackage instance.
*
* @return the GuiPackage instance
*/
public static GuiPackage getInstance() {
return guiPack;
}
/**
* When GuiPackage is requested for the first time, it should be given
* handles to JMeter's Tree Listener and TreeModel.
*
* @param listener
* the TreeListener for JMeter's test tree
* @param treeModel
* the model for JMeter's test tree
*
* @return GuiPackage
*/
public static GuiPackage getInstance(JMeterTreeListener listener, JMeterTreeModel treeModel) {
if (guiPack == null) {
guiPack = new GuiPackage();
guiPack.setTreeListener(listener);
guiPack.setTreeModel(treeModel);
}
return guiPack;
}
/**
* Get a JMeterGUIComponent for the specified test element. If the GUI has
* already been created, that instance will be returned. Otherwise, if a GUI
* component of the same type has been created, and the component is not
* marked as an {@link UnsharedComponent}, that shared component will be
* returned. Otherwise, a new instance of the component will be created. The
* TestElement's GUI_CLASS property will be used to determine the
* appropriate type of GUI component to use.
*
* @param node
* the test element which this GUI is being created for
*
* @return the GUI component corresponding to the specified test element
*/
public JMeterGUIComponent getGui(TestElement node) {
String testClassName = node.getPropertyAsString(TestElement.TEST_CLASS);
String guiClassName = node.getPropertyAsString(TestElement.GUI_CLASS);
try {
Class testClass;
if (testClassName.equals("")) { // $NON-NLS-1$
testClass = node.getClass();
} else {
testClass = Class.forName(testClassName);
}
Class guiClass = null;
if (!guiClassName.equals("")) { // $NON-NLS-1$
guiClass = Class.forName(guiClassName);
}
return getGui(node, guiClass, testClass);
} catch (ClassNotFoundException e) {
log.error("Could not get GUI for " + node, e);
return null;
}
}
/**
* Get a JMeterGUIComponent for the specified test element. If the GUI has
* already been created, that instance will be returned. Otherwise, if a GUI
* component of the same type has been created, and the component is not
* marked as an {@link UnsharedComponent}, that shared component will be
* returned. Otherwise, a new instance of the component will be created.
*
* @param node
* the test element which this GUI is being created for
* @param guiClass
* the fully qualifed class name of the GUI component which will
* be created if it doesn't already exist
* @param testClass
* the fully qualifed class name of the test elements which have
* to be edited by the returned GUI component
*
* @return the GUI component corresponding to the specified test element
*/
public JMeterGUIComponent getGui(TestElement node, Class guiClass, Class testClass) {
try {
JMeterGUIComponent comp = (JMeterGUIComponent) nodesToGui.get(node);
if (comp == null) {
comp = getGuiFromCache(guiClass, testClass);
nodesToGui.put(node, comp);
}
log.debug("Gui retrieved = " + comp);
return comp;
} catch (Exception e) {
log.error("Problem retrieving gui", e);
return null;
}
}
/**
* Remove a test element from the tree. This removes the reference to any
* associated GUI component.
*
* @param node
* the test element being removed
*/
public void removeNode(TestElement node) {
nodesToGui.remove(node);
}
/**
* Convenience method for grabbing the gui for the current node.
*
* @return the GUI component associated with the currently selected node
*/
public JMeterGUIComponent getCurrentGui() {
try {
updateCurrentNode();
TestElement curNode = treeListener.getCurrentNode().getTestElement();
JMeterGUIComponent comp = getGui(curNode);
comp.clearGui();
log.debug("Updating gui to new node");
comp.configure(curNode);
currentNodeUpdated = false;
return comp;
} catch (Exception e) {
log.error("Problem retrieving gui", e);
return null;
}
}
/**
* Find the JMeterTreeNode for a certain TestElement object.
*
* @param userObject
* the test element to search for
* @return the tree node associated with the test element
*/
public JMeterTreeNode getNodeOf(TestElement userObject) {
return treeModel.getNodeOf(userObject);
}
/**
* Create a TestElement corresponding to the specified GUI class.
*
* @param guiClass
* the fully qualified class name of the GUI component or a
* TestBean class for TestBeanGUIs.
* @param testClass
* the fully qualified class name of the test elements edited by
* this GUI component.
* @return the test element corresponding to the specified GUI class.
*/
public TestElement createTestElement(Class guiClass, Class testClass) {
try {
JMeterGUIComponent comp = getGuiFromCache(guiClass, testClass);
comp.clearGui();
TestElement node = comp.createTestElement();
nodesToGui.put(node, comp);
return node;
} catch (Exception e) {
log.error("Problem retrieving gui", e);
return null;
}
}
/**
* Create a TestElement for a GUI or TestBean class.
* <p>
* This is a utility method to help actions do with one single String
* parameter.
*
* @param objClass
* the fully qualified class name of the GUI component or of the
* TestBean subclass for which a TestBeanGUI is wanted.
* @return the test element corresponding to the specified GUI class.
*/
public TestElement createTestElement(String objClass) {
JMeterGUIComponent comp;
Class c;
try {
c = Class.forName(objClass);
if (TestBean.class.isAssignableFrom(c)) {
comp = getGuiFromCache(TestBeanGUI.class, c);
} else {
comp = getGuiFromCache(c, null);
}
comp.clearGui();
TestElement node = comp.createTestElement();
nodesToGui.put(node, comp);
return node;
} catch (NoClassDefFoundError e) {
log.error("Problem retrieving gui for " + objClass, e);
String msg="Cannot find class: "+e.getMessage();
JOptionPane.showMessageDialog(null,
msg,
"Missing jar? See log file." ,
JOptionPane.ERROR_MESSAGE);
throw new RuntimeException(e.toString()); // Probably a missing
// jar
} catch (ClassNotFoundException e) {
log.error("Problem retrieving gui for " + objClass, e);
throw new RuntimeException(e.toString()); // Programming error:
// bail out.
} catch (InstantiationException e) {
log.error("Problem retrieving gui for " + objClass, e);
throw new RuntimeException(e.toString()); // Programming error:
// bail out.
} catch (IllegalAccessException e) {
log.error("Problem retrieving gui for " + objClass, e);
throw new RuntimeException(e.toString()); // Programming error:
// bail out.
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -