2009-08-10 34 views
1

在我正在開發的項目中,我有一個擴展JFrame的主類(名爲TrackWin)。在這個框架中,我使用了JTabbedPane。Java線程和JTabbedPane難題

用戶可以通過菜單欄在窗格中創建一個新選項卡。每當發生這種情況,在TrackWin中調用tabbedPane.addTab()。

我也有一個名爲TrackTab的類,它擴展了JPanel。該類包含新選項卡的所有實際信息。包含在這個類中的是一個線程,它調用一個「第三方」類(以及一組類)來在單擊JButton時執行特定的操作。

但是,我的問題發生在每當我製作多個標籤並嘗試一次啓動多個線程實例時。當我運行調試器(我使用Eclipse)時,我注意到當單擊JButton時創建的當前線程集合被另一個選項卡的線程實例覆蓋。

但是,我必須認爲我的問題是由於我自己的實現,而不是我正在創建實例的「第三方」類的性質。因爲如果我向TrackTab類添加多個Thread實例(例如,Thread1和Thread2,它們都會調用/調用第三方類的新實例),那麼調試器會爲每個類顯示一組線程,並且它們運行正常。

我會很感激任何建議!

下面是一些示例代碼:

public class TrackWin extends JFrame { 
    public JTabbedPane tabbedPane; 

    public TrackWin() 
    { 
     tabbedPane = new JTabbedPane(); 
     TrackTab panel = new TrackTab(); 

     tabbedPane.addTab("Tab Name", null, panel, 
       "Tab Instance"); 

     tabbedPane.updateUI(); 
     add(tabbedPane); 

     ///////////////////////////////////////////////////////////// 
     // Initialize Menu Bar 
     ///////////////////////////////////////////////////////////// 

     JMenuBar menuBar = new JMenuBar(); 
     JMenu menu; 
     JMenuItem menuItem; 

     menu = new JMenu("File"); 
     menu.setMnemonic(KeyEvent.VK_F); 

     // New Tab Instance 
     menuItem = new JMenuItem("New Instance"); 

     menuItem.addActionListener(new java.awt.event.ActionListener() { 
      public void actionPerformed(java.awt.event.ActionEvent evt) { 

       TrackTab panel = new TrackTab(); 

       tabbedPane.addTab("Tab Name", null, panel, "Tab Instance"); 

       tabbedPane.updateUI(); 
       tabbedPane.repaint(); 
       tabbedPane.setVisible(true); 
     } 
     }); 
     menu.add(menuItem); 
     setJMenuBar(menuBar); 
     setVisible(true); 
    } 
} 

TrackTab.java的線程中調用:

thread = new Thread(new TrackThread(variable1, variable2, variable3)); 
thread.start(); 

其中, '線' 是TrackTab的公共全局變量。

然後,該TrackThread類很簡單:

public class TrackThread extends Thread { 
    public int variable1; 
    public int variable2; 
    public int variable3; 

    public TrackThread(int variable1, int variable2, int variable3) { 
     this.variable1 = variable1; 
     this.variable2 = variable2; 
     this.variable3 = variable3; 
    } 

    public void run() { 
     3rdPartyClass myPub = new 3rdPartyClass(); 
     myPub.do(variable1, variable2, variable3); 
    } 
} 

我沒有一大堆的信息對第三方類包(因爲我還沒有深入研究它太深),但我知道有一些靜態變量可能會導致問題。我承認可能需要完成一些重構。但是,我想知道是否我的代碼首先給我提供了問題。

奇怪的是,在TrackTab中,如果我添加TrackThread的另一個實例並且從TrackTab的單個實例併發地運行它們,一切順利)。太奇怪了。請幫忙!

+0

你是什麼意思的「全球」是「線程」的一個實例或靜態變量? – KarlP 2009-08-11 09:59:05

+0

@Monster而不是使用eclipse調試來觀察線程行爲,嘗試使用jconsole,它顯示真正的線程進程,無需任何外部干預。也許命名行事會有所幫助。 – ugo 2017-07-12 16:17:00

回答

2

這可能什麼都沒有做與你所遇到的問題,但你行:

thread = new Thread(new TrackThread(variable1, variable2, variable3)); 

長相「有趣」 - TrackThread本身繼承Thread,你不需要環繞它的另一個線程運行它。要麼讓TrackThread實現Runnable(而不再擴展Thread),或只寫:

thread = new TrackThread(variable1, variable2, variable3); 

這應該工作一樣好,節省了不必要的線程對象的創建。

此外,在調試線程時,命名它們以便更易於區分非常有用。使用setName()或採用名稱參數的構造函數之一。

+0

也許它不會全部運行,因爲TrackThread使用默認的構造函數,在啓動時它將不會運行任何東西。 您的陳述確實是正確的,但TrackThread只應實現Runnable,而不擴展Thread,這就是現在它的工作方式。 – ugo 2017-07-12 16:12:18

0

除了Simon的觀察和建議,我建議你最大限度地減少你的未知數。

在這種情況下,這意味着嘲笑你的第三方類。將它替換爲你知道沒有任何問題靜態的東西。沒有什麼奇特的,只是一個簡單的線程運行併產生輸出。

+0

啊,真的。我會試一試。 – Monster 2009-08-10 15:58:52