我有JFrame
个我想要的组件
引用另一个JFrame
,我想要
通过名字得到他们而不是
为每个人做公共获取/设置方法。
是否有一种方法可以让Swing通过其名称获取组件引用,如do C#?
e.g。 form.Controls["text"]
由于
答案 0 :(得分:27)
我知道这是一个老问题,但我发现自己现在才问这个问题。我想要一种简单的方法来按名称获取组件,这样我就不必每次都要编写一些复杂的代码来访问不同的组件。例如,让JButton访问文本字段中的文本或列表中的选择。
最简单的解决方案是使所有组件变量成为类变量,以便您可以在任何地方访问它们。但是,不是每个人都想这样做,有些人(比如我自己)正在使用不会将组件生成为类变量的GUI编辑器。
我的解决方案很简单,我想,并且并没有真正违反任何编程标准,据我所知(参考fortran的内容)。它允许以简单直接的方式按名称访问组件。
创建Map类变量。你需要导入HashMap 非常少。为简单起见,我将我的命名为componentMap。
private HashMap componentMap;
正常将所有组件添加到框架中。
initialize() {
//add your components and be sure
//to name them.
...
//after adding all the components,
//call this method we're about to create.
createComponentMap();
}
在您的课程中定义以下两种方法。如果您尚未导入,则需要导入Component:
private void createComponentMap() {
componentMap = new HashMap<String,Component>();
Component[] components = yourForm.getContentPane().getComponents();
for (int i=0; i < components.length; i++) {
componentMap.put(components[i].getName(), components[i]);
}
}
public Component getComponentByName(String name) {
if (componentMap.containsKey(name)) {
return (Component) componentMap.get(name);
}
else return null;
}
现在您已经有了一个HashMap,它将您的框架/内容窗格/面板/等中的所有当前现有组件映射到它们各自的名称。
现在访问这些组件,就像调用getComponentByName(String name)一样简单。如果存在具有该名称的组件,则它将返回该组件。如果不是,则返回null。您有责任将组件转换为正确的类型。我建议使用instanceof来确定。
如果您计划在运行时的任何时候添加,删除或重命名组件,我会考虑添加根据您的更改修改HashMap的方法。
答案 1 :(得分:6)
每个Component
都可以有一个名称,可以通过getName()
和setName()
访问,但您必须编写自己的查找功能。
答案 2 :(得分:4)
getComponentByName(frame,name)
如果您正在使用NetBeans或其他IDE,默认情况下会创建私有变量(字段)来保存所有AWT / Swing组件,那么以下代码可能对您有用。使用方法如下:
// get a button (or other component) by name
JButton button = Awt1.getComponentByName(someOtherFrame, "jButton1");
// do something useful with it (like toggle it's enabled state)
button.setEnabled(!button.isEnabled());
以下是使上述成为可能的代码......
import java.awt.Component;
import java.awt.Window;
import java.lang.reflect.Field;
/**
* additional utilities for working with AWT/Swing.
* this is a single method for demo purposes.
* recommended to be combined into a single class
* module with other similar methods,
* e.g. MySwingUtilities
*
* @author http://javajon.blogspot.com/2013/07/java-awtswing-getcomponentbynamewindow.html
*/
public class Awt1 {
/**
* attempts to retrieve a component from a JFrame or JDialog using the name
* of the private variable that NetBeans (or other IDE) created to refer to
* it in code.
* @param <T> Generics allow easier casting from the calling side.
* @param window JFrame or JDialog containing component
* @param name name of the private field variable, case sensitive
* @return null if no match, otherwise a component.
*/
@SuppressWarnings("unchecked")
static public <T extends Component> T getComponentByName(Window window, String name) {
// loop through all of the class fields on that form
for (Field field : window.getClass().getDeclaredFields()) {
try {
// let us look at private fields, please
field.setAccessible(true);
// compare the variable name to the name passed in
if (name.equals(field.getName())) {
// get a potential match (assuming correct <T>ype)
final Object potentialMatch = field.get(window);
// cast and return the component
return (T) potentialMatch;
}
} catch (SecurityException | IllegalArgumentException
| IllegalAccessException ex) {
// ignore exceptions
}
}
// no match found
return null;
}
}
它使用反射来查看类字段,以查看它是否可以找到由同名变量引用的组件。
注意:上面的代码使用泛型将结果转换为您期望的任何类型,因此在某些情况下,您可能必须明确表示类型转换。例如,如果myOverloadedMethod
同时接受JButton
和JTextField
,您可能需要明确定义要调用的重载...
myOverloadedMethod((JButton) Awt1.getComponentByName(someOtherFrame, "jButton1"));
如果您不确定,可以获得Component
并使用instanceof
进行检查......
// get a component and make sure it's a JButton before using it
Component component = Awt1.getComponentByName(someOtherFrame, "jButton1");
if (component instanceof JButton) {
JButton button = (JButton) component;
// do more stuff here with button
}
希望这有帮助!
答案 3 :(得分:2)
你可以在第二个JFrame中保存对第一个JFrame的引用,然后循环遍历JFrame.getComponents(),检查每个元素的名称。
答案 4 :(得分:1)
您可以将变量声明为公共变量,然后获取所需的文本或任何操作,然后您可以在另一个框架中访问它(如果它在同一个包中),因为它是公共的。
答案 5 :(得分:1)
我需要访问位于单个JPanel
内的多个JFrame
内的元素。
@Jesse Strickland发布了一个很好的答案,但提供的代码无法访问任何嵌套元素(就像我的情况一样,在JPanel
内)。
经过额外的Google搜索后,我发现@aioobe here提供了这种递归方法。
通过组合并略微修改@Jesse Strickland和@aioobe的代码,我得到了一个可以访问所有嵌套元素的工作代码,无论它们有多深:
private void createComponentMap() {
componentMap = new HashMap<String,Component>();
List<Component> components = getAllComponents(this);
for (Component comp : components) {
componentMap.put(comp.getName(), comp);
}
}
private List<Component> getAllComponents(final Container c) {
Component[] comps = c.getComponents();
List<Component> compList = new ArrayList<Component>();
for (Component comp : comps) {
compList.add(comp);
if (comp instanceof Container)
compList.addAll(getAllComponents((Container) comp));
}
return compList;
}
public Component getComponentByName(String name) {
if (componentMap.containsKey(name)) {
return (Component) componentMap.get(name);
}
else return null;
}
代码的使用与@Jesse Strickland代码完全相同。
答案 6 :(得分:0)
如果您的组件是在同一个类中声明的,那么您只需将这些组件作为类名的属性进行访问。
public class TheDigitalClock {
private static ClockLabel timeLable = new ClockLabel("timeH");
private static ClockLabel timeLable2 = new ClockLabel("timeM");
private static ClockLabel timeLable3 = new ClockLabel("timeAP");
...
...
...
public void actionPerformed(ActionEvent e)
{
...
...
...
//set all components transparent
TheDigitalClock.timeLable.setBorder(null);
TheDigitalClock.timeLable.setOpaque(false);
TheDigitalClock.timeLable.repaint();
...
...
...
}
...
...
...
}
而且,可能能够将类组件作为类名的属性从同一名称空间中的其他类访问。我可以访问受保护的属性(类成员变量),也许您也可以访问公共组件。试试吧!
答案 7 :(得分:0)
Swing 确实提供了其他方法来实现这一点,因为这里是我在组件层次结构上下文中实现查找的版本。
/**
* Description : Find a component having the given name in container desccendants hierarchy
* Assumptions : First component with the given name is returned
* @return java.awt.Component
* @param component java.awt.Component
* @param componentName java.lang.String
*/
public static Component findComponentByName(Component component, String componentName) {
if (component == null ) {
return null;
}
if (component.getName() != null && component.getName().equalsIgnoreCase(componentName)) {
return component;
}
if ( (component instanceof Container ) ) {
Component[] children = ((Container) component).getComponents();
for ( int i=0; i<children.length; i++ ) {
Component child = children[i];
Component found = findComponentByName( child, componentName );
if (found != null ) {
return found;
}
}
}
return null;
}