按名称获取Swing组件

我在JFrame有一些组件,我想引用另一个JFrame ,我希望通过名称获取它们,而不是为每个组件执行公共get / set方法。

是否有一种方法可以让Swing通过其名称获得组件引用,例如do c#?

例如form.Controls["text"]

谢谢

我知道这是一个古老的问题,但我发现自己现在才问这个问题。 我想要一种简单的方法来按名称获取组件,这样我就不必每次都能编写一些复杂的代码来访问不同的组件。 例如,让JButton访问文本字段中的文本或List中的选择。

最简单的解决方案是使所有组件变量成为类变量,以便您可以在任何地方访问它们。 然而,不是每个人都想这样做,有些人(比如我自己)正在使用不会将组件生成为类变量的GUI编辑器。

我的解决方案很简单,我想,并且并没有真正违反任何编程标准,据我所知(参考fortran的内容)。 它允许以简单直接的方式按名称访问组件。

  1. 创建一个Map类变量。 您至少需要导入HashMap。 为简单起见,我将我的命名为componentMap。

     private HashMap componentMap; 
  2. 正常地将所有组件添加到框架中。

     initialize() { //add your components and be sure //to name them. ... //after adding all the components, //call this method we're about to create. createComponentMap(); } 
  3. 在您的类中定义以下两个方法。 如果您还没有导入Component,则需要导入:

     private void createComponentMap() { componentMap = new HashMap(); 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; } 
  4. 现在您已经有了一个HashMap,它将您的框架/内容窗格/面板/等中的所有当前现有组件映射到它们各自的名称。

  5. 现在访问这些组件,就像调用getComponentByName(String name)一样简单。 如果存在具有该名称的组件,则它将返回该组件。 如果不是,则返回null。 您有责任将组件转换为正确的类型。 我建议使用instanceof来确定。

如果您计划在运行时的任何时候添加,删除或重命名组件,我会考虑添加根据您的更改修改HashMap的方法。

每个Component都有一个名称,可以通过getName()setName() ,但是你必须编写自己的查找函数。

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, * eg 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  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 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; } } 

它使用reflection来查看类字段,以查看它是否可以找到由同名变量引用的组件。

注意:上面的代码使用generics将结果转换为您期望的任何类型,因此在某些情况下,您可能必须明确表示类型转换。 例如,如果myOverloadedMethod接受JButtonJTextField ,则可能需要显式定义要调用的重载…

 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 } 

希望这可以帮助!

你可以在第二个JFrame中保存对第一个JFrame的引用,然后循环遍历JFrame.getComponents(),检查每个元素的名称。

您可以将变量声明为公共变量,然后获取所需的文本或任何操作,然后您可以在另一个框架中访问它(如果它在同一个包中),因为它是公共的。

我需要访问几个JFrame几个JPanel内的元素。

@Jesse Strickland发布了一个很好的答案,但提供的代码无法访问任何嵌套元素(就像在我的情况下,在JPanel )。

在额外的谷歌搜索后,我发现@aioobe 在这里提供了这种递归方法。

通过组合并稍微修改@Jesse Strickland和@aioobe的代码,我得到了一个可以访问所有嵌套元素的工作代码,无论它们有多深:

 private void createComponentMap() { componentMap = new HashMap(); List components = getAllComponents(this); for (Component comp : components) { componentMap.put(comp.getName(), comp); } } private List getAllComponents(final Container c) { Component[] comps = c.getComponents(); List compList = new ArrayList(); 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代码完全相同。

如果您的组件是在您操作它们的同一个类中声明的,那么您只需将这些组件作为类名的属性进行访问。

 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(); ... ... ... } ... ... ... } 

并且,您可以从同一名称空间中的其他类访问类组件作为类名的属性。 我可以访问受保护的属性(类成员变量),也许您也可以访问公共组件。 尝试一下!