2010-08-12 34 views
5

Mi aplicación tiene un módulo que permite al usuario agregar jButtons en el jLayeredpane durante el tiempo de ejecución. Quiero agregar detectores de acción a estos contenidos dinámicamente agregados y también tengo que proporcionar acceso para eliminar los botones agregados dinámicamente durante el tiempo de ejecución. ¿Hay alguna manera de hacer esto?Java Swing agregar/eliminar jButtons en tiempo de ejecución

private Map<String, JButton> dynamicButtons; 

public void addButton(String name) { 
    JButton b = new JButton(name); 
    b.addActionListener(new java.awt.event.ActionListener() { 

     public void actionPerformed(java.awt.event.ActionEvent evt) { 
      jButton1ActionPerformed(evt); 
     } 
    }); 

    jLayeredPane2.add(b); 
    dynamicButtons.put(name, b); 
    jLayeredPane2.invalidate(); 
} 

public void removeButton(String name) { 
    JButton b = dynamicButtons.remove(name); 
    jLayeredPane2.remove(b); 
    jLayeredPane2.invalidate(); 
} 
+0

Código reformado; por favor revertir si es incorrecto. – trashgod

+0

Mi última edición tiene un código que agregará botones donde haga clic. Y quite los botones si hace clic en ellos después de hacer clic en Eliminar. – jjnguy

Respuesta

10

respuesta originalbuena en general, pero hecho de manera diferente, en este caso

Con el fin de realizar un seguimiento de un número arbitrario de agregado JButtons, tendrá que mantenerlos en una lista.

Por lo tanto, después de crear un nuevo botón, agregarle los oyentes y agregarlo al panel, debe guardar ese nuevo botón en una lista.

De esta manera puede realizar un seguimiento de todos los botones que ha agregado.

También puede usar un Map<String, JButton> que asigna un nombre de botón al botón.

Ejemplo:

private Map<String, JButton> dynamicButtons; 

public void addButton(String name) { 
    JButton b = new JButton(name); 
    b.addActionListener(someAction); 
    yourPanel.add(b); 
    dynamicButtons.put(name, b); 
    yourPanel.invalidate(); 
} 

public void removeButton(String name) { 
    Button b = dynamicButtons.remove(name); 
    yourPanel.remove(b); 
    yourPanel.invalidate(); 
} 

La siguiente es una clase completa que le permite agregar y quitar botones de forma dinámica. No es exactamente lo que quieres, pero te debería acercar mucho.

Código

para su caso específico:

import java.awt.BorderLayout; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 

public class ExampleFrame extends JFrame { 

    private JButton add, remove; 
    private JPanel dynamicButtonPane, addRemovePane; 

    private boolean waitingForLocationClick; 

    public ExampleFrame() { 
     super("Dynamic button example"); 
     waitingForLocationClick = false; 
     add = new JButton("Add Button"); 
     add.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       addButton(JOptionPane 
         .showInputDialog("Name of the new button:")); 
      } 
     }); 
     remove = new JButton("Remove Button"); 
     remove.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       lookingToRemove = true; 
      } 
     }); 
     JPanel mainPane = new JPanel(new BorderLayout()); 
     dynamicButtonPane = new JPanel(); 
     dynamicButtonPane.setLayout(null); 
     dynamicButtonPane.setPreferredSize(new Dimension(300, 300)); 
     addRemovePane = new JPanel(); 
     addRemovePane.add(add); 
     addRemovePane.add(remove); 
     mainPane.add(dynamicButtonPane, BorderLayout.NORTH); 
     mainPane.add(addRemovePane, BorderLayout.SOUTH); 
     add(mainPane); 
     pack(); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setVisible(true); 
     dynamicButtonPane.addMouseListener(pointSelectorListener); 
    } 

    private JButton buttonToPlace; 

    public void addButton(String name) { 
     JButton b = new JButton(name); 
     b.setActionCommand(name); 
     b.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       if (lookingToRemove) { 
        if (e.getSource() instanceof JButton) { 
         dynamicButtonPane.remove((Component) e.getSource()); 
         dynamicButtonPane.validate(); 
         dynamicButtonPane.repaint(); 
        } 
       } else 
        JOptionPane.showMessageDialog(ExampleFrame.this, "This is " + e.getActionCommand()); 
      } 
     }); 
     waitingForLocationClick = true; 
     lookingToRemove = false; 
     buttonToPlace = b; 
    } 

    public void putButtonAtPoint(Point p) { 
     System.out.println("Placing a button at: " + p.toString()); 
     dynamicButtonPane.add(buttonToPlace); 
     buttonToPlace.setBounds(new Rectangle(p, buttonToPlace 
       .getPreferredSize())); 
     dynamicButtonPane.validate(); 
     buttonToPlace = null; 
     waitingForLocationClick = false; 
    } 

    private boolean lookingToRemove = false; 

    private final MouseListener pointSelectorListener = new MouseAdapter() { 
     @Override 
     public void mouseClicked(MouseEvent e) { 
      if (waitingForLocationClick) { 
       putButtonAtPoint(e.getPoint()); 
      } else { 
       System.out.println("Not in waiting state"); 
      } 
     } 
    }; 

    public static void main(String[] args) { 
     new ExampleFrame(); 
    } 
} 
+0

soy nuevo en swing, ¿puedes elaborar un poco? Le agradeceré si explica con código de muestra .. – Deepak

+0

@Deepak, necesita 2 botones estáticos en su Marco. Uno para agregar un botón y otro para quitar un botón. A continuación, agregará un detector de acciones a ambos botones.La acción para el botón Agregar será el método 'addButton (cadena)', y la acción para el botón Eliminar será 'removeButton (cadena)'. – jjnguy

+0

gracias por la explicación del código, solo dime ¿dónde debería agregar este código? ¿está en un archivo de clase separado o junto con el archivo jframe? – Deepak

6

Absolutamente. Todas estas cosas se pueden hacer programáticamente en cualquier momento. Aquí hay un par de consejos para evitar problemas y dificultades:

  • Cuando añade componentes a cualquier panel, asegúrese de que esto se hace en el hilo de eventos a través de Despacho SwingUtilities.invokeLater(Runnable). Dentro de Runnable, desea agregar el componente al panel, conectar los oyentes y rediseñar el panel.
  • Usa SwingUtilities.isEventDispatchThread() para comprobar si ya estás en el hilo de envío del evento. Si es así, puede ejecutar Runnable inmediatamente en lugar de llamar al invokeLater.
  • Una vez que haya modificado el diseño de un panel, asegúrese de llamar al Component.invalidate() en el panel para asegurarse de que se distribuye nuevamente.
  • Mantenga su propia lista de oyentes. Sobrescriba los métodos de agregar y eliminar en el panel para agregarlos o eliminarlos de su lista y también de todos los botones existentes. Cuando agregue nuevos botones, agregue todos los oyentes en la lista.

Esta es una tarea muy común, y es totalmente compatible con Java. Debería poder hacerlo sin demasiados problemas.

+0

Sé que podemos hacer esto pero soy nuevo en los conceptos de swing, así que no sé mucho. Tengo un problema más que necesito para dar diferentes nombres a botones creados. ¿Puedes explicarlo en la muestra del código? o simplemente darme un enlace para seguir. También quiero el ejemplo de código para mi pregunta original. – Deepak

+0

Me preguntaste si había alguna forma de hacerlo, y la hay. La muestra del código sería sea ​​bastante dependiente de la implementación. Como usted es el que lo implementa, no debería tener problemas para armar el código para hacerlo y averiguar los detalles. Si se queda atascado con un detalle en particular, pregunte acerca de eso específicamente. –

+3

Básicamente, hay sucedieron muchas cosas. Usted hizo una pregunta bastante importante con varias partes móviles en la respuesta. Es demasiado código para escribir solo para una pregunta. Le recomiendo que lo intente usted mismo y le pida a un Otra pregunta si te quedas atascado con algo. –

Cuestiones relacionadas