どんな時にも今までに描いた絵を消すことなく一度見えなくなったウインドウが戻ることなどでも絵が消えないようにするには、絵はJPanelではなく別のところに描いておくことにして、paintComponentにはその絵をJPanelにコピーさせるようにします。
まず別の場所の用意ですが、
BufferedImage buffimg = new BufferedImage(int width,int height, int TYPE); Graphics bfg = buffimg.createGraphics();
こうしておくと、後で
bfg.fillOval(x,y,w,h);
などと描画ができます。
paintComponentには
myg.drawImage(buffimg, 0, 0, this);
と書いて、bufimg内のデータをJPanel内にコピーします。
import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.awt.image.*; public class EventRandom3 extends JFrame implements ActionListener{ JButton mybtn; MyPanel mypnl; int pcct=0; //paintComponentが呼び出された回数 int clct=0; //クリックした回数 BufferedImage buffimg; Graphics bfg; Color bc; public EventRandom3() { setDefaultCloseOperation(EXIT_ON_CLOSE); setSize(400,300); setTitle("BufferedImageで描く"); mypnl = new MyPanel(); //mypnl.setSize(400,300); // 表示した時にレイアウトマネージャで大きさを勘案するので // あっても無視される mypnl.setBackground(new Color(255,255,191)); bc = new Color(255,255,191); // BufferedImageの背景色にするため mybtn = new JButton("draw"); setLayout(new BorderLayout()); add(mypnl, BorderLayout.CENTER); add(mybtn,BorderLayout.SOUTH); mybtn.addActionListener(this); setVisible(true); buffimg = new BufferedImage( mypnl.getSize().width, mypnl.getSize().height, BufferedImage.TYPE_INT_RGB); bfg = buffimg.createGraphics(); bfg.setColor(bc); bfg.fillRect(0, 0, getSize().width, getSize().height); } public void actionPerformed(ActionEvent e) { if (e.getSource() == mybtn) { clct++; mypnl.drawRdm(); mypnl.repaint(); } } public static void main(String[] args){ EventRandom3 myframe = new EventRandom3(); } public class MyPanel extends JPanel{ int w=30; //楕円の幅 int h=20; //楕円の高さ Color c = new Color(0,0,0); //楕円の色 int dc = 51; //色の変化の大きさ int dx = 50; //横位置の変化の大きさ public void paintComponent(Graphics myg){ super.paintComponent(myg); pcct++; myg.drawImage(buffimg, 0, 0, this); myg.setColor(bc); myg.fillRect(10,4,60,20); myg.setColor(Color.black); myg.drawString(pcct+" "+clct,10,20); } public void drawRdm() { for(int i=0; 10>i; i++){ nextColor(); bfg.setColor(c); int x = (int)(400*Math.random()); int y = (int)(300*Math.random()); int h = (int)(50*Math.random()+5); bfg.fillOval(x-h/2,y-h/2,h,h); } } public void nextColor(){ int r=c.getRed(); int g=c.getGreen(); int b=c.getBlue(); g = (int)(g + dc*Math.random()); if (g > 255){ g = 0; } c = new Color(r,g,b); } } }
上記プログラムをつくって動作を確認しなさい。