@634

おえかき その17 元に戻す(undo)

Advertisement

概念(?)

今まであった「元に戻す」は図形管理しているVector(v1)の最後の要素を削除しているだけだったから、たとえば開いたばかりのファイルにでも「元に戻す」が実行できちゃったりしたのさ。あんまダメじゃん。

んで、ちゃんとしたの作るんだけど、時間ない&本当にそれでいいのか微妙だから、とりあえず、どうやって実現しようとしてるかメモ。

Vectorでバッファつくる。1つの図形描画するごとに、そのときのすべての図形を管理しているv1(Vector)の状態をバッファにコピー。参照の代入だとダメだから、コピーする。(たぶんclone()メソッドかな。)で、「元に戻す」を実行したら、バッファの一番後ろの要素の参照先のオブジェクトをv1に代入してバッファの一番後ろの要素削除。

きっとこんな感じだな。プログラム起動時とファイル開いたときは、その状態をバッファの一番最初にコピー?で、バッファの要素が一個のときは「元に戻す」を実行できないようにすればいいのかな。眠いからよくワカンネ:-p

…差分だけ保持?でもいいのかな。

つか、このプログラムの場合、元に戻すことが出来る回数を数えておけば、別にバッファなんか作る必要ないのかも。リソースの無駄だし。やり直しを実現するなら別だけど。

てことで、手抜き。

カウンタ増やしただけ。
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;

    //「元に戻す」可能回数のカウンタ
    int undoCount;

    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;
        undoCount = 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();

        //元に戻せる回数 + 1
        undoCount++;
    }

    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();

                //元に戻せる回数初期化
                undoCount = 0;

            }catch(Exception e){
                System.out.println(e);
            }
        }

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

        if(ae.getSource() == undo && undoCount > 0){
            v1.remove(v1.size()-1);
            undoCount--;
            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ラボ
   UIコレクションギャラリー

サイト検索

Google

Web サイト内

Y!ログール