2

次のコードが機能しないのはなぜですか?基本的に、これはより難しいプログラムの簡略化されたバージョンであり、さまざまな実行可能ファイルにリンクするボタンを持つ選択を使用して実行可能初期画面を作成しようとしていますが、これは期待どおりに実行されません。

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class Runnables {
    static Runnable runone;
    static Runnable runtwo;
    static JFrame frame = new JFrame();
    static JButton button1 = new JButton("Initial screen");
    static JButton button2 = new JButton("After button click screen");

    public static void main(String[] args) {
        runone = new Runnable() {
            @Override
            public void run() {
                frame.removeAll();
                frame.revalidate();
                frame.repaint();
                frame.add(button2);
            }

        };
        runtwo = new Runnable() {
            @Override
            public void run() {
                frame.setSize(800, 600);
                frame.setVisible(true);
                button1.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        runone.run();
                        System.out
                                .println("This is performed, but the button doesnt change");
                    }
                });
                frame.add(button1);
            }
        };
        runtwo.run();
    }
}
4

2 に答える 2

4

Runnableこれが機能するのを妨げる特別なことは何もありません。コードサンプルが立っているので、以下は同等です:

public void actionPerformed(ActionEvent arg0) {
    runone.run();
    System.out.println("This is performed, but the button doesnt change");
}

public void actionPerformed(ActionEvent arg0) {
    frame.removeAll();
    frame.revalidate();
    frame.repaint();
    frame.add(button2);
    System.out.println("This is performed, but the button doesnt change");
}

コードを取得し、そのSystem.out.println中にデバッグステートメントを追加するrunone.runと、実際に実行されていることがわかります。

あなたのコードサンプルはあなたの問題の単純化されたデモであることを意図していると思います。最初に「プレーン関数」として必要なことを実行することを検討し(上記の2番目の例では、Runnableが結合されます)、その後、個別のRunnableに分割することをお勧めします。

編集-例を機能させるために、覚えておくべきことJFrameは、contentPaneを使用してその子をホストすることです-contentPaneframe.addに追加するための便利な機能として存在します( JFrameのjavadocに基づく)が、これremoveAllは行いません(私がプレイしていることに基づく)ちょうど今それで)。また、ボタンが追加された後に呼び出すとvalidate、サブコンポーネントが再度適切にリレーアウトされ、2番目のボタンが表示されます。

の定義runoneをこれに置き換えると、サンプルが機能します。

runone = new Runnable() {
    @Override
    public void run() {
        frame.getContentPane().removeAll();
        frame.add(button2);
        frame.validate();
    }
};
于 2012-12-26T20:40:32.240 に答える
3

Runnable最初にオブジェクトをオブジェクト内に カプセル化し、Thread次にを呼び出してスレッドを開始する必要がありますstart()。例えば:

Runnable r = ...;
Thread thread = new Thread(r);
thread.start();


編集:

必ずEDTからRunnableを呼び出す必要があります。例えば:

SwingUtilties.invokeLater(r);

またはSwingWorker、スイングコードに関連する集中的な操作を処理するために使用することもできます。SwingWorkerがどのように機能するかを理解するには、この回答を参照してください。

于 2012-12-26T20:05:08.997 に答える