Поток 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() или один из конструкторов, которые принимают аргумент имени.

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

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

Другие вопросы по тегам