ぼんさい塾

ぼんさいノートと補遺に関する素材や注釈です.ミスが多いので初稿から1週間を経た重要な修正のみ最終更新日を残しています.

例で考えるJavaプログラミング (14)

2013-01-10 12:16:25 | 暮らし
progJ.pdf
progJ-s.pdf
progJ-e.pdf

記事一覧

                     アニメーション(楕円の移動)

progJ.pdf の[#64]に対応する部分を追加しました.progJ.pdf の行数不足のため App6?.java を
少し変更した New6?.java を用いています.
※ *.class は http://hakurei-isl.org/m-miyata/jar/App64-dist.zip,
下記のリストを少し変えて New61 → New62 → New63 → App64 と継承しました.
描画しないときは外枠を拡大して paint(g) を実行させてください(^^;).

[0] トラブル・シューティングのヒント < Javaデスクトップ・アプリケーションのパッケージ化と配布
  http://netbeans.org/kb/docs/java/javase-deploy_ja.html#troubleshooting
  ほとんどのシステムでは、実行可能なJARファイルを単純にダブルクリックすることによって、そのJARファイルを
  実行できます。JARファイルをダブルクリックしても何も起こらない場合は、次の2つの理由のどちらかが原因である
  可能性があります。(App64-dist.zip を保存せずに,圧縮ファイルを開いて tmp4jar.jar をクリックすればよい)
[1] NetBeansを使ったSwingアプリケーション開発 - やさしいデスマーチ
  http://d.hatena.ne.jp/shuji_w6e/20090504/1241412260
・Swingのコンポーネントに関する処理は全てEDT上で行わなければなりません。これはコンポーネントの
  インスタンス生成も同様ですが、mainメソッドが実行されるのはEDTではない為、mainメソッドでAppFrameを
  newするとSwingのシングルスレッド設計に反するコードとなるのです。
・Netbeansの自動生成コードではjava.awt.EventQueue#invokeLater(Runnable runnable)が使用されていますが、
  javax.swing.SwingUtilities#invokeLater(Runnable runnable)の方が有名だと思います*1。
[2] AWTとSwingのペイント(paint)の仕組み
  http://homepage1.nifty.com/algafield/paint.html#swing_summary
・paint()の中や、paint()から呼び出されるメソッド以外の場所(paint()のスコープ内にない場所)に書くのは
  禁物です。〔訳注:コンポーネントのgetGraphics()メソッドから取得したGraphicsオブジェクトを・・・
・Swingのプログラムでは、paint()ではなく、必ずpaintComponent()をオーバライドしてください。
・AWTではオーバライドしたpaint()の中で必ずsuper.paint()を呼ぶ必要があり、それを忘れると子の軽量
  コンポーネントが描画されませんでしたが、Swingではそういう問題がありません。
[3] invalidate()とvalidate()とrevalidate()の違い - kaisehのブログ
  http://d.hatena.ne.jp/kaiseh/20080411/1207927370
  Swingではinvalidate()とvalidate()を直接呼ぶ局面はほとんどないと思います。
  revalidate():まず、自身のinvalidate()を実行する。 次に、親コンポーネントを順に辿り、isValidateRoot()
  がtrueを返すコンポーネントを探す。ちなみに、trueを返すのはJRootPaneとJScrollPaneとJTextFieldのみ。
  見つかったコンポーネントのvalidate()の呼び出しをリクエストキューに入れる。 
※ 背景色を「p1」で設定し,Fig60 では透明にしました.revalidate() は New63() で使っています.(表示が改善された
ので一応挿入しましたが,サブクラスの“コンストラクタで”部品を追加したときも必要なのかよく分かりません)

//Main.java
//*.java の貼り合わせ(主プロジェクトにして jar 作成)
//デバッグ時はファイルごとに「ファイルを実行」
package Main;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
//-------------------------------------------------
class New50 extends JFrame implements Runnable {
    JTextField tf1; JButton b1;
    New50( ){
        super("myApp");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(250,105); setLayout(new FlowLayout( ));
        setVisible(true);
        tf1 = new JTextField("JTextField", 20);
        b1 = new JButton("JButton");
        Container f0 = getContentPane( );
        System.out.println(f0);
        f0.add(tf1); f0.add(b1);
    }
    public void run( ){}
}
//-------------------------------------------------
class Fig60 extends JPanel{
    int x;
    Fig60( ){
        super( );
        setPreferredSize(new Dimension(300, 200));
        setOpaque(false);
    }
    Fig60(int x0){this( ); x = x0;}
    //public void paint(Graphics g) {
    public void paintComponent(Graphics g){
        //super.paintComponent(g);
        g.drawLine(0,0,200,200);
        g.drawString("Hello", 50, 150);
        g.drawOval(x, 50, 100, 50);
    }
}
class New61 extends New50 {
    JPanel p1; Fig60 f1;
    New61( ){
        super( );
        setSize(350, 300); p1 = new JPanel( );
        Container cp = getContentPane( );
        p1.setBackground(Color.white);
        p1.add(f1 = new Fig60(150)); cp.add(p1);
    }
    public static void main(String[ ] args) {
        //New61 app = new New61( );
        //Thread th = new Thread(new New61( )); th.start( );//最初描画せず
        //EventQueue.invokeLater(new New61( ));//最初描画せず
        //*
        EventQueue.invokeLater(new Runnable( ) {
            public void run( ) {new New61( );}
        });
        //*/
    }
}
//-------------------------------------------------
class New62 extends New61 {
    /*
    New62( ){super( );
        p1.addMouseMotionListener(new MouseAdapter( ){
            public void mouseMoved(MouseEvent e){
                tf1.setText(e.getX( ) +", "+ e.getY( ));
            }
        });
    }
    */
    //class MMA62 extends MouseMotionAdapter {
    class MA62 extends MouseAdapter {
        //MA62( ){super( ); /* 追加なし */}
        public void mouseMoved(MouseEvent e){
            tf1.setText(e.getX( ) +", "+ e.getY( ));
        }
    }
    New62( ){super( );
        p1.addMouseMotionListener(new MA62( ));
        //p1.addMouseAdapter(new MA62( ));エラー
        //p1.addMouseListener(new MMA62( ));無効
    }
    public static void main(String[ ] args) {
        New62 app = new New62( );
    }
}
//-------------------------------------------------
class New63 extends New61 {
    class Fig63 extends Fig60 {
        public void paintComponent(Graphics g){
            int x = 90, y = 200, dx = 10, dy;
            while(y < 201){
                dy = (-2 * (150 - x) * dx)/25;
                g.drawLine(x, y, x + dx, y + dy);
                x += dx; y += dy;
            }//y = 56 - (150 - x)*(150 - x)/25
        }
    }
    New63( ){
        super( ); p1.setLayout(new CardLayout( ));
        p1.add(new Fig63( ), BorderLayout.CENTER);
        p1.revalidate( );//add(cmp, obj)の後処理
    }
    public static void main(String[ ] args) {
        New63 app = new New63( );
    }
}
//-------------------------------------------------
class App64 extends New61 {
    //App64( ){super( );}
    public void run( ){
        while(f1.x < 300){
            //p1.repaint( );//非推奨
            f1.repaint(f1.x-10, 40, 120, 70);
            f1.x += 5; f1.x %= 300;
            try{Thread.sleep(100);}
            catch(Exception e){System.out.println(e);}
        }
    }
    public static void main(String[ ] args) {
            Thread th = new Thread(new App64( ));
            th.start( );
    }
}
//-------------------------------------------------
//-------------------------------------------------
public class Main {
    public static void main(String[ ] args) {
            Thread th = new Thread(new App64( ));
            th.start( );
    }
}
//-------------------------------------------------