隠されていたウインドウが表面に出た時、もともとあった画面を書き直すのはアプリケーションの仕事です。
JButton, JLabel, などの部品(javaではコンポーネントと呼ぶ)はそれが備わっています。JPanelも、それを持っているのですが、それなりの書き方をしなければなりません。
Colorクラスの使い方と、キャストも勉強します。
JButton, JLabel, JPanelが画面を書き直すのは、paintConponent()メソッドをもっているからです。隠されていたウインドウが表面に出た時にこの部分を実行します。
JPanelを継承したクラスをつくって、書き足してほしい円や四角をpaintConponent()メソッドに書き足せばそれも書き直してくれます。
ここではMyPanelというクラスを作って、JPanelの代わりにMyPanelをつくってJFrameに配置します。
import java.awt.*; import javax.swing.*; public class PaintComp extends JFrame{ MyPanel mypnl; public PaintComp() { setDefaultCloseOperation(EXIT_ON_CLOSE); setSize(400,300); setTitle("PaintComp"); mypnl = new MyPanel(); setLayout(new BorderLayout()); add(mypnl, BorderLayout.CENTER); setVisible(true); } public static void main(String[] args){ PaintComp myframe = new PaintComp(); } public class MyPanel extends JPanel{ public void paintComponent(Graphics myg){ super.paintComponent(myg); myg.setColor(new Color(0,0,255)); for(int i=0; i*2<300; i=i+10){ myg.drawOval(i*2,i,20,10); } } } }
MyPanelというクラスはPaintCompというクラスの中に記述されています。これをクラスの中のクラス(インナークラス)といいます。
いままでのtoi.javaやMondaishuu.javaのように別ファイルで用意してもかまいませんが、このような書き方も可能です。
MyPanelの中にはコンストラクタがありません。このような時は親であるJPanelのコンストラクタが使用されます。必要なところだけを書き加え、他は親の機能を使うのが「継承」の仕組みです。
MyPanelに書き加えたものは、paintConponent()メソッドだけです。子クラスに親クラスと同じ名前のメソッドを書くと親のメソッドが子のメソッドで上書きされます。
ここでは特別に super.paintComponent(myg) と書いて、親のpaintComponent()のメソッドを実行した後で独自の仕事を書き加えています。
独自の仕事は楕円をたくさん描くことです。
paintConponent()メソッドは一度隠されたウインドウが戻った時に自動的に実行されます。そのときにも楕円をたくさん描くことが行われます。
一度隠されたウインドウが戻った時にその都度書き直しているといっても、実感がもてないかも知れません。そこであえてMath.random()を用いて描くたびに違う図形を描いてみることにします。
import java.awt.*;
import javax.swing.*;
public class PaintComp2 extends JFrame{
MyPanel mypnl;
public PaintComp2() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(400,300);
setTitle("PaintComp");
mypnl = new MyPanel();
setLayout(new BorderLayout());
add(mypnl, BorderLayout.CENTER);
setVisible(true);
}
public static void main(String[] args){
PaintComp2 myframe = new PaintComp2();
}
public class MyPanel extends JPanel{
public void paintComponent(Graphics myg){
super.paintComponent(myg);
myg.setColor(new Color(0,0,255));
for(int i=0; i*2<300; i=i+10){
myg.drawOval(i*2,i,20,10);
}
myg.setColor(new Color(0,191,0));
int x = (int)(200*Math.random());
int y = (int)(200*Math.random());
int h = (int)(50*Math.random()+5);
myg.fillOval(x,y,h,h);
myg.setColor(new Color(255,0,0));
x = (int)(200*Math.random());
y = (int)(200*Math.random());
h = (int)(50*Math.random()+5);
myg.fillRect(x,y,h,h);
}
}
}
ランダムな場所にランダムな大きさで緑の円と赤い四角がでます。
Windowを一度最小化した後に戻したり、Windowの大きさを変えたりすると、緑の円と赤い四角が違うところに出ますから書き換えられていることが分かります。
しかし、一度隠されたウインドウが戻るだけだと書き換えられていません。これはjavaのversion1.6から変更になった様です。
Version1.5までは、隠されただけでも必ず書き換えていました。
ランダムな場所にランダムな大きさで緑の円と赤い四角がでます。
一部だけを隠して戻すと、隠れなかったところは元のままなので、このように2つの四角や円が出ることもありました。