プログラミング演習3 第3回 ミニプロジェクト ミニプロジェクトについて • 1週目では丸や三角形などの形状を用いて 継承の復習、2週目ではボタンなどのレイア ウトや図形の描画などGUIの復習をしました • ミニプロジェクトでは、これら2つを組み合わ せておえかきツールを作ってみましょう 完成図の例 図形選択パネル メニュー 描画パネル 1) ボタンを選択 -> 選択された図形の描画準備 2) 描画パネルをクリック -> 選択された図形をクリックされた 座標に描画 ミニプロジェクトの流れ • Swingによる描画 – 描画パネルと図形選択パネルの設計 – ActionListenerの処理の記述 – Graphicsクラスによる描画 • 描画クラスの定義 – 図形クラスの設計 – 描画用インターフェースの設計 • 複合図形の描画 描画パネルと図形選択パネルの設計 JPanelを継承したクラスを作り、実行クラス内で呼び出す class MainFrame extends JFrame{ ChoosePanel cp; DrawPanel dp; class ChoosePanel extends JPanel{ } class DrawPanel extends JPanel{ } ActionListenerの処理の記述 イベントを発生させたいコンポーネントに リスナー(ボタンの場合はActionListener)を指定 イベントを発生した時に行う処理を書く ボタンによって処理を変えたい場合は getSourceやgetActionCommandで場合分け ボタンに貼る画像の作り方 まず図形クラスで、図形の大きさに合った BufferedImageを作成しdrawメソッドで描いた ものをImageとして返す サイズが(70,70)の空のイメージを作成 し、そこにTreeを構成する要素を描く 作成する画像の横幅を返すメソッド 作成する画像の高さを返すメソッド ※Treeクラスについてはスライド23,24を参考にすること ボタンに画像を貼る方法 getImageメソッドで生成した 画像は図形によって大きさが 異なるので、一定の大きさに 縮小してからボタンに貼り付 ける パネルへの配置例 private Drawable drawable; private JLabel l; private JButton b; 縦1,横2で配置 : setLayout(new GridLayout(1, 2)); drawable = new Tree(); l = new JLabel(drawable.toString(), SwingConstants.CENTER); add(l); img = drawable.getImage(); newimg = img.getScaledInstance(imagesize, imagesize, java.awt.Image.SCALE_SMOOTH); b = new JButton(new ImageIcon(newimg)); b.addActionListener(this); レイアウトマネージャーを無効にして絶対座標で指定す add(b); る方法もあります http://www.javadrive.jp/tutorial/nulllayout/index1.html 描画に必要なメソッド • 塗りつぶさずに描画 -> draw(int x, int y, Graphics g) • 塗りつぶして描画 -> drawfill(int x, int y, Graphics g) – 色の設定と取得 -> setColor(Color c), getColor() – 塗りつぶすか選択 -> setFilled(Boolean b), getFilled() ChoosePanel( ) { ・ ・ ・ drawable[0] = new Tree(); drawable[1] = new Tree(); drawable[2] = new BigCircle(); drawable[3] = new BigCircle(); drawable[1].setColor(Color.PINK); drawable[1].setFilled(true); drawable[3].setColor(Color.BLUE); drawable[3].setFilled(true); ・ ・ ・ • ボタンに画像を貼る -> getImage() : draw(…), drawfill(…) を場合分け • 画像サイズを決定する -> getWidth(), getHeight() Graphicsクラスによる描画 描画はpaintComponentメソッド で行う 描画には以下のようなメソッド が用意されている 文字列の描画 線の描画 四角形の描画 丸の描画 多角形の描画 :drawstring(表示する文字列,x座標,y座標) :drawLine(始点のx座標,y座標,終点のx座標,y座標) :drawRect(x座標,y座標,横幅,高さ) :drawOval(x座標,y座標,横幅,高さ) :drawPolygon(x座標の配列,y座標の配列,頂点数) 塗りつぶす場合は draw~をfill~に変える クリックしたところに描画する mouseClickメソッド内 でクリックした座標を 取得し、描画を行う ←2回めの Homeworkの解答例 図形とクリックした場所の保持 private ArrayList<ShapeObject> shapes=new ArrayList<ShapeObject>(); @Override public void paintComponent(Graphics g) { super.paintComponent(g); for (int i = 0; i < shapes.size(); i++) shapes.get(i).pd.draw(shapes.get(i).p.x,shapes.get(i).p.y, g); } 追加された形状を全て描画 @Override public void mouseClicked(MouseEvent e) { Point p = e.getPoint(); shapes.add(new ShapeObject(currentDrawable, p)); repaint(); } クリックされたら形状と座標を追加 : private class ShapeObject { 描画する形状と座標を保つクラス Drawable d; Point p; public ShapeObject(Drawable d, Point p){ this.pd = pd; this.p = p; } } repaintメソッドで再描画す ると、これまでに描画してい たものは消えてしまうので、 LinkedHashMapやAllayList を使ってこれまでに描画し た図形と描画した座標を保 持する ←実装例 継承を生かした描画 SmallCircleもBigCircleも大きさが異なるだけで描 画する方法は同じなのでCircleクラスに処理をま とめることができる Circleクラス SmallCircleクラスとBigCircleクラスには drawメソッドが書かれていないので継 承元のCircleクラスのdrawメソッドが 呼ばれる SmallCircleクラス BigCircleクラス メニューの作り方 メニューを作るには JMenuBar,Jmenu,JMenuItemを用いる JMenuBar L JMenu L JMenuItem の構造になっていて、JMenuItemをクリッ クした時にイベントを発生させたい場合は JButtonと同様にActionListenerに登録し、 actionPerformedメソッド内に処理を書く 表示する文字列やショート カットキーの設定 終了を押した時の処理 描画クラスの定義 • 基本的(primitive)な図形と複合的(compound) な図形を分けて考える 複合的 基本的 • 描画に必要なメソッドを考え、インターフェー スにまとめる 実現したいこと (機能) 必要なこと (メソッド) 基本的な図形クラスの設計 ? Interface Drawable Shape void draw(int x, int y, Graphics g) void setColor(Color c) Polygon Rectangle ? ・ ・ ・ ? Circle Square ? ? IsoscelesTriangle ? SmallRectangle BigRectangle SmallSquare BigSquare SmallCircle SmallIsoscelesTriangle BigIsoscelesTriangle BigCircle 全ての基本図形がDrawable のメソッドを使える 複合的な図形クラスの設計 draw( int x, int y, Graphics g) の宣言はどこ? Tree の中で宣言? Interface Drawable draw(int x, int y, Graphics g)? ・ ・ ・ CompoundDrawable の中で宣言? Drawable から継承? Interface CompoundDrawable getParts()の返り値は何? あらゆる図形を複数入れれる箱は..? Tree getParts() draw( int x, int y, Graphics g)? draw( int x, int y, Graphics g)? BigIsoscelesTriangle SmallSquare SmallIsoscelesTriangle BigIsoscelesTriangle 描画に必要なメソッド • 塗りつぶさずに描画 -> draw(int x, int y, Graphics g) • 塗りつぶして描画 -> drawfill(int x, int y, Graphics g) – 色の設定と取得 -> setColor(Color c), getColor() – 塗りつぶすか選択 -> setFilled(Boolean b), getFilled() ChoosePanel( ) { ・ ・ ・ drawable[0] = new Tree(); drawable[1] = new Tree(); drawable[2] = new BigCircle(); drawable[3] = new BigCircle(); drawable[1].setColor(Color.PINK); drawable[1].setFilled(true); drawable[3].setColor(Color.BLUE); drawable[3].setFilled(true); ・ ・ ・ • ボタンに画像を貼る -> getImage() : draw(…), drawfill(…) を場合分け • 画像サイズを決定する -> getWidth(), getHeight() BigCircle クラスの実装例 (Shape クラス) protected 修飾子はサブク ラスのみがアクセス範囲 BigCircle クラスの実装例 (Circle クラス) BigCircle クラスの実装例 (/3) Tree クラスの実装例 (1/2) Tree クラスの実装例 (2/2) Treeクラスをもっと簡潔に 複合的な図形では、使用するパーツの定義と描画する座標の設定以 外の処理はほとんど共通の処理を抽象クラスにまとめて書くと便利 継承 継承 他の複合的な形状のクラス 実装の過程 Step1 Step2 • Circleクラスを参考にして四角形や三角形などの基本図形を作る • 図形選択パネルにStep1で作成した図形の画像を貼り付けたボタンを表示する • 図形選択パネルのボタンを選んで、描画パネル上でクリックすると、クリックした場所に図形が描画さ Step3 れる • 複合的な図形を実装する上で共通のメソッドをまとめたCompoundFigureクラスを定義し、Treeクラス Step4 などの複合的な図形を表すクラスに継承させる Step5 • おえかきツールでStep4で作成した図形を描画できるようにする • TreeクラスのようなCompoundDrawbleを継承するクラスをメンバーに持つCompoundDrawbleを継承 Step6 したクラスを5個以上作る Step7 Step8 • メニューにヘルプの項目を作り、クリックすると作成者の名前が書かれたダイアログを表示させる • おえかきツールにオリジナルの機能を追加する(Undoとかキャプチャとか)
© Copyright 2024 ExpyDoc