おえかき その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コレクションギャラリー サイト検索Y!ログール |