プロが教える店舗&オフィスのセキュリティ対策術

JButtonの画像をactionPerformedメソッド内で再描画したい。

以下のソースのようにして、再描画したいのです。
setIconメソッドではなく、
JButtonに対して描画したものに対して再描画したいです。
Graphics2DクラスについてJAVA APIで調べましたが、
仕組の理解に至りませんでした。
仕組みと方法を教えて頂きたいです。
よろしくお願いいたします。

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class test extends JFrame implements ActionListener{
JButton b= new JButton();
public static void main(String a[]) {
new test();
}
public test() {
super();
this.setSize(100,100);
b.addActionListener(this);
b.add(new Zoom(new ImageIcon("img1.jpg"),0,0,50,50));
this.add(b);
this.setVisible(true);
}
class Zoom extends JComponent {
private static final long serialVersionUID = 1L;
private ImageIcon icon = null;
private int x = 0;
private int y = 0;
private int h = 0;
private int w = 0;
private double scale = 1.0d;

public Zoom(ImageIcon icon, int x, int y, int w, int h) {
super();
this.icon = icon;
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}

public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.scale(scale, scale);
//////////////////////////////////
//画僧を再描画したい。
//g2.clearRect(0, 0, 80, 80);//×

g2.drawImage(icon.getImage(), x, y, w, h, this);
}
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()==b){
System.out.print("ok");
//this.repaint();//×
//b.repaint();//×
b.add(new Zoom(new ImageIcon("img2.jpg"),0,0,50,50));//(再描画できない)
//b.setIcon(new ImageIcon("img2.jpg"));//ok(再描画出来る)
}
}
}

A 回答 (2件)

 #1です。



 今回の問題は、再描画されていないのではなく、JButtonのデフォルトのレイアウトが OverlayLayout であるため、一つ目の Zoom コンポーネントと、二つ目の Zoom コンポーネントが重なってしまい、二つ目が見えていないだけです。

 ちゃんと、一つ目を remove したあとに、add してやれば、OKです。
 表示後のコンポーネントの追加と削除の後は、validate もお忘れなく。

 ただし、ボタンが押されるたびに、新しいZoomのインスタンスが作られ、そこで、ImageIcon が読み込まれるなど、無駄があったりするので、改善した方がよいと思います。

public class test extends JFrame implements ActionListener {

  JButton b = new JButton("test");

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

  public test() {
    super();
    this.setSize(100, 100);
    b.addActionListener(this);
    b.add(new Zoom(new ImageIcon("img1.jpg"), 0, 0, 50, 50));
    this.add(b);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setVisible(true);
  }

  class Zoom extends JComponent {

    private static final long serialVersionUID = 1L;
    private ImageIcon icon = null;
    private int x = 0;
    private int y = 0;
    private int h = 0;
    private int w = 0;
    private double scale = 1.0d;

    public Zoom(ImageIcon icon, int x, int y, int w, int h) {
      super();
      this.icon = icon;
      this.x = x;
      this.y = y;
      this.w = w;
      this.h = h;
      
      Dimension d = new Dimension(w, h);
      this.setMinimumSize(d);
      this.setPreferredSize(d);
      
    }

    public void paintComponent(Graphics g) {
      Graphics2D g2 = (Graphics2D) g;
      g2.scale(scale, scale);
//////////////////////////////////
//画僧を再描画したい。
//g2.clearRect(0, 0, 80, 80);//×

      g2.drawImage(icon.getImage(), x, y, w, h, this);
    }
  }

  public void actionPerformed(ActionEvent e) {
    if (e.getSource() == b) {
      System.out.println("ok");
//this.repaint();//×
//b.repaint();//×
      b.removeAll();
      b.add(new Zoom(new ImageIcon("img2.jpg"), 0, 0, 50, 50));
      b.validate();
//(再描画できない)
//b.setIcon(new ImageIcon("img2.jpg"));//ok(再描画出来る)
    }
  }
}
    • good
    • 0
この回答へのお礼

お返事遅くなりすみません。
とても参考になりました。
描画処理の中身を理解出来ました。
細かなソースの補足もしていただきありがとうございます。

お礼日時:2010/07/03 23:20

 こんにちは。



 最終的に、どのようになるのがお望みですか。

1.img1が消え、img2に差し変わる。
2.img1、img2ともに表示されるようになる。

 補足をお願いします。

この回答への補足

ご回答ありがとうございます。
目標は、
1.img1が消え、img2に差し変わる。
です。
描画したものを消して、書き直す作業が必要です。
setVisible(false);
してnewすると書き換えられますが。
そのようにすると、フレームのメモリが残ってしまいますので、
そうはしたくありません。
よろしくお願いいたします。

補足日時:2010/07/03 19:05
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!