2011-02-10 129 views
14

Swing组件我有一个JFrame一些组件,我想 指到另一个JFrame,我想 的名字,让他们不 做每个公共get/set方法。按名称获取

有没有一种方法可以从Swing获取组件引用的名称,就像do c#?

例如form.Controls["text"]

感谢

+1

Window.getWindows()然后扫描你需要的东西 – bestsss 2011-02-10 15:05:56

+1

为什么你想在世界上这样做?通过这样做,您将失去两个重要的静态编译器检查: - 首先,该字段存在。 - 其次,它是正确的类型。另外,动态查询比引用该字段要慢。 – fortran 2011-02-10 15:11:23

回答

27

我知道这是一个古老的问题,但我发现自己现在就问它。我想要一个简单的方法来按名称获取组件,所以我不必每次都写一些令人费解的代码来访问不同的组件。例如,让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. 在你的类中定义以下两种方法。你需要进口元件,如果您尚未:

    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. 现在你已经得到了所有当前存在的组件映射在帧/内容窗格/板/等,以各自的名称一个HashMap 。

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

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

1

可以声明一个变量作为一个公众一个再得到你想要的文字或任何操作,然后就可以在其他帧访问它(如果在同一个包),因为它是公众。

2

您可以在第二个JFrame中持有对第一个JFrame的引用,并通过JFrame.getComponents()循环检查每个元素的名称。

6

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

4

getComponentByName(框架名)

如果你正在使用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 &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; 
    } 

} 

它使用反射通过类领域看,看它是否可以找到被称为组件由一个相同名称的变量。

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

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

如果你不知道,你可以得到一个Componentinstanceof检查...

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

希望这有助于!

1

我需要访问几个JPanel之内的元素,这些元素在单个JFrame之内。

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

经过额外的Google搜索后,我发现@aioobe here提供了这种递归方法。

通过组合和修改稍微斯特里克兰@Jesse和@​​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代码完全一样。

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

        ... 
        ... 
        ... 

       } 
    ... 
    ... 
    ... 
} 

而且,你可以能够访问类组件如在同一个名字太从其他类的类名的属性。我可以访问受保护的属性(类成员变量),也许你也可以访问公共组件。尝试一下!