简体   繁体   中英

Swing : Focus Components

I have a Frame that contains CardLayout with various JPanels setting it to center of the JFrame.

On 1st Panel, I have focus on 1st component ie a button. But can't have focus on other panels or components. While setting the required panel, I use the following code :

public void SetMainPanel(String panel) {
    activePanel = panel;
    SetFontSize();
    cards.show(mainPanel, panel);
    mainPanel.revalidate();
    mainPanel.repaint();
    mainPanel.requestFocusInWindow();
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            mainPanel.grabFocus();
            mainPanel.getComponent(0).requestFocus();
        }
    });
    //mainPanel.getComponent(0).requestFocusInWindow();
}

But I can't get focus on the panel or its 1st component. How can I make the setting panel to have focus and focus on its 1st component ? Finally, for focus on each Panel what is better - FocusPolicy, Manager, Keyboard.... Panels either has all buttons OR table and buttons OR form with fields. There are this 3 types of Panels. BTW, the panels added to cardLayout are focusable.

Any ideas....

EDIT : Code has been edited as shown by mKorbel.

You should be able to add a ComponentListener to the panel and handle the componentShown() event to place focus on whatever component you want.

Or Card Layout Focus extends the CardLayout to provide this functionality by default.

in most of cases (when is Focus_Cycle inside one Container) works for me follows code

    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            mainPanel.getComponent(0).grabFocus();
            mainPanel.getComponent(0).requestFocus();
            // or mainPanel.getComponent(0).requestFocusInWindow();
        }
    });

Arrgg ... should have known that Rob has a nice ready-to-use class for handling the case :-) Adding this nevertheless, to emphasize the basics

The base problem is that focus transfer gets completely confused when the focused component is removed from the hierarchy (as happens when showing a new card). In this case, the transfer has to be handled manually. Rob's solution is sound and basically the same as this. Both trigger the focus transfer by messaging card.transferFocus: the advantage over requestFocus is twofold

  • safe if there is no child (or no focusable)
  • leaves the timing/queuing issue to be handled by the default mechanism

Here's a code snippet of the bare-bones approach

    final CardLayout layout = new CardLayout();
    final JComponent main = new JPanel(layout );
    Action action = new AbstractAction("toggle cards") {

        @Override
        public void actionPerformed(ActionEvent e) {
            layout.next(main);
            Component visibleChild = main.getComponent(0).isVisible() ?
                    main.getComponent(0) : main.getComponent(1);
            visibleChild.transferFocus();        
        }
    };
    main.getActionMap().put("nextCard", action);
    main.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
       .put(KeyStroke.getKeyStroke("F2"), "nextCard");
    JComponent first = new JPanel();
    first.add(new JTextField(20));
    first.add(new JButton("dummy on first"));

    JComponent second = new JPanel();
    second.add(new JTextField("I'm on the second"));
    second.add(new JButton("me on second, too"));

    main.add(first, "one");
    main.add(second, "two");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM