2014-10-31 1 views
0

Я использую самодельную панель инструментов для навигации по моему приложению, а панель инструментов присутствует на всех страницах. Каждый раз, когда появляется новая страница Я закрываю текущего кадра и открытие нового, используя следующий код:Закрытие и повторение кадра происходит с увеличением частоты каждый раз, когда одна кнопка нажата один раз

java.awt.Window win[] = java.awt.Window.getWindows(); 
for(int i=0;i<win.length;i++){ 
win[i].dispose(); 
} 

Я делаю это так, как ActionListeners объявлены в классе панели инструментов, в то время как кадры для каждой страницы объявляются во время выполнения и не являются статическими.

Это все работает отлично, за исключением одного конкретного случая - кнопки «Отмена», при первом обращении к кадру он будет закрываться один раз. Второй раз он закроется и откроется 2 раза, третий 3 и так далее. Я отслеживал это, используя «счетчик» в коде.

Я минимизировал код воссоздать такое же поведение, как показано ниже:

Toolbar Class

public class Toolbar { 

    static JButton buttonCancel = new JButton("Cancel"); 
    static int counter; 

    public static JPanel Toolbar(String panelname){ 

     FlowLayout layout = new FlowLayout(); 

     JPanel Toolbar = new JPanel(new BorderLayout()); 
     Toolbar.setLayout(layout); 

     GridLayout GLayout = new GridLayout(2,1); 
     GLayout.setVgap(0); 

     JPanel container2 = new JPanel(); 

     if(panelname.matches("Customers")){ 

     container2.setLayout(GLayout); 
     JButton buttonAddCust = new JButton("Add Cust"); 
     container2.add(buttonAddCust, BorderLayout.PAGE_START); 

     buttonAddCust.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 

       java.awt.Window win[] = java.awt.Window.getWindows(); 
       for(int i=0;i<win.length;i++){ 
       win[i].dispose(); 
       } 

      Customers.AddCustomersGui();   
      } 
     }); 
     } 


     JPanel container21 = new JPanel(); 
     if(panelname.matches("Add Customers")){ 
      container21.setLayout(GLayout); 
      container21.add(buttonCancel, BorderLayout.PAGE_START); 

      buttonCancel.addActionListener(new ActionListener() { 

       @Override 
       public void actionPerformed(ActionEvent e) { 

        counter ++;     
        java.awt.Window win[] = java.awt.Window.getWindows(); 
        for(int i=0;i<win.length;i++){ 
        win[i].dispose(); 
        }      
        System.out.println("Coutner " + counter);     
        Customers.CustomersGui(); 

       } 
       }); 
     } 

     Toolbar.add(container2);  
     Toolbar.add(container21); 

     return Toolbar; 

    } 



} 

класс GUI

public class Customers extends Toolbar{ 

    public static void CustomersGui(){ 

     final JFrame frame = new JFrame("Customers"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     JPanel customers = new JPanel(); 

     customers.add(Toolbar.Toolbar(frame.getTitle())); 

     frame.setContentPane(customers); 

     frame.setSize(1200,500); 

     frame.setVisible(true); 

    } 

    public static void AddCustomersGui(){ 

     final JFrame frame1 = new JFrame("Add Customers"); 
     frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     JPanel Addcustomers = new JPanel(); 

     Addcustomers.add(Toolbar.Toolbar(frame1.getTitle())); 

     frame1.setContentPane(Addcustomers); 

     frame1.setSize(1200,500); 

     frame1.setVisible(true); 
    } 
    } 

главный класс

public static void main(String[] args) { 

    Customers.CustomersGui(); 

} 
+0

Вы должны быть повторно добавить слушателя где-то –

+1

'" Каждый раз, когда отображается новая страница Я закрываю текущего кадра и открытие нового. «' - лучший дизайн, вероятно, не для того, чтобы менять окна, которые могут раздражать, а вместо того, чтобы сменять точки JPanel с помощью CardLayout. Пожалуйста, прочитайте [Использование нескольких JFrames, Хорошая/Плохая Практика?] (Http://stackoverflow.com/questions/9554636/the-use-of-multiple-jframes-good-bad-practice). –

+0

@ Alex- Почему вы снимаете все свои вопросы ??? Любая проблема??? –

ответ

2

You добавляют новый ActionListener в buttonCancel, с каждой итерацией вашего кода, и это является причиной поведения вашей программы.


Кроме того, в соответствии с моим комментарием, вы утверждаете,

Каждый раз, когда появляется новая страница Я закрываю текущего кадра и открытие нового.

Лучший дизайн, вероятно, не для того, чтобы менять окна, которые могут раздражать, а вместо того, чтобы менять вид JPanel с помощью CardLayout. Пожалуйста, прочитайте The Use of Multiple JFrames, Good/Bad Practice?.


Например, добавьте следующую строку кода в программе:

if (panelname.matches("Add Customers")) { 
    container21.setLayout(GLayout); 
    container21.add(buttonCancel, BorderLayout.PAGE_START); 
    buttonCancel.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      counter++; 
      java.awt.Window win[] = java.awt.Window.getWindows(); 
      for (int i = 0; i < win.length; i++) { 
       win[i].dispose(); 
      } 
      System.out.println("Coutner " + counter); 
      Customers.CustomersGui(); 
     } 
    }); 

    // ***** add this here ********** 
    System.out.println("buttonCancel ActionListener count: " 
      + buttonCancel.getListeners(ActionListener.class).length); 
    } 

, и вы увидите, что ActionListeners добавляются несколько раз эту кнопку.


Пример поменяв просмотров:

import java.awt.*; 
import java.awt.event.ActionEvent; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class SwapPanels extends JPanel { 
    public static final String CUSTOMER = "customer"; 
    public static final String ADD_CUSTOMER = "Add Customer"; 
    protected static final int PREF_W = 800; 
    protected static final int PREF_H = 600; 
    public static final String CANCEL = "Cancel"; 
    private CardLayout cardLayout = new CardLayout(); 

    public SwapPanels() { 
     setLayout(cardLayout); 

     add(createCustomerPanel(CUSTOMER), CUSTOMER); 
     add(createAddCustomerPanel(ADD_CUSTOMER), ADD_CUSTOMER); 
    } 

    public void showCard(String key) { 
     cardLayout.show(this, key); 
    } 

    public JPanel createAddCustomerPanel(String name) { 
     JPanel addCustPanel = new JPanel() { 
     @Override 
     public Dimension getPreferredSize() { 
      if (isPreferredSizeSet()) { 
       return super.getPreferredSize(); 
      } 
      return new Dimension(PREF_W, PREF_H); 
     } 
     }; 
     addCustPanel.setName(name); 
     addCustPanel.setBorder(BorderFactory.createTitledBorder(name)); 
     addCustPanel.add(new JButton(new AbstractAction(CANCEL) { 
     { 
      int mnemonic = (int)getValue(NAME).toString().charAt(0); 
      putValue(MNEMONIC_KEY, mnemonic); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      if (CANCEL.equals(e.getActionCommand())) { 
       SwapPanels.this.showCard(CUSTOMER); 
      } 
     } 
     })); 
     return addCustPanel; 
    } 

    private JPanel createCustomerPanel(String name) { 
     JPanel custPanel = new JPanel() { 
     @Override 
     public Dimension getPreferredSize() { 
      if (isPreferredSizeSet()) { 
       return super.getPreferredSize(); 
      } 
      return new Dimension(PREF_W, PREF_H); 
     } 
     }; 
     custPanel.setName(name); 
     custPanel.setBorder(BorderFactory.createTitledBorder(name)); 
     custPanel.add(new JButton(new AbstractAction(ADD_CUSTOMER) { 
     { 
      int mnemonic = (int)getValue(NAME).toString().charAt(0); 
      putValue(MNEMONIC_KEY, mnemonic); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      if (ADD_CUSTOMER.equals(e.getActionCommand())) { 
       SwapPanels.this.showCard(ADD_CUSTOMER); 
      } 
     } 
     })); 
     return custPanel; 
    } 

    private static void createAndShowGui() { 
     JFrame frame = new JFrame("SwapPanels"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(new SwapPanels()); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 
+0

, если это так, то почему это происходит только в одном случае, когда возникает идентичная ситуация с кнопкой buttonAddCust, но у нее нет такой же проблемы? –

+0

@jim: потому что вы создаете новый JButton для добавления cust, но не для отмены, и поэтому одна и та же кнопка добавляет слушателя несколько раз. –

Смежные вопросы