Поток Java и дилемма JTabbedPane
В проекте, над которым я работаю, у меня есть основной класс (названный TrackWin), который расширяет JFrame. В этом кадре я использую JTabbedPane.
Пользователь может создать новую вкладку на панели из строки меню. Всякий раз, когда это происходит, tabbedPane.addTab() вызывается в TrackWin.
У меня также есть класс TrackTab, который расширяет JPanel. Этот класс содержит всю актуальную информацию для новой вкладки. В этот класс включен поток, который вызывает "сторонний" класс (и группу классов) для выполнения определенного действия при каждом нажатии JButton.
Однако моя проблема возникает, когда я делаю несколько вкладок и пытаюсь запустить более одного экземпляра потока одновременно. Когда я запустил отладчик (я использую Eclipse), я заметил, что текущий набор потоков, созданный при каждом нажатии JButton, перезаписывается экземпляром потока другой вкладки.
Тем не менее, я должен думать, что моя проблема связана с моей собственной реализацией, а не с природой "стороннего" класса, примером которого я являюсь. Потому что, если я добавлю более одного экземпляра Thread в класс TrackTab (например, Thread1 и Thread2, которые оба создают / вызывают новые экземпляры класса Third Party), отладчик показывает набор потоков для каждого, и они работают нормально,
Буду признателен за любые предложения!
Вот пример кода:
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();
где 'thread' является публичной глобальной переменной 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, все идет хорошо). Так странно. Пожалуйста помоги!
2 ответа
Это может не иметь ничего общего с проблемой, с которой вы столкнулись, но с вашей линией:
thread = new Thread(new TrackThread(variable1, variable2, variable3));
выглядит "интересно" - сам TrackThread расширяет поток, вам не нужно оборачивать вокруг него другой поток, чтобы запустить его. Либо заставьте TrackThread реализовать Runnable (и больше не расширять Thread), либо просто напишите:
thread = new TrackThread(variable1, variable2, variable3);
Это должно работать так же хорошо и экономит создание ненужного объекта потока.
Кроме того, при отладке потоков очень полезно назвать их, чтобы их было легче различить. Используйте setName() или один из конструкторов, которые принимают аргумент имени.
В дополнение к наблюдению и рекомендации Саймона, я бы посоветовал вам свести к минимуму ваши неизвестные.
В этом случае это будет означать издевательство над вашим третьим классом. Замените его на то, что вы знаете, чтобы не иметь проблемных статик. Ничего особенного, просто простой поток, который запускает и производит вывод где-то.