2010-08-12 22 views
5

Moja aplikacja posiada moduł, który pozwala użytkownikowi dodawać jButtons na jLayeredpane podczas pracy. Chcę dodawać detektory akcji do tej dynamicznie dodawanej zawartości, a także muszę zapewnić dostęp do usuwania dynamicznie dodawanych przycisków w czasie wykonywania. Czy jest jakiś sposób to zrobić?Java Swing dodaj/usuń jButtons on runtime

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

Zreformowany kod; proszę cofnąć, jeśli jest niepoprawna. – trashgod

+0

Moja ostatnia edycja zawiera kod, który doda przyciski, które klikniesz. I usuń przyciski, jeśli klikniesz na nich po kliknięciu na usuń. – jjnguy

Odpowiedz

10

Original OdpowiedźDobry w ogóle, ale odbywa się w różny sposób w tym przypadku

Aby śledzić dowolną liczbę dodany JButtons, trzeba będzie przechowywać je w postaci listy.

Po utworzeniu nowego przycisku dodaj do niego słuchaczy i dodaj go do panelu, następnie zapisz ten nowy przycisk na liście.

W ten sposób możesz śledzić wszystkie dodane przyciski.

Można również użyć przycisku Map<String, JButton>, który odwzorowuje nazwę przycisku na przycisk.

Przykład:

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

Poniżej znajduje się pełna klasa, która pozwala dodawać i usuwać przyciski dynamicznie. Nie jest to dokładnie to, czego chcesz, ale powinno ci to bardzo pomóc.

Kod dla konkretnego przypadku:

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

Jestem nowy na huśtawce, więc czy mógłbyś trochę się rozwinąć? Będę wdzięczny, jeśli wyjaśnisz próbką kodu. – Deepak

+0

@Deepak, potrzebujesz 2 statyczne przyciski w ramce. Jeden do dodania przycisku i jeden do usunięcia przycisku. Następnie dodasz detektor akcji do obu tych przycisków.Akcja dla przycisku Dodaj będzie miała postać 'addButton (ciąg)', a akcją dla przycisku Usuń będzie "removeButton (ciąg)". – jjnguy

+0

dzięki za wyjaśnienie kodu, po prostu powiedz mi, gdzie powinienem dodać ten fragment kodu? jest w osobnym pliku klasy lub razem z plikiem jframe? – Deepak

6

Absolutnie. Wszystko to można zrobić programowo w dowolnym momencie. Oto kilka wskazówek, aby uniknąć problemów i pułapek:

  • Podczas dodawania składników do każdego panelu, upewnij się to odbywa się na wątku Event Dispatch przez SwingUtilities.invokeLater(Runnable). Wewnątrz Runnable, chcesz dodać komponent do panelu, podłączyć słuchaczy i zmienić układ panelu.
  • Użyj SwingUtilities.isEventDispatchThread(), aby sprawdzić, czy jesteś już w wątku wysyłki zdarzeń. Jeśli tak, to możesz po prostu uruchomić Runnable natychmiast, zamiast dzwonić pod numer invokeLater.
  • Po zmodyfikowaniu układu panelu, należy zadzwonić pod numer Component.invalidate(), aby upewnić się, że zostanie ponownie rozłożony.
  • Zachowaj własną listę słuchaczy. Zastąp metody dodawania i usuwania na panelu, aby dodać lub usunąć je z listy, a także ze wszystkich istniejących przycisków. Po dodaniu nowych przycisków dodaj wszystkich odbiorców na liście.

Jest to bardzo częste zadanie i jest w pełni obsługiwane przez Javę. Powinieneś być w stanie zrobić to bez większych problemów.

+0

Wiem, że możemy to zrobić, ale jestem nowy, aby wymieniać się pojęciami, więc nie wiem zbyt wiele.Mam jeszcze jeden problem, muszę podać różne nazwy guziki utworzone, czy możesz wyjaśnić to w przykładowym kodzie? lub po prostu daj mi link do naśladowania.Zapytam przykładowy kod do mojego oryginalnego pytania, jak również – Deepak

+0

Zapytałeś, czy był jakiś sposób, aby to zrobić, i istnieje. Zależy to od implementacji, ponieważ to Ty jesteś tym, który ją implementuje, nie powinieneś mieć problemu ze złożeniem kodu, aby to zrobić i ustaleniem szczegółów. Jeśli utkniesz przy danym szczególe, zapytaj o to konkretnie: –

+3

wiele rzeczy się dzieje.Zapytałeś dość wysokie pytanie z kilkoma ruchomymi częściami w odpowiedzi.To zbyt dużo kodu, aby napisać tylko na jedno pytanie.Zalecam, polecam spróbować samemu i poprosić o Inne pytanie, jeśli coś utkniesz. –