按名称获取Swing组件。

[英]Get a Swing component by name


I have in a JFrame some components that I want to refer into another JFrame and I want to get them by name and not do public get/set methods for each.

我在一个JFrame中有一些组件,我想引用另一个JFrame,我想让它们按名字命名,而不是为每一个都做公共的get/set方法。

Is there a way from Swing to get a component reference by its name like do c#?

是否有一种方法可以从Swing获取组件引用,比如c#?

e.g. form.Controls["text"]

例如form.Controls(“文本”)

Thanks

谢谢

7 个解决方案

#1


27  

I know this is an old question, but I found myself asking it just now. I wanted an easy way to get components by name so I didn't have to write some convoluted code each time to access different components. For example, having a JButton access the text in a text field or a selection in a List.

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

The easiest solution is to make all of the component variables be class variables so that you can access them anywhere. However, not everyone wants to do that, and some (like myself) are using GUI Editors that don't generate the components as class variables.

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

My solution is simple, I'd like to think, and doesn't really violate any programming standards, as far as I know (referencing what fortran was getting at). It allows for an easy and straightforward way to access components by name.

我的解决方案很简单,我很愿意思考,而且也没有违反任何编程标准,据我所知(引用了fortran所得到的东西)。它允许通过名称访问组件的简单而直接的方法。

  1. Create a Map class variable. You'll need to import HashMap at the very least. I named mine componentMap for simplicity.

    创建一个Map类变量。您至少需要导入HashMap。为了简单起见,我命名了我的组件图。

    private HashMap componentMap;
    
  2. Add all of your components to the frame as normal.

    将所有组件添加到框架中。

    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. Define the following two methods in your class. You'll need to import Component if you haven't already:

    在类中定义以下两种方法。如果还没有导入组件,则需要导入:

    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;
    }
    
  4. Now you've got a HashMap that maps all the currently existing components in your frame/content pane/panel/etc to their respective names.

    现在,您已经得到了一个HashMap,它将框架/内容窗格/面板/等所有当前存在的组件映射到它们各自的名称。

  5. To now access these components, it is as simple as a call to getComponentByName(String name). If a component with that name exists, it will return that component. If not, it returns null. It is your responsibility to cast the component to the proper type. I suggest using instanceof to be sure.

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

If you plan on adding, removing, or renaming components at any point during runtime, I would consider adding methods that modify the HashMap according to your changes.

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

#2


6  

Each Component can have a name, accessed via getName() and setName(), but you'll have to write your own lookup function.

每个组件都可以有一个名称,通过getName()和setName()访问,但是您必须编写自己的查找函数。

#3


4  

getComponentByName(frame, name)

getComponentByName(框架、名称)

IF you're using NetBeans or another IDE that by default creates private variables (fields) to hold all of your AWT/Swing components, then the following code may work for you. Use as follows:

如果您使用的是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());

Here's the code to make the above possible...

下面是使上述情况成为可能的代码……

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;
    }

}

It uses reflection to look through the class fields to see if it can find a component that is referred to by a variable of the same name.

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

NOTE: The code above uses generics to cast the results to whatever type you are expecting, so in some cases you may have to be explicit about type casting. For example if myOverloadedMethod accepts both JButton and JTextField, you may need to explicitly define the overload you wish to call ...

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

myOverloadedMethod((JButton) Awt1.getComponentByName(someOtherFrame, "jButton1"));

And if you're not sure, you can get an Component and check it with instanceof...

如果你不确定,你可以得到一个组件,然后用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
}

Hope this helps!

希望这可以帮助!

#4


2  

you could hold a reference to the first JFrame in the second JFrame and just loop through JFrame.getComponents(), checking the name of each element.

您可以在第二个JFrame中保存对第一个JFrame的引用,并通过JFrame. getcomponents()进行循环,检查每个元素的名称。

#5


1  

You can declare a variable as a public one then get the text or whatever operation you want and then you can access it in the other frame(if its in the same package) because it's public.

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

#6


1  

I needed to access elements inside several JPanels which were inside a single JFrame.

我需要访问在一个JFrame内的几个jpanel中的元素。

@Jesse Strickland posted a great answer, but the provided code is not able to access any nested elements (like in my case, inside JPanel).

@Jesse Strickland给出了一个很好的答案,但是提供的代码不能访问任何嵌套的元素(就像在我的例子中,在JPanel中)。

After additional Googling I found this recursive method provided by @aioobe here.

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

By combining and slightly modifying the code of @Jesse Strickland and @aioobe I got a working code that can access all the nested elements, no matter how deep they are:

通过结合和稍微修改@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;
}

Usage of the code is exactly the same as in @Jesse Strickland code.

代码的使用与@Jesse Strickland代码完全相同。

#7


0  

If your components are declared inside the same class you're manipulating them from, you simply access these components as attributes of the class name.

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

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

                     ...
                     ...
                     ...

                }
    ...
    ...
    ...
}

And, you may be able to access class components as attributes of the class name from other classes in the same namespace too. I can access protected attributes(class member variables), maybe you can access public components, too. Try it!

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

智能推荐

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.silva-art.net/blog/2011/02/10/d89566fae50d43a5e1b3f9b1eea0517b.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告