【问题标题】:Swing UI: not visible components remain activeSwing UI:不可见的组件保持活动状态
【发布时间】:2016-09-08 03:17:49
【问题描述】:

我正在使用JComponents 构建用户界面。 UI 应该以这种方式工作:根据设置的值(例如通过JComboBox),显示不同的JComponents。

我的想法是 @Override 每个组件的 isVisible() 方法,或者,通过 JComboBox 将它们设置为可见或不可见。实际上,这两种方法都有效,因为当我更改 JComboBox 值时,所需的组件会在 JPanel 中出现和消失。

问题在于,即使组件在面板中不可见,它仍然处于活动状态并单击它应该在的位置(如果可见),它会触发其动作。例如。我将鼠标移到另一个JComboBox 应该在的位置上;组合框不可见,但鼠标光标变为Cursor.HAND_CURSOR,如果我点击,组合框项目的弹出列表会出现,我可以选择其中一项。

这是我正在使用的代码的一个示例:

public class MyPanel extends JPanel{
    public MyPanel(){
        super(new GridBagLayout());
        GridBagConstraints g = new GridBagConstraints(
            0,                              // int gridx
            -1,                             // int gridy
            1,                              // int gridwidth
            1,                              // int gridheight
            1,                              // double weightx
            1,                              // double weighty
            GridBagConstraints.NORTHWEST,   // int anchor
            GridBagConstraints.NONE,        // int fill
            new Insets(0,0,0,0),            // Insets insets
            0,                              // int ipadx
            0                               // int ipady
         );

        String[] comboItems = {"ShowCombo1","ShowCheckbox","ShowTextField"};
        JComboBox combo = new JComboBox(comboItems);

        JComboBox combo1 = new JComboBox(){
            @Override
            public boolean isVisible(){
                return combo.getSelectedIndex()==0;
            }
        };

        JCheckBox checkBox= new JCheckBox(){
            @Override
            public boolean isVisible(){
                return combo.getSelectedIndex()==1;
            }
        };

        JTextField textField= new JTextField(){
            @Override
            public boolean isVisible(){
                 return combo.getSelectedIndex()==2;
            }
        };

        add(combo,g);
        g.gridy += 1;
        add(combo1,g);
        g.gridy += 1;
        add(checkBox,g);
        g.gridy += 1;
        add(textField,g);
    }
}

有没有更好的方法来管理这类用户界面?

【问题讨论】:

  • 我认为你必须展示一些代码。否则很难分析。
  • @Vampire 我认为你是对的! :)
  • 如果您不想触发不可见组件的操作,也许您可​​以同时设置不可见组件和 setEnable(false) 其子组件但是使用代码会更清楚
  • 是的,有更好的方法。根据 JComboBox 选择为您想要的每个 JComponents 组合创建一个单独的 JPanel,并使用 CardLayout 管理 JPanel。

标签: java swing user-interface


【解决方案1】:

我认为通过您的方法,您只需根据选择将标志返回为真。在内部,setVisible(false) 不仅仅是关闭标志。它调用 super.setVisible(false) 来执行以下操作。

/**
     * Shows or hides this component depending on the value of parameter
     * <code>b</code>.
     * <p>
     * This method changes layout-related information, and therefore,
     * invalidates the component hierarchy.
     *
     * @param b  if <code>true</code>, shows this component;
     * otherwise, hides this component
     * @see #isVisible
     * @see #invalidate
     * @since JDK1.1
     */
    public void setVisible(boolean b) {
        show(b);
    }

    /**
     * @deprecated As of JDK version 1.1,
     * replaced by <code>setVisible(boolean)</code>.
     */
    @Deprecated
    public void show() {
        if (!visible) {
            synchronized (getTreeLock()) {
                visible = true;
                mixOnShowing();
                ComponentPeer peer = this.peer;
                if (peer != null) {
                    peer.setVisible(true);
                    createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED,
                                          this, parent,
                                          HierarchyEvent.SHOWING_CHANGED,
                                          Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
                    if (peer instanceof LightweightPeer) {
                        repaint();
                    }
                    updateCursorImmediately();
                }

                if (componentListener != null ||
                    (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 ||
                    Toolkit.enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK)) {
                    ComponentEvent e = new ComponentEvent(this,
                                                          ComponentEvent.COMPONENT_SHOWN);
                    Toolkit.getEventQueue().postEvent(e);
                }
            }
            Container parent = this.parent;
            if (parent != null) {
                parent.invalidate();
            }
        }
    }

虽然我不明白他们实际上在做什么:-),但我觉得这部分代码需要执行。

【讨论】:

  • 非常感谢。我也认识到这两种方法是不同的,重写isVisible()方法是不够的。
猜你喜欢
  • 2012-03-09
  • 2012-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-14
  • 2011-11-22
相关资源
最近更新 更多