【问题标题】:Java Swing - How to disable a JPanel?Java Swing - 如何禁用 JPanel?
【发布时间】:2011-02-12 09:27:55
【问题描述】:

我在JPanel 上有几个JComponents,我想在按下“开始”按钮时禁用所有这些组件。

目前,我正在通过

显式禁用所有组件
component1.setEnabled(false);
:
:

但是无论如何我可以一次禁用所有组件吗?我试图禁用添加这些组件的JPanel

panel.setEnabled(false);

但是没有用。

【问题讨论】:

  • 为什么会有人这样做?似乎更容易将 Swing 组件放在 JDialog 上,当用户单击 Ok 按钮(可以重命名为 Start)时,您使该 JDialog 不可见。
  • @GilbertLeBlanc 我可以为自己说话——我来这里是为了寻找一种暂时禁用特定区域的方法——以表明它正在等待某个过程完成。 @YatendraGoel 你的代码中有那些: 的原因吗?

标签: java swing jpanel


【解决方案1】:

面板应该有一个getComponents() 方法,可以在循环中使用它来禁用子组件而无需显式命名。

【讨论】:

  • +1 我用过这个。但是警告,如果您的子组件是容器(例如用于布局管理的框),那么您需要递归地执行此操作。此外,如果您的组件因其他原因而被禁用,那么重新启用将会使它们失效。
  • 同意staticman,这是一种危险的行为,使用时需要小心,因为如果不小心,您将重新启用一切。也许这对您的情况来说不是问题,那么您可以喜欢这个。或者,如果它是一个 pb,那么您可能必须在禁用它们之前记住组件的状态,以便将它们重置为良好状态。
  • 这有点棘手,但我不会说危险。我的常规方法是继承JPanel 并覆盖setEnabled() 方法。在那里,我将根据内部状态手动启用/禁用适当的子组件。
  • @staticman @MatthieuBROUILLARD 我不明白。为什么调用setEnabled(false) 会重新启用任何东西?
  • @line 他的意思是setEnabled(true) 可以启用一切,即使你想要只读元素。
【解决方案2】:

使用 JXLayerLockableUI

【讨论】:

  • 投反对票,因为没有解释或示例如何使用它,并且链接现在已损坏
【解决方案3】:

Disabled Panel 支持两种方法。一个用于递归禁用组件,另一个用于“绘制”具有禁用外观的面板。

【讨论】:

    【解决方案4】:

    以下方法使用递归来实现这一点。传入任何Container,此方法将返回一个Component 数组,其中包含位于Container“内部”任何位置的所有非容器组件。

        private Component[] getComponents(Component container) {
            ArrayList<Component> list = null;
    
            try {
                list = new ArrayList<Component>(Arrays.asList(
                      ((Container) container).getComponents()));
                for (int index = 0; index < list.size(); index++) {
                    for (Component currentComponent : getComponents(list.get(index))) {
                        list.add(currentComponent);
                    }
                }
            } catch (ClassCastException e) {
                list = new ArrayList<Component>();
            }
    
            return list.toArray(new Component[list.size()]);
            }
        }
    

    只需循环遍历返回数组的元素并禁用组件。

    for(Component component : getComponents(container)) {
        component.setEnabled(false);
    }
    

    【讨论】:

      【解决方案5】:

      下面的方法应该就是你需要添加的全部了,你可以用setEnableRec(panel, true)或者setEnableRec(panel, false)调用它:

      private void setEnableRec(Component container, boolean enable){
          container.setEnabled(enable);
      
          try {
              Component[] components= ((Container) container).getComponents();
              for (int i = 0; i < components.length; i++) {
                  setEnableRec(components[i], enable);
              }
          } catch (ClassCastException e) {
      
          }
      }
      

      【讨论】:

      • 如果您将第一条指令container.setEnabled(enable) 移动到catch 中,那么您可以保留容器的某些功能,例如JTabbed 仍然可以点击。
      • 也要小心,因为如果一个元素应该在启用循环中保持禁用状态,那么此方法将覆盖所有内容。
      【解决方案6】:

      禁用应该递归发生:

      Queue<Component> queue = new LinkedList<>(Arrays.asList(container.getComponents()));
      while(!queue.isEmpty()) {
          Component head = queue.poll();
          head.setEnabled(enable);
          if(head instanceof Container) {
              Container headCast = (Container) head;
              queue.addAll(Arrays.asList(headCast.getComponents()));
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-07
        • 2011-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多