Java Swingアプリケーションでスレッドを使って情報を設定/リフレッシュする良い方法

私はJavaのプログラマーではなく、私がやっていることが正しいかどうか、あるいはこれを行うためのよりよい方法が存在するかどうかはわかりません。

I'm making a swing Java app with multi-threading.
I have many swing component (textfield, texarea, label, list, ...) which are set and refresh with many threads.

For all my component I use something like the code below (it's just a tiny example) for set/refresh it.

Is Main.mainUI.setThumbLbl(image); for set/refresh my component a good way or not ? (I use something like this in other threads for all component)
And is there another better way to do this ?

メイン:

public class Main {

  public static MyMainUI mainUI;

  public static void main(String args[]) {
    mainUI = new mainUI();
    java.awt.EventQueue.invokeLater(new Runnable() {

      @Override
      public void run() {        
        mainUI.setVisible(true);
      }
    });
  }
}

Jframe:

public class MyMainUI extends JFrame {

  private JLabel thumbLbl;
  private JButton thumbBtn;

  public MyMainUI(){
   //add thumbLbl, thumBtn
    ...
    thumBtn.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseReleased(MouseEvent evt) {
        new MyThread().start();
      }
    });
  }

  public void setThumbLbl(final Image image) {
    SwingUtilities.invokeLater(new Thread() {

      @Override
      public void run() {
        thumbLbl.setIcon(new ImageIcon(image.getScaledInstance(thumbLblDim.width,
           thumbLblDim.height, Image.SCALE_DEFAULT)));
      }
    });
  }
}

スレッド:

public class MyThread extends Thread {
  @Override
  public void run() {
    //Get image from web server
    ...
    Main.mainUI.setThumbLbl(image);
  }
}

NB: I wrote this sample code in a text editor very quickly, maybe there are some mistakes but it's not what I'm asking for ^^.
NB2: Sorry for my bad English.

3
自分自身、私は通常このようなもののためにSwingWorkerを使用します。バックグラウンドスレッドで作業する以外にも、未来であり、値を返すことができ、PropertyChangeListenersを簡単に使用することができるなど、他の多くの機能があります。
追加された 著者 Hovercraft Full Of Eels,
また:1)あなたの英語は大丈夫です。 2)JButtonプレスに応答するためにMouseListenerを使用しないでください。代わりにActionListenerを使用してください。微妙ではあるが重要な違いがあります。重要な点の1つは、JButtonが無効になっているときにMouseListenerが応答し、ActionListenerが(正しく)応答しないことです。
追加された 著者 Hovercraft Full Of Eels,
コメントをいただき、ありがとうございました。私はSwingWorkerについて知らなかったので、良い選択肢と思われます。やってみます。
追加された 著者 Duffydake,
1)google traductionありがとうございました(2)私のボタンが無効になっていて、listernerが働いていたことがありますが、私のコードでこのようなエラーが多発していると思います。私が大きなミスを犯したくない理由、あなたのコメントに感謝します。私は私のアプリをリリースするとき、あなたのような人々は私に何が間違っていると言うことを願っています。
追加された 著者 Duffydake,
あなたが言ったことをすべて試し、私の例を作り直してこのスレッドを解決させます
追加された 著者 Duffydake,

1 答え

私が言ったことの一例は、次のようなものです:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ExecutionException;

import javax.imageio.ImageIO;
import javax.swing.*;

public class Main {
   private static void createAndShowGui() {
      JFrame frame = new JFrame("Main");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new MyMainUI());
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
 }

@SuppressWarnings("serial")
class MyMainUI extends JPanel {
   public static final String IMG_URL_PATH = "http://duke.kenai.com/Oracle/OracleStrat.png";
   private static final int PREF_W = 900;
   private static final int PREF_H = 650; 
   private JLabel thumbLbl = new JLabel();
   private JButton thumbBtn = new JButton("Get Image");

   public MyMainUI() {      
      thumbBtn.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent arg0) {
            thumbBtn.setEnabled(false);
            final ImageDownloader imgDownLoader = new ImageDownloader(IMG_URL_PATH);
            imgDownLoader.execute();

            imgDownLoader.addPropertyChangeListener(new ImgDownLoaderListener(imgDownLoader));
         }
      });

      JPanel btnPanel = new JPanel();
      btnPanel.add(thumbBtn);

      setLayout(new BorderLayout());
      add(new JScrollPane(thumbLbl), BorderLayout.CENTER);
      add(btnPanel, BorderLayout.PAGE_END);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private class ImgDownLoaderListener implements PropertyChangeListener {
      ImageDownloader imgDownLoader;

      public ImgDownLoaderListener(ImageDownloader imgDownLoader) {
         this.imgDownLoader = imgDownLoader;
      }

      @Override
      public void propertyChange(PropertyChangeEvent evt) {
        //swing worker is done
         if (evt.getNewValue().equals(SwingWorker.StateValue.DONE)) {
            thumbBtn.setEnabled(true);
            try {
               ImageIcon icon = imgDownLoader.get();
               if (icon != null) {
                  thumbLbl.setIcon(icon);
               }
            } catch (InterruptedException e) {
               e.printStackTrace();
            } catch (ExecutionException e) {
               e.printStackTrace();
            }
         }
      }
   }
}



class ImageDownloader extends SwingWorker {
   private String imageUrlPath;

   public ImageDownloader(String imageUrlPath) {
      this.imageUrlPath = imageUrlPath;
   }

   @Override
   protected ImageIcon doInBackground() throws Exception {
      try {
         URL imgUrl = new URL(imageUrlPath);
         BufferedImage img = ImageIO.read(imgUrl);
         return new ImageIcon(img);//return the ImageIcon
      } catch (MalformedURLException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
      return null;//or return null if an error occurs
   }

}

この例のバックグラウンドワーカースレッドは、GUIの構造についての知識がありません。それは画像をダウンロードすることです。それだけです。それから、PropertyChangeListenerで完了を待ち受けるGUIは、作業者の get()を呼び出してイメージを取得し、その作業を決定しますそれ。

4
追加された
私が思っていても、例をありがとう、私は自分でそれをすることができる
追加された 著者 Duffydake,