Obtener un componente Swing por nombre

Tengo en un JFrame algunos componentes que quiero referir a otro JFrame y quiero obtenerlos por nombre y no hacer públicos los métodos get / set para cada uno.

¿Hay alguna forma de Swing para obtener una referencia de componente por su nombre como do c #?

por ejemplo, form.Controls["text"]

Gracias

Sé que esta es una vieja pregunta, pero me encontré preguntándola hace un momento. Quería una manera fácil de obtener componentes por nombre, así que no tenía que escribir un código complicado cada vez para acceder a diferentes componentes. Por ejemplo, tener un JButton accede al texto en un campo de texto o una selección en una lista.

La solución más fácil es hacer que todas las variables componentes sean variables de clase para que pueda acceder a ellas en cualquier lugar. Sin embargo, no todos quieren hacer eso, y algunos (como yo) están usando editores de GUI que no generan los componentes como variables de clase.

Mi solución es simple, por lo que sé, y realmente no infringe ningún estándar de progtwigción (haciendo referencia a lo que Fortran estaba consiguiendo). Permite una forma fácil y directa de acceder a los componentes por su nombre.

  1. Crea una variable de clase Map. Necesitarás importar HashMap por lo menos. Llamé a mi componentMap por simplicidad.

     private HashMap componentMap; 
  2. Agregue todos sus componentes al marco como siempre.

     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 los siguientes dos métodos en tu clase. Deberá importar Component si aún no lo ha hecho:

     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. Ahora tiene un HashMap que mapea todos los componentes existentes en su marco / panel de contenido / panel / etc a sus respectivos nombres.

  5. Para acceder ahora a estos componentes, es tan simple como una llamada a getComponentByName (String name). Si existe un componente con ese nombre, devolverá ese componente. Si no, devuelve nulo. Es su responsabilidad colocar el componente en el tipo correcto. Sugiero usar instanceof para estar seguro.

Si planea agregar, eliminar o cambiar el nombre de los componentes en cualquier momento durante el tiempo de ejecución, consideraría agregar métodos que modifiquen el HashMap de acuerdo con sus cambios.

Cada Component puede tener un nombre, al que se accede a través de getName() y setName() , pero deberá escribir su propia función de búsqueda.

getComponentByName (frame, name)

SI está usando NetBeans u otro IDE que por defecto crea variables privadas (campos) para contener todos sus componentes AWT / Swing, entonces el siguiente código puede funcionar para usted. Use de la siguiente manera:

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

Aquí está el código para hacer que lo anterior sea posible …

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

Utiliza la reflexión para mirar a través de los campos de clase para ver si puede encontrar un componente al que hace referencia una variable del mismo nombre.

NOTA: El código anterior usa generics para arrojar los resultados al tipo que espere, por lo que en algunos casos es posible que tenga que ser explícito sobre el tipo de conversión. Por ejemplo, si myOverloadedMethod acepta JButton y JTextField , es posible que deba definir explícitamente la sobrecarga a la que desea llamar …

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

Y si no está seguro, puede obtener un Component y verificarlo con 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 } 

¡Espero que esto ayude!

puede mantener una referencia al primer JFrame en el segundo JFrame y simplemente recorrer mediante bucle JFrame.getComponents (), verificando el nombre de cada elemento.

Puede declarar una variable como pública y luego obtener el texto o la operación que desee y luego puede acceder a ella en el otro marco (si está en el mismo paquete) porque es público.

Necesitaba acceder a elementos dentro de varios JPanel que estaban dentro de un solo JFrame .

@Jesse Strickland publicó una gran respuesta, pero el código proporcionado no puede acceder a ningún elemento nested (como en mi caso, dentro de JPanel ).

Después de Google adicional encontré este método recursivo proporcionado por @aioobe aquí .

Al combinar y modificar ligeramente el código de @Jesse Strickland y @aioobe obtuve un código de trabajo que puede acceder a todos los elementos nesteds, sin importar qué tan profundos sean:

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

El uso del código es exactamente el mismo que en el código de @Jesse Strickland.

Si sus componentes están declarados dentro de la misma clase a la que los está manipulando, simplemente acceda a estos componentes como atributos del nombre de la clase .

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

Además, es posible que pueda acceder a los componentes de la clase como atributos del nombre de clase de otras clases en el mismo espacio de nombres . Puedo acceder a los atributos protegidos (variables miembro de la clase), tal vez también se puede acceder a los componentes públicos. ¡Intentalo!