0

我正在对现有应用程序进行维护。我正在开发的功能在 Java 6 下编译时可以使用,但在 Java 7 下无法使用。我会尽量简短。

该应用程序有一个巨大的 JTabbedPane,几乎构成了整个 UI。JTabbedPane 包含许多 JPanel。反过来,每个 JPanel 都包含大量的 JComponent。用户可以在控件中输入值,但是如果出于某种原因他们想要清除所有更改,他们可以选择一个选项来“重置”面板。负责方法的工作方式是删除 JPanel,重新创建一个完全相同的类(它们都继承自 JPanel)并将其重新插入到 JTabbedPane 中的相同索引处。很简单,对吧?

但实际发生的情况是它切换到 JTabbedPane 中的下一个 JPanel 选项卡,然后新面板中的许多控件显示与下一个面板中的控件重叠。因此,例如,如果我选择了 panel0 并想要重置它,它将显示 panel1 已被选中,并且一大堆 panel0 的组件与其重叠。

它变得更加奇怪。发生这种情况后,无法选择其他选项卡。就像用户界面冻结一样。用户必须通过单击其顶部的选项卡来选择当前选项卡(即 panel1)(这很奇怪,因为它已经被选中)。然后他们可以转到其他选项卡,一切都按应有的方式运行。但是,如果他们不知道解决方法,那就太可怕了。这是完全错误的。重置面板应该只显示所有控件为空白的相同面板。

这是用伪代码完成的操作:

  1. 获取当前面板
  2. 创建它的新实例
  3. 移除当前面板
  4. 插入新实例
  5. 重新验证和重新绘制
  6. 设置面板的选中索引

这是实际的代码:

public void resetCurrentTab( int currentTabIndex ) {

   // tried using m_tabbedPane.getTabComponentAt( currentTabIndex), but that returns null
   JPanel curTab = (JPanel)m_tabbedPane.getSelectedComponent();
   if( curTab == null )
          return;
   String curTabName = curTab.getName().trim();

   // create new instance of panel
   JPanel newPanel = null;
   try {
      newPanel = curTab.getClass().newInstance();
   } catch (InstantiationException e) {
      log.equals("Could not reset tab... tab " + curTabName + " creation failed.");
      return;
   } catch (IllegalAccessException e) {
      log.equals("Could not reset tab... tab " + curTabName + " creation failed.");
      return;
   }

   if( newPanel != null ) {
      m_tabbedPane.remove( currentTabIndex );
      m_tabbedPane.insertTab( newPanel.getName(), null, newPanel, null, currentTabIndex );
      newPanel.setVisible( true );
   }


   m_tabbedPane.revalidate();
   m_tabbedPane.repaint();
   m_tabbedPane.setSelectedIndex( currentTabIndex );
}

就像我说的,这是在 Java 6 下编译的。在 Java 7 下,会发生奇怪的事情。我尝试了所有显而易见的事情,比如更改调用 revalidate()、repaint() 和 setSelectedIndex() 的顺序,但这并没有改变行为。我还尝试取出并重新添加相同的 JPanel 只是为了看看会发生什么。我没有得到重叠控件的奇怪之处,但它确实会在选项卡式控件中选择下一个 JPanel(选项卡)。

tl;博士

在 Java 6 下编译运行良好的功能在 Java 7 下编译不工作。

有任何想法吗?

编辑:我将问题完全追溯到其他东西。在用户重置选项卡之前,一个方法会弹出一个 JOptionPane 询问他们是否确定要这样做。它只是使用简单的 YES/NO 版本的 .showConfirmDialog()。如果我删除对话框,该功能将完美运行。如果我使用对话框,我会得到古怪的行为。

int response = JOptionPane
   .showConfirmDialog(
      currentTab,
      confirmMsg,
      "Reload the '" + curTabName + "' Tab",
      JOptionPane.YES_NO_OPTION,
      JOptionPane.QUESTION_MESSAGE );

      if( response == JOptionPane.YES_OPTION )
         // return a value indicating to reset the panel

我为第一个参数尝试了几个不同的值,但没有一个改变行为。如您所见,对话框在重置发生之前很久就超出了范围。仍然不知道为什么这在 Java 6 而不是 7 下有效。

4

1 回答 1

0

感谢所有的建议。

我以不寻常的方式修复了这个问题,但这是一个不寻常的错误。我删除了之前完成的方法中的 Panel(在上面的代码中称为 curTab),然后设置了一个标志。TabbedPane(我必须创建自己的,继承自 JTabbedPane)在自定义 Paint() 方法中查找标志。我不做任何自定义绘画,但在该方法中,我分配新面板并将其插入到 TabbedPane 中删除旧面板的索引处。然后我清除所有标志并清理所有内容。

就像我说的,这是一个不寻常的修复,但这是我尝试过的唯一方法,我可以避免视觉和功能故障。

于 2013-03-28T21:26:19.963 回答