2009-08-10 3 views
1

В проекте, над которым я работаю, у меня есть основной класс (с именем TrackWin), который расширяет JFrame. В этом фрейме я использую JTabbedPane.Java-потоки и дилемма JTabbedPane

Пользователь может создать новую вкладку в панели из панели меню. Всякий раз, когда это происходит, tabbedPane.addTab() вызывается в TrackWin.

У меня также есть класс TrackTab, который расширяет JPanel. Этот класс содержит всю фактическую информацию для новой вкладки. Включенный в этот класс - это Thread, который вызывает класс «третьей стороны» (и группу классов) для выполнения определенного действия всякий раз, когда нажимается JButton.

Моя проблема возникает, однако, когда я делаю несколько вкладок и пытаюсь запустить более одного экземпляра потока за раз. Когда я запускаю отладчик (я использую Eclipse), я заметил, что текущий набор потоков, созданный при щелчке по JButton, перезаписывается экземпляром потока другой вкладки.

Однако, я должен думать, что моя проблема связана с моей собственной реализацией, а не с природой класса «третьей стороны», я делаю экземпляр. Поскольку, если я добавляю более одного экземпляра Thread в класс TrackTab (например, 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

Что вы подразумеваете под "global" Является ли "thread" экземпляром или статической переменной? – KarlP

+0

@Monster вместо использования отладки eclipse для наблюдения за поведением потока, попробуйте использовать jconsole, который показывает реальный процесс потока без какого-либо внешнего вмешательства. Может быть, именование протектора поможет. – ugo

ответ

2

Это может не иметь ничего общего с проблемой, которую вы испытываете, но ваша линия:

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

выглядит «интересным» - TrackThread сама проходит нить, вам не нужно обернуть другую нить вокруг него для запуска. Либо сделать TrackThread реализовать Runnable (и не простираться тему больше), или просто написать:

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

Это должно работать точно так же и спасает создание ненужного объекта потока.

Кроме того, при отладке потоков очень полезно назвать их, чтобы их было легче различить. Используйте setName() или один из конструкторов, которые принимают аргумент имени.

+0

Возможно, он не будет работать все, поскольку TrackThread использует конструктор по умолчанию, при запуске он ничего не будет запускать. Ваше утверждение действительно верно, но TrackThread должен реализовывать только Runnable, не увеличивая Thread, так оно и работает. – ugo

0

В дополнение к наблюдению и рекомендации Саймона, я предлагаю вам свести к минимуму ваши неизвестные.

В этом случае это означало бы издевательство над вашим сторонним классом. Замените его тем, что вы знаете, чтобы не иметь проблемной статики. Ничего необычного, просто простой поток, который запускает и производит выход где-то.

+0

Ах, правда. Я попробую. – Monster