@634

おえかき その16 フリーライン

Advertisement

ここでやること。

マウスドラッグで、自由な曲線をかけるようにしましょーね、っと。
この機能なかったらダメよね。なんで今ごろ気づいてやってるんだろ。わはは。

機能追加するぞー

んー、あんま難しくないっぽいなぁ。とりあえず適当にやってみた。ら、できた。

やること一覧
  • 図形メニュー増やす。
  • 一本のフリーライン管理するクラス作成。他と同じでFigureの派生クラス。
  • マウスクリックでオブジェクト生成。フリーラインのを管理する。
  • フリーラインのオブジェクト生成時の引数は、他の図形とは違って描画色だけだから、親クラスにデフォルトコンストラクタ追加(最初から記述しとけばよかった。)→追加しないとコンパイルエラー。説明(?)
  • マウスドラッグで点を追加する。
まぁ、こんなとこかな。最初はクラス作りからしよっと。

FreeLineData。一本(マウスのボタンが押されてから離されるまで)の線を管理するクラス。
class FreeLineData extends Figure{
    Vector v = new Vector();
    public FreeLineData(Color c){
        col = c;
    }

    public void addPoint(int x1, int y1, int x2, int y2){
        v.addElement(new LineData(x1, y1, x2, y2, col));
    }

    public void Draw(Graphics g){
       for(int i = 0; i < v.size(); i++){
            ((LineData)v.elementAt(i)).Draw(g);
        }
    }
}
マウスがドラッグされるごとに、その時の点の情報をFreeLineDataの中のVectorに追加。効率悪そうだ。他にもっといいのないかなぁ。考えとこう。

で、FreeLineDataクラスを追加して、使えるようにしたプログラム。
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;

public class Gr{
    public static void main(String args[]){
        mainFrame f = new mainFrame();
        f.setSize(400, 300);
        f.setTitle("タイトル");
        f.show();
    }
}

class mainFrame extends Frame implements WindowListener,
          MouseListener, ActionListener, ItemListener, MouseMotionListener{
    int x, y;
    int ex, ey;
    int dragFlag;
    int figureFlag;
    Color col;

    Vector v1 = new Vector();
    MenuBar mb = new MenuBar();
    Menu file, edit, help;
    Menu figure, color;
    MenuItem open, save, quit;
    MenuItem undo, clear;

    //図形メニューの数が一個増える。
    CheckboxMenuItem[] figItem = new CheckboxMenuItem[6];
    CheckboxMenuItem[] colItem = new CheckboxMenuItem[13];

    OpenDialog od = new OpenDialog();
    SaveDialog sd = new SaveDialog();

    mainFrame(){
        int i;
        col = Color.black;
        figureFlag = 0;

        file = new Menu("ファイル");
        edit = new Menu("編集");
        help = new Menu("ヘルプ");
        figure = new Menu("図形選択");
        color = new Menu("描画色選択");

        open = new MenuItem("開く", new MenuShortcut(KeyEvent.VK_O, false));
        save = new MenuItem("保存", new MenuShortcut(KeyEvent.VK_S, false));
        quit = new MenuItem("終了", new MenuShortcut(KeyEvent.VK_X, false));
        undo = new MenuItem("元に戻す", new MenuShortcut(KeyEvent.VK_Z, false));
        clear = new MenuItem("画面消去");

        String[] str1 = {"直線","四角形","楕円",
                        "塗りつぶした四角形","塗りつぶした楕円",
                        "フリーライン"};
        for(i = 0; i < figItem.length; i++){
            figItem[i] = new CheckboxMenuItem(str1[i]);
            figure.add(figItem[i]);
            figItem[i].addItemListener(this);
        }

        figItem[0].setShortcut(new MenuShortcut(KeyEvent.VK_L, false));
        figItem[1].setShortcut(new MenuShortcut(KeyEvent.VK_R, false));
        figItem[2].setShortcut(new MenuShortcut(KeyEvent.VK_O, false));

        //一応ショートカットキー追加しとく。
        figItem[5].setShortcut(new MenuShortcut(KeyEvent.VK_F, false));


        String[] str2 = {"黒","青","シアン",
                        "ダークグレイ","グレイ",
                        "緑","ライトグレイ",
                        "マゼンダ","オレンジ",
                        "ピンク","赤","白","黄色"};

        for(i = 0; i < colItem.length; i++){
            colItem[i] = new CheckboxMenuItem(str2[i]);
            color.add(colItem[i]);
            colItem[i].addItemListener(this);
        }

        file.add(open);
        file.add(save);
        file.addSeparator();
        file.add(quit);
        edit.add(undo);
        edit.addSeparator();
        edit.add(figure);
        edit.add(color);
        edit.add(clear);
        mb.add(file);
        mb.add(edit);
        mb.add(help);
        mb.setHelpMenu(help);

        setMenuBar(mb);

        open.addActionListener(this);
        save.addActionListener(this);
        quit.addActionListener(this);
        clear.addActionListener(this);
        undo.addActionListener(this);
        addWindowListener(this);
        addMouseListener(this);
        addMouseMotionListener(this);

        figItem[0].setState(true);
        colItem[0].setState(true);
    }

    public void paint(Graphics g){
        for(int i = 0; i < v1.size(); i++){
                ((Figure)v1.elementAt(i)).Draw(g);
        }

        if(dragFlag == 1){
            g.setColor(col);
            if(figureFlag == 0){
                g.drawLine(x, y, ex, ey);
            }else if(figureFlag == 1){
                g.drawRect(x<ex?x:ex, y<ey?y:ey, Math.abs(x-ex), Math.abs(y-ey));
            }else if(figureFlag == 2){
                g.drawOval(x<ex?x:ex, y<ey?y:ey, Math.abs(x-ex), Math.abs(y-ey));
            }else if(figureFlag == 3){
                g.fillRect(x<ex?x:ex, y<ey?y:ey, Math.abs(x-ex), Math.abs(y-ey));
            }else if(figureFlag == 4){
                g.fillOval(x<ex?x:ex, y<ey?y:ey, Math.abs(x-ex), Math.abs(y-ey));
            }
        }
    }

    public void mousePressed(MouseEvent e){
        x = e.getX();
        y = e.getY();
        dragFlag = 1;

        //現在の描画機能がフリーラインならば、
        //クリックした時点でオブジェクト生成。
        if(figureFlag == 5){
            v1.addElement(new FreeLineData(col));
        }
    }

    public void mouseReleased(MouseEvent e){
        dragFlag = 0;

        if(figureFlag == 0){
            v1.addElement(new LineData(x, y, e.getX(), e.getY(), col));
        }else if(figureFlag == 1){
            v1.addElement(new RectData(x, y, e.getX(), e.getY(), col));
        }else if(figureFlag == 2){
            v1.addElement(new OvalData(x, y, e.getX(), e.getY(), col));
        }else if(figureFlag == 3){
            v1.addElement(new FillRectData(x, y, e.getX(), e.getY(), col));
        }else if(figureFlag == 4){
            v1.addElement(new FillOvalData(x, y, e.getX(), e.getY(), col));
        }
        repaint();
    }

    public void mouseDragged(MouseEvent e){
        ex = e.getX();
        ey = e.getY();

        if(figureFlag == 5){
            //フリーラインのポイント追加。
            ((FreeLineData)v1.elementAt(v1.size() - 1)).addPoint(x, y, ex, ey);
            x = ex; //現在の終点座標を新しい始点にする。
            y = ey;
        }
        repaint();
    }


    public void actionPerformed(ActionEvent ae){
        if(ae.getSource() == save){
            try{
                FileOutputStream fos = new FileOutputStream(sd.save());
                ObjectOutputStream oos = new ObjectOutputStream(fos);
                oos.writeObject(v1);
                oos.close();
                fos.close();
            }catch(IOException ioe){
                System.out.println(ioe);
            }
        }

        if(ae.getSource() == open){
            try{
                FileInputStream fis = new FileInputStream(od.open());
                ObjectInputStream ois = new ObjectInputStream(fis);
                v1.removeAllElements();
                v1 = (Vector)ois.readObject();
                ois.close();
                fis.close();
                repaint();
            }catch(Exception e){
                System.out.println(e);
            }
        }

        if(ae.getSource() == quit){
            System.exit(0);
        }

        if(ae.getSource() == undo && v1.size() > 0){
            v1.remove(v1.size()-1);
            repaint();
        }

        if(ae.getSource() == clear){
            v1.removeAllElements();
            repaint();
        }
    }

    public void itemStateChanged(ItemEvent ie){
        if(ie.getSource() == figItem[0]){
            figureFlag = 0;
            setFigState(0);
        }else if(ie.getSource() == figItem[1]){
            figureFlag = 1;
            setFigState(1);
        }else if(ie.getSource() == figItem[2]){
            figureFlag = 2;
            setFigState(2);
        }else if(ie.getSource() == figItem[3]){
            figureFlag = 3;
            setFigState(3);
        }else if(ie.getSource() == figItem[4]){
            figureFlag = 4;
            setFigState(4);
        }else if(ie.getSource() == figItem[5]){
            figureFlag = 5;
            setFigState(5);
        }


        if(ie.getSource() == colItem[0]){
            col = Color.black;
            setColState(0);
        }else if(ie.getSource() == colItem[1]){
            col = Color.blue;
            setColState(1);
        }else if(ie.getSource() == colItem[2]){
            col = Color.cyan;
            setColState(2);
        }else if(ie.getSource() == colItem[3]){
            col = Color.darkGray;
            setColState(3);
        }else if(ie.getSource() == colItem[4]){
            col=  Color.gray;
            setColState(4);
        }else if(ie.getSource() == colItem[5]){
            col = Color.green;
            setColState(5);
        }else if(ie.getSource() == colItem[6]){
            col = Color.lightGray;
            setColState(6);
        }else if(ie.getSource() == colItem[7]){
            col = Color.magenta;
            setColState(7);
        }else if(ie.getSource() == colItem[8]){
            col = Color.orange;
            setColState(8);
        }else if(ie.getSource() == colItem[9]){
            col = Color.pink;
            setColState(9);
        }else if(ie.getSource() == colItem[10]){
            col = Color.red;
            setColState(10);
        }else if(ie.getSource() == colItem[11]){
            col = Color.white;
            setColState(11);
        }else if(ie.getSource() == colItem[12]){
            col = Color.yellow;
            setColState(12);
        }
    }

    private void setFigState(int n){
        for(int i = 0; i < figItem.length; i++){
            figItem[i].setState(false);
        }
        figItem[n].setState(true);
    }

    private void setColState(int n){
        for(int i = 0; i < colItem.length; i++){
            colItem[i].setState(false);
        }
        colItem[n].setState(true);
    }

    public void mouseMoved(MouseEvent e){}
    public void mouseEntered(MouseEvent me){}
    public void mouseExited(MouseEvent me){}
    public void mouseClicked(MouseEvent me){}
    public void windowOpened(WindowEvent e){}
    public void windowClosed(WindowEvent e){}
    public void windowIconified(WindowEvent e){}
    public void windowDeiconified(WindowEvent e){}
    public void windowActivated(WindowEvent e){}
    public void windowDeactivated(WindowEvent e){}

    public void windowClosing(WindowEvent we){
        System.exit(0);
    }
}

abstract class Figure implements Serializable{
    protected int sx, sy, ex, ey;
    protected Color col;

    //デフォルトコンストラクタ追加。処理なし。
    public Figure(){};

    public Figure(int x1, int y1, int x2, int y2, Color c){
        sx = x1;  sy = y1;
        ex = x2;  ey = y2;
        col = c;
    }

    abstract void Draw(Graphics g);
}

class LineData extends Figure{
    public LineData(int x1, int y1, int x2, int y2, Color c){
        super(x1, y1, x2, y2, c);
    }

    public void Draw(Graphics g){
        g.setColor(col);
        g.drawLine(sx, sy, ex, ey);
    }
}

class RectData extends Figure{
    public RectData(int x1, int y1, int x2, int y2, Color c){
        super(x1, y1, x2, y2, c);
    }

    public void Draw(Graphics g){
        g.setColor(col);
        g.drawRect(sx<ex?sx:ex, sy<ey?sy:ey,
                      Math.abs(sx-ex), Math.abs(sy-ey));
    }
}

class OvalData extends Figure{
    public OvalData(int x1, int y1, int x2, int y2, Color c){
        super(x1, y1, x2, y2, c);
    }

    public void Draw(Graphics g){
        g.setColor(col);
        g.drawOval(sx<ex?sx:ex, sy<ey?sy:ey,
                       Math.abs(sx-ex), Math.abs(sy-ey));
    }
}

class FillRectData extends Figure{
    public FillRectData(int x1, int y1, int x2, int y2, Color c){
        super(x1, y1, x2, y2, c);
    }

    public void Draw(Graphics g){
        g.setColor(col);
        g.fillRect(sx<ex?sx:ex, sy<ey?sy:ey,
                       Math.abs(sx-ex), Math.abs(sy-ey));
    }
}

class FillOvalData extends Figure{
    public FillOvalData(int x1, int y1, int x2, int y2, Color c){
        super(x1, y1, x2, y2, c);
    }

    public void Draw(Graphics g){
        g.setColor(col);
        g.fillOval(sx<ex?sx:ex, sy<ey?sy:ey,
                       Math.abs(sx-ex), Math.abs(sy-ey));
    }
}

//一本のフリーラインを管理するクラス。
class FreeLineData extends Figure{
    Vector v = new Vector();
    public FreeLineData(Color c){
        col = c;
    }

    public void addPoint(int x1, int y1, int x2, int y2){
        v.addElement(new LineData(x1, y1, x2, y2, col));
    }

    public void Draw(Graphics g){
       for(int i = 0; i < v.size(); i++){
            ((LineData)v.elementAt(i)).Draw(g);
        }
    }
}

class OpenDialog{
    public String open(){
        FileDialog fd = new FileDialog(new Frame(),
                             "ファイルを開く", FileDialog.LOAD);
        fd.show();
        String fullpath = fd.getDirectory() + fd.getFile();
        return fullpath;
    }
}

class SaveDialog{
    public String save(){
        FileDialog fd = new FileDialog(new Frame(),
                              "ファイルの保存", FileDialog.SAVE);
        fd.show();
        String fullpath = fd.getDirectory() + fd.getFile();
        return fullpath;
    }
}
実行結果サンプル。
実行結果サンプル
スムーズにかけるんだけど、やっぱりチラつきすごいな。そろそろ対策しましょ。

Advertisement

ショートカット

634
634ブログ
このカテゴリのトップページに戻る
Incubator(Pukiwiki)
634ラボ
   UIコレクションギャラリー
   ZO-3ジェネレーター

サイト検索


Y!ログール