按名称获取Swing组件

xde*_*000 14 java swing jframe

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

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

例如 form.Controls["text"]

谢谢

小智 27

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

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

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

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

    private HashMap componentMap;
    
    Run Code Online (Sandbox Code Playgroud)
  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();
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在您的类中定义以下两个方法.如果您还没有导入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;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 现在您已经有了一个HashMap,它将您的框架/内容窗格/面板/等中的所有当前现有组件映射到它们各自的名称.

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

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


tra*_*god 6

每个都Component可以有一个名称,通过getName()和访问setName(),但你必须编写自己的查找功能.


Jon*_*han 6

getComponentByName(框架,名称)

如果您使用 NetBeans 或其他默认情况下创建私有变量(字段)来保存所有 AWT/Swing 组件的 IDE,那么以下代码可能适合您。使用方法如下:

// 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());
Run Code Online (Sandbox Code Playgroud)

这是使上述成为可能的代码......

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 &lt;T&gt;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;
    }

}
Run Code Online (Sandbox Code Playgroud)

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

注意:上面的代码使用泛型将结果转换为您期望的任何类型,因此在某些情况下您可能必须明确类型转换。例如,如果同时myOverloadedMethod接受JButtonand JTextField,您可能需要明确定义您希望调用的重载...

myOverloadedMethod((JButton) Awt1.getComponentByName(someOtherFrame, "jButton1"));
Run Code Online (Sandbox Code Playgroud)

如果你不确定,你可以得到一个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
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!