Swing:聚焦组件

时间:2011-12-08 14:32:39

标签: java swing focus

我有一个包含CardLayout的Frame,其中包含各种JPanel,将其设置为JFrame的中心。

在第一个面板上,我专注于第一个组件,即一个按钮。但不能专注于其他面板或组件。在设置所需的面板时,我使用以下代码:

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

但我无法专注于面板或其第一部分。如何使设置面板具有焦点并专注于其第一个组件?最后,为了专注于每个面板什么是更好的 - FocusPolicy,经理,键盘....面板要么具有所有按钮或表格和按钮或形式与字段。有这3种类型的面板。 顺便说一下,添加到cardLayout的面板是可以关注的。

任何想法......

编辑:代码已经过编辑,如mKorbel所示。

3 个答案:

答案 0 :(得分:4)

您应该能够将ComponentListener添加到面板并处理componentShown()事件,以便将焦点放在您想要的任何组件上。

或者Card Layout Focus扩展了CardLayout以默认提供此功能。

答案 1 :(得分:2)

在大多数情况下(当一个Container内的Focus_Cycle何时)对我有用,遵循代码

    EventQueue.invokeLater(new Runnable() {

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

答案 2 :(得分:1)

Arrgg ......应该知道Rob有一个很好的即用型课程来处理这个案例:-)然后添加它来强调基础知识

基本问题是当聚焦组件从层次结构中移除时焦点转移完全混淆(如显示新卡时所发生的那样)。在这种情况下,必须手动处理转移。 Rob的解决方案是合理的,基本上与此相同。两者都通过消息传递卡触发焦点转移.transferFocus:优于requestFocus的优势是双重的

  • 如果没有孩子(或没有专注),则安全
  • 使时间/排队问题由默认机制
  • 处理

这是一个简单方法的代码片段

    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");