【问题标题】:Swing controls work under Java 6, not under Java 7Swing 控件在 Java 6 下工作,而不是在 Java 7 下工作
【发布时间】:2013-03-29 05:26:19
【问题描述】:

我正在对现有应用程序进行维护。我正在开发的功能在 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;dr

在 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 下有效。

【问题讨论】:

  • 从这段代码和描述中不可能回答一些聪明的事情
  • 使用 here 引用的方法之一验证 EDT 的正确使用。
  • 您使用的是最新的 Java 7 吗?
  • 如需尽快获得更好的帮助,请发帖SSCCE
  • 同时寻找空的异常处理程序。 EDT 将重新启动,但可能已经造成太多损坏。

标签: java swing user-interface


【解决方案1】:

感谢所有建议。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-28
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    • 2014-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多