私は、JavaでcliベースのカスタムWebクローラーを開発しています。結果を表示するためのユーザーフレンドリーなグラフィカルインターフェイスが必要なので、いくつかのツリー、ラベル、テーブルなどを含むスイングフレームを追加する必要があります。 そのグラフィカルインターフェイスはそのスイッチの1つで、ユーザーがそれを呼び出す場合に備えて起動する必要があります。したがって、必要に応じてアプリケーションを他のタスクに進め、GUIフレーム内のコンポーネントを更新できるように、このインターフェイスを新しいスレッドで開始する必要があります。 私のGUIクラスはいくつかのことのようである:別のスレッドでスウィングを使用する
public class Frame extends JFrame {
......
public static JLabel urlLabel;
......
public static void run() {
urlLabel = new JLabel();
urlLabel.setText("Test Url");
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Frame().setVisible(true);
}
});
}
.....
}
そして、私はこのように私のメインクラスからそれをfork:
.....
if(cmd.gui){
Frame.run();
Frame.urlLabel.setText("New Url");
}
......
残念ながら、ラベルのテキストは変更されません。私はすでにrepaint()
、revalidate()
などの他の関数をテストしましたが、何も表示されませんでした。 私はgetText()
をテストして、メインクラスからurlLabel
にアクセスすることが可能であることを確認しました。それは働いていました(ラベルのテキストを取得できました)。
私はこの問題をどのように解決できるのでしょうか? (基本的には、別のスレッドでスイングフレームを開始し、そのコンポーネントをメインスレッドから制御する必要があります)
ありがとうございます。
毎回、SwingUtilities.invokeLaterで既に行ったように、専用のスイングスレッドを使用してUI要素を変更するだけで済みます。あるいは、あなたの問題が間違っていると私は理解しています – xander
@xander私はすでにそれをしました。スイングは新しい専用スレッドで開始され、そのコンポーネントを更新/変更する必要があります。私はそれがカスタムWebクローラーであると説明したので、アプリケーションがWebサイトをクロールしている間に、収集した新しいデータをGUIに追加する必要があります。 –
@SinaYazdanmehrまた、スイングはスレッドセーフではなく、UIへのすべての更新はイベントディスパッチスレッドのコンテキスト内で行わなければならないことに注意してください。また、クロスオブジェクト通信メソッドとして '静的'に頼るべきではありません。それはコード内の単なる痛みです。代わりに、UIとコードの他の部分との間でモデルを共有する必要があります。 UIは、モデルが変更されたときにオブザーバーパターンを使用して更新を取得し、EDT内から 'invokeLater'を介して更新されるようにします。通常は、UI以外の部分を駆動するSwingWorkerを使用しますが、UIを通知することができるのは – MadProgrammer