【问题标题】:Java JTabbedPane questionsJava JTabbedPane 问题
【发布时间】:2023-03-16 05:59:01
【问题描述】:

我正在使用 JTabbedPane 来保存我正在构建的向导中的每个步骤。步骤之间的导航是使用上一个/下一个按钮或通过选择一个选项卡进行的。按钮减少/增加 JTabbedPane 的 SelectedIndex。

在进行下一步之前,我需要验证每个步骤。本质上,我很难确定要使用哪个事件。 StateChange 事件发生得太晚。我需要观察哪个事件?

另一个烦人:当向导运行时,它似乎保存了 JTabbedPane 的 SelectedIndex 的状态(通常是最后一步的值),然后在下次运行向导时使用这个值来设置 SelectedIndex。设计器中的 selectedIndex 属性没有改变。此外,在 JPanel 的构造函数中调用 setSelectedIndex() 似乎对此没有影响。我错过了什么?

【问题讨论】:

    标签: java swing jpanel wizard jtabbedpane


    【解决方案1】:

    考虑使用CardLayout,而不是JTabbedPane。后者让您可以更严格地控​​制导航。

    【讨论】:

    • CardLayout 运行良好。两个相关的问题。 1:有没有办法显示标签? 2:我可以使用哪个事件来验证每张卡上的条目?
    • "我可以使用哪个事件来验证每张卡上的条目?" - 当用户按下 Next 按钮时,在 actionPerformed() 方法中进行验证,如果验证失败,不要更改面板。
    • "有没有办法显示标签?" - 我认为您不想显示选项卡,但我认为您可能希望显示步骤列表,并指出用户正在执行的步骤。我建议在向导面板的左侧使用垂直面板,每个步骤都使用 JLabels,并使用粗体突出显示当前步骤。
    • David 的 cmets 非常有说服力。真正的问题不是“我应该使用什么组件?”但是“我如何引导用户做出连贯的选择?”创建具有合适默认值的模型可能会有所帮助,这样用户就不会因为不清楚问题所在而“卡住”。尝试创建“首选项”而不是“序列”。
    【解决方案2】:

    您可以扩展 JTabbedPane 以覆盖 setSelectedIndex 方法,然后调用 super.setSelectedIndex(index);在进行验证后:

    public class ValidationTabbedPane extends JTabbedPane {
        private static final long serialVersionUID = 1L;
    
        public ValidationTabbedPane() {
            super();
          }
    
          @Override
          public void setSelectedIndex(int index) {
              if (index >= 0 && index < getTabCount()) {
                  if(getSelectedIndex() == -1) {
                      super.setSelectedIndex(index);
                  } else  {
                      Containers tab = tabs.get(getSelectedIndex());
                      boolean change = true;
                      if(tab.isDirty()) {
                          if(!MessageAlert.
                                  yesNoMessage("You have unsaved changes. Do you want to change tab anyways? ", 
                                          mainTabbedPane)) {
                              change = false;
                          }
                      }
                      if(change) {
                          super.setSelectedIndex(index);
                      }
                  }
              }           
          }
    }
    

    【讨论】:

      【解决方案3】:

      首先,您使用的是 JTabbedPane,它表示用户可以按任何顺序选择选项卡,以实现向导,这通常需要按顺序执行步骤。考虑一下这是否是要使用的正确 UI 组件。

      其次,您正在寻找的是可否决的状态更改,尽管它不存在开箱即用。

      我在a thread in Sun's forums找到这个:

      我使用的技巧是替换 JTabbedPane 使用的 SingleSelectionModel。扩展 DefaultSingleSelectionModel 并覆盖 setSelectedIndex 方法似乎可以很好地完成工作(仅在允许切换时调用 super 方法)。

      此外,Kirill Grouchnikov 也有一些想法 - “Spicing up your JTabbedPane - part V”。

      【讨论】:

        【解决方案4】:

        它会出现太晚,因为当制表符已经改变时,当您需要的时候要知道它即将改变。

        您可以尝试的(如果您坚持使用可能不是最佳选择的选项卡式窗格)是添加鼠标侦听器并将其与玻璃窗格一起使用。这将捕获鼠标事件并允许您执行验证。如果成功,则以编程方式更改选项卡。

        您必须连接事件,这使得代码有点难以编写(我猜这就是您在向导中看不到选项卡的原因)

        至于索引,那是因为您使用的是同一个实例。它没有效果,因为您必须在实例上而不是在构造函数中调用它。

        这是一个关于如何使用GlassPanes的示例。

        查看示例中他们如何拦截按钮上的点击事件。您可以尝试使用游览选项卡进行类似的操作。

        【讨论】:

          【解决方案5】:

          一个低俗的替代方案(这是我将要做的,因为我已经完成了大部分并且现在反对剧烈的变化)是将enabled 属性设置为false。选项卡按钮将被禁用,但您的下一个和上一个按钮仍将按预期运行。如果您的用户能够容忍这种情况,这可能是一个简单的解决方案。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-04-04
            • 1970-01-01
            • 2011-09-18
            • 2013-05-13
            相关资源
            最近更新 更多