1 Reply Latest reply: Jul 30, 2013 7:40 AM by PhHein RSS

    How to Resolve Strange Menu Item Accelerator Behavior After Removing A JButton in OSX

    user7443702

      I have a simple Swing application to demonstrate a weird behavior where remove and add a new component i.e. removed and added a new JButton caused the JMenuItem accelerator, "F3" not to response. What I experienced was,

       

      1. Pressed F3 for the 1st time worked (the JButton label number increase by 1. Pressed F3 repeatedly did not work. If I clicked on a button and pressed F3 again, it worked again.

      2. Next scenario, instead of clicked on the button, I clicked on the menu item "Refresh", pressed F3 repeatedly worked all the way.

       

      If I did not remove the JButton and modified the label, it worked perfectly. Where did my code go wrong? This issue occurred only with JDK 1.7 on top of OSX (Mountain Lion). Windows and Linux do not exhibit this problem.

       

      This is just an example. In actual, I have variable number of JLabel and JButton inside the ContentPane. This number of labels and buttons changes depending on input but the total number components is fixed.

       

      Thanks

       

      /lim/

       

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

      public class ClickMeFrame {
          private JButton clickMe = new JButton("1");

          public ClickMeFrame() {
              JFrame app = new JFrame("Numbers Frame");
              app.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);


              final Container appContent = app.getContentPane();
              clickMe.setSize(new Dimension(20, 20));
              appContent.add(clickMe);

              JMenuBar menuBar = new JMenuBar();

              JMenu file = new JMenu("File");
              menuBar.add(file);

              AbstractAction refreshAction = new AbstractAction() {
                  @Override
                  public void actionPerformed(ActionEvent e) {
                      System.out.println("Refresh");
                      SwingUtilities.invokeLater(new Runnable() {
                          @Override
                          public void run() {
                              int nextIndex = Integer.parseInt(clickMe.getText()) + 1;
                              // remove from here
                              appContent.remove(clickMe);
                              clickMe = new JButton(nextIndex + "");
                              appContent.add(clickMe);
                              // to here to experiment with button text change instead of replacing with a new JButton

                              // enable me to experiment with button text change instead
      //                        clickMe.setText(nextIndex + "");
                              appContent.revalidate();
                              appContent.repaint();
                          }
                      });
                  }
              };

              JMenuItem refresh = new JMenuItem("Refresh");
              refresh.setAccelerator(KeyStroke.getKeyStroke("F3"));
              refresh.addActionListener(refreshAction);
              file.add(refresh);
              app.setJMenuBar(menuBar);
              app.pack();
              app.setVisible(true);
          }

          public static void main(String[] args) {
              new ClickMeFrame();
          }
      }