1

以下のコード スニペットは、JFrame にアタッチされた JPanel に追加される JLabel にテキストを設定します。何をしても (repaint()、revalidate() など)、アクション リスナーが完了するまで UI でテキストを更新できません。

Action Listener の 1 回の起動で複数のことが発生する必要がなかったため、これまでこの問題が発生したことはありません。私は何が欠けていますか?

TL;DR 各 listPanel.add() の後に repaint() を挿入したとしても、アクション リスナーの起動が完了するまで、次のコードが画面上のテキストを更新しないのはなぜですか?

final JFrame guiFrame = new JFrame();
final JPanel listPanel = new JPanel();
listPanel.setVisible(true);
final JLabel listLbl = new JLabel("Welcome");
listPanel.add(listLbl);

startStopButton.addActionListener(new ActionListener(){@Override public void         actionPerformed(ActionEvent event){
     if(startStopButton.getText()=="Start"){
                startStopButton.setVisible(false);
                listPanel.remove(0);

     JLabel listLbl2 = new JLabel("Could not contact”);
                listPanel.add(listLbl2);

     JLabel listLbl2 = new JLabel("Success”);
                listPanel.add(listLbl2);
     }
}
guiFrame.setResizable(false);
guiFrame.add(listPanel, BorderLayout.LINE_START);
guiFrame.add(startStopButton, BorderLayout.PAGE_END);

//make sure the JFrame is visible
guiFrame.setVisible(true);

編集: SwingWorker を実装しようとしましたが、アクション インターフェイスの起動が完了するまで、インターフェイスは更新されません。ここに私のSwingWorkerコードがあります:

@Override
protected Integer doInBackground() throws Exception{
    //Downloads and unzips the first video.  
    if(cameraBoolean==true)
        panel.add(this.downloadRecording(camera, recording));
    else
        panel.add(new JLabel("Could not contact camera "+camera.getName()));

    panel.repaint();
    jframe.repaint();
    return 1;
}

private JLabel downloadRecording(Camera camera, Recording recording){
    //does a bunch of calculations and returns a jLabel, and works correctly
}

protected void done(){
    try{
        Date currentTime = new Timestamp(Calendar.getInstance().getTime().getTime());
        JOptionPane.showMessageDialog(jframe, "Camera "+camera.getName()+" finished downloading at "+currentTime.getTime());
    }catch (Exception e){
        e.printStackTrace();
    }
}

基本的に、SwingWorker (私が実装したもの) は JPanel と JFrame を適切に更新していません。「done()」で再描画しようとしても、更新されません。私は何が欠けていますか?

さらに、JOptionPane 自体が表示されるとすぐに、jframe にパネルを追加できなくなります。何が原因なのかもわかりません。

4

1 に答える 1

3

アクション リスナーはEvent Dispatch Threadで実行されています。そのようなタスクについては、SwingWorkerの使用を検討してください。

これにより、JFrame の更新 (したがって再描画) をブロックすることなく、ロジックを処理できます。

大まかに言えば、これは私が意味することです:

startStopButton.addActionListener(new ActionListener(){@Override public void         actionPerformed(ActionEvent event){
     if(startStopButton.getText()=="Start"){
          // Start SwingWorker to perform whatever is supposed to happen here.
     }

必要に応じて、SwingWorker ここで使用方法に関する情報を見つけることができます。

于 2013-08-30T18:24:07.673 に答える