1

私が取り組んでいるプロジェクトでは、JFrame を拡張するメイン クラス (TrackWin という名前) があります。このフレームでは、JTabbedPane を使用します。

ユーザーは、メニュー バーからペインに新しいタブを作成できます。これが発生するたびに、tabbedPane.addTab() が TrackWin で呼び出されます。

また、JPanel を拡張する TrackTab というクラスもあります。このクラスには、新しいタブの実際の情報がすべて含まれています。このクラスには、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(); 

ここで、'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 インスタンスから同時に実行すると、すべてうまくいくことです)。とても奇妙。助けてください!

4

2 に答える 2

2

これはあなたが経験している問題とは何の関係もないかもしれませんが、あなたのラインは:

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

'おもしろい'に見えます-TrackThread自体がThreadを拡張します。実行するために、別のスレッドをラップする必要はありません。TrackThreadにRunnableを実装させる(そしてThreadを拡張しない)か、または単に次のように記述します。

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

これも同様に機能し、不要なスレッドオブジェクトの作成を節約できます。

さらに、スレッドをデバッグするときは、区別しやすいように名前を付けると非常に便利です。setName()またはname引数を取るコンストラクターの1つを使用します。

于 2009-08-10T15:04:10.220 に答える
0

サイモンの観察と推奨事項に加えて、未知数を最小限に抑えることをお勧めします。

この場合、それはサードパーティのクラスをモックアウトすることを意味します。問題のない統計を持っていないことがわかっているものに置き換えます。派手なことは何もありません。どこかで実行して出力を生成する単純なスレッドです。

于 2009-08-10T15:29:20.047 に答える