2013-02-19 51 views
0

我對現有的應用程序進行維護。我正在使用的功能在Java 6下編譯時工作,但不在Java 7下。我會盡量簡短。Swing控件工作的Java 6下,不是在Java 7中

應用程序有對構成幾乎整個UI巨大JTabbedPane的。 JTabbedPane包含許多JPanel。每個JPanel又包含一個下流的JComponents。用戶可以在控件中輸入值,但如果 - 出於某種原因 - 他們想要清除所有更改,則可以選擇一個選項來「重置」面板。負責方法的工作方式是刪除JPanel,重新創建一個完全相同的新類(它們都從JPanel繼承),並將其重新插入JTabbedPane的相同索引。很簡單,對吧?

但實際發生的事情是它切換到JTabbedPane中下一個的JPanel選項卡,然後一些來自新的面板顯示在下一屏重疊控件控制。因此,例如,如果我選擇了panel0並想重置它,它將顯示panel1爲選中狀態,並且一組panel1的組件與其重疊。

它會變得怪異。發生這種情況後,不能選擇其他選項卡。這就像用戶界面凍結。用戶必須通過點擊頂部的標籤來選擇當前標籤(即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。

+0

從這段代碼和描述是不可能的回答一些巧妙的 – mKorbel 2013-02-19 20:46:28

+2

驗證正確使用EDT使用引用[這裏](http://stackoverflow.com/q/7787998/230513)的方法之一。 – trashgod 2013-02-19 21:01:00

+0

您使用的是最新的Java 7嗎? – madth3 2013-02-20 01:22:14

回答

0

感謝您的所有建議。

我以一種不尋常的方式解決了這個問題,但這是一個不尋常的錯誤。我在該方法之前刪除了面板(在上面的代碼中稱爲curTab),然後設置一個標誌。 TabbedPane(我必須創建自己的,從JTabbedPane繼承)在自定義Paint()方法中查找標誌。我不做任何自定義繪畫,但在該方法中,我分配新面板並將其插入TabbedPane中的舊版本的索引處。然後我清除所有標誌並清理所有內容。

就像我說的,這是一個不尋常的修復,但這是我嘗試的唯一方法,我可以避免視覺和功能故障。