// Java版AceDrawのためのステップ // 「AceDraw プロト4」AceDrawProto4.java // Copyright(c)2007 A.Hiramatsu import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.io.*; import java.util.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.filechooser.*; public class AceDrawProto4 { private static final int imgWidth = 320; private static final int imgByteWidth = imgWidth / 8; private static final int imgHeight = 240; private static final int animeFrmSize = 9728; private static final int animeFrmImgBytes = imgByteWidth * imgHeight; private static final int animeFrmHeadSize = 128; private static final int lupePixels = 40; private static final int lupeScale = 4; private static class AnimeFrame { boolean mark; byte[] img; private AnimeFrame() { this.mark = false; this.img = new byte[animeFrmImgBytes]; for(int i=0; i<animeFrmImgBytes; i++) { this.img[i] = (byte)255; } } private void setMark(boolean b) { this.mark = b; } private boolean getMark() { return this.mark; } private void setImg(byte[] src) { int n = src.length; if(n > animeFrmImgBytes) n = animeFrmImgBytes; for(int i=0; i<n; i++) { this.img[i] = src[i]; } } private byte[] getImg() { return this.img; } private byte[] cloneImg() { byte[] rImg = new byte[animeFrmImgBytes]; for(int i=0; i<animeFrmImgBytes; i++) { rImg[i] = this.img[i]; } return rImg; } }; private ArrayList<AnimeFrame> aniFrms = new ArrayList<AnimeFrame>(); private final int paletts[][] = { // CPN CPn CpN Cpn cPN cPn cpN cpn {0x000000,0x000000,0x000000,0x000000,0xffffff,0xffffff,0xffffff,0xffffff}, // cur {0xe00000,0xe00000,0x000000,0x000000,0xffb0b0,0xffb0b0,0xffffff,0xffffff}, // cur,prv {0x0000e0,0x000000,0x0000e0,0x000000,0xb0c0ff,0xffffff,0xb0c0ff,0xffffff}, // cur,nxt {0xd000d0,0xe00000,0x0000e0,0x000000,0xffb0ff,0xffb0b0,0xb0c0ff,0xffffff} // all }; private byte[] fileHeadBuf = new byte[animeFrmSize]; private byte[] frameHeadBuf = new byte[animeFrmHeadSize]; private byte[] frameImgBuf = new byte[animeFrmImgBytes]; private byte[] drawingImg; private byte[] prvFrmImg; private byte[] nxtFrmImg; private int curFrmNo; private byte[] undoImg; private byte[] redoImg; private byte[] ccImg; private JLabel grpInfoLbl; private JToggleButton freeBtn; private JToggleButton snglBtn; private JToggleButton polyBtn; private JToggleButton lupeBtn; private JButton undoBtn; private JPopupMenu plMenu; private boolean plMenuVisible; private JFrame mainFrm; private JFileChooser fChoose = new JFileChooser("."); private JFrame lupeFrm; private JLabel lupeInfoLbl; private JLabel frmInfoLbl; private JButton frmBMBtn; private JButton frmBBtn; private JButton frmFBtn; private JButton frmFMBtn; private JToggleButton frmPBtn; private JToggleButton frmNBtn; private JMenu fileMenu; private JMenu grpMenu; private JMenu frmMenu; private JMenu playMenu; private BufferedImage mainImg = new BufferedImage(imgWidth,imgHeight, BufferedImage.TYPE_INT_RGB); private boolean drawing = false; private boolean dragging = false; private boolean erasing = false; private boolean tempdraw = false; private int drawLatX,drawLatY; private int drawCurX,drawCurY; private enum DrawMode {none,free,sngl,poly}; private DrawMode drawmode; private ArrayList<Point> plPoints; private boolean canundo,canredo; private boolean fileClean; private String fileName = ""; private int ccx1,ccy1,ccx2,ccy2; private int ccWidth,ccHeight; private boolean grpSelecting; private boolean inGrpCut; private boolean inGrpCopy; private boolean inGrpPaste; private boolean pasteModeOr; private int lupeX,lupeY; private int lupeDragColor; private int lupeOfsX,lupeOfsY; private boolean lupeDragging; private JPanel grpPnl = new JPanel() { public void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(mainImg,0,0,this); if(lupeFrm.isVisible()) { g.setColor(Color.GREEN); g.drawRect(lupeX-1,lupeY-1,lupePixels+1,lupePixels+1); } } }; private JPanel lupeGrpPnl = new JPanel() { public void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(mainImg,0,0,lupePixels*lupeScale,lupePixels*lupeScale, lupeX,lupeY,lupeX+lupePixels,lupeY+lupePixels,this); } }; private void updateView() { int bc,bp,bn; int pal,ix; int srcp = 0; pal = 0; if(frmPBtn.isSelected() && (curFrmNo > 0)) pal = pal + 1; if(frmNBtn.isSelected() && (curFrmNo < aniFrms.size()-1)) pal = pal + 2; for(int y=0; y<imgHeight; y++) { for(int x=0; x<imgByteWidth; x++) { bc = drawingImg[srcp]; bp = prvFrmImg[srcp]; bn = nxtFrmImg[srcp++]; for(int i=0; i<8; i++) { ix = ((bc >> (7-i)) & 1)*4 + ((bp >> (7-i)) & 1)*2 + ((bn >> (7-i)) & 1); mainImg.setRGB(x*8+i,y,paletts[pal][ix]); } } } grpPnl.repaint(); } private void updateView(int x1,int y1,int x2,int y2) { int bc,bp,bn; int pal,ix; int srcp; int t; if(! (((x1 < 0) && (x2 < 0)) || ((x1 >= imgWidth) && (x2 >= imgWidth)) || ((y1 < 0) && (y2 < 0)) || ((y1 >= imgHeight) && (y2 >= imgHeight))) ) { if(x1>x2) { t = x1; x1 = x2; x2 = t; } if(y1>y2) { t = y1; y1 = y2; y2 = t; } if(x1 < 0) x1 = 0; if(x2 >= imgWidth) x2 = imgWidth-1; if(y1 < 0) y1 = 0; if(y2 >= imgHeight) y2 = imgHeight-1; int bx1 = x1 / 8; int bx2 = x2 / 8; pal = 0; if(frmPBtn.isSelected() && (curFrmNo > 0)) pal = pal + 1; if(frmNBtn.isSelected() && (curFrmNo < aniFrms.size()-1)) pal = pal + 2; for(int y=y1; y<=y2; y++) { srcp = y * imgByteWidth + bx1; for(int x=bx1; x<=bx2; x++) { bc = drawingImg[srcp]; bp = prvFrmImg[srcp]; bn = nxtFrmImg[srcp++]; for(int i=0; i<8; i++) { ix = ((bc >> (7-i)) & 1)*4 + ((bp >> (7-i)) & 1)*2 + ((bn >> (7-i)) & 1); mainImg.setRGB(x*8+i,y,paletts[pal][ix]); } } } grpPnl.repaint(); } } private void updateLupe() { updateView(lupeX,lupeY,lupeX+lupePixels-1,lupeX+lupePixels); lupeGrpPnl.repaint(); } private void updateFrmInfo() { char c = ' '; if(aniFrms.get(curFrmNo).getMark()) c = '*'; frmInfoLbl.setText(c + Integer.toString(curFrmNo+1) + " / "+Integer.toString(aniFrms.size())); } private byte[] newImg() { byte[] img = new byte[animeFrmImgBytes]; for(int i=0; i < animeFrmImgBytes; i++) { img[i] = (byte)255; } return img; } private void updateFrm() { byte[] img =aniFrms.get(curFrmNo).getImg(); for(int i=0; i < animeFrmImgBytes; i++) { if(drawingImg[i] != img[i]) { aniFrms.get(curFrmNo).setImg(drawingImg); fileClean = false; break; } } canundo = false; canredo = false; } private void enaMenu(boolean t) { fileMenu.setEnabled(t); grpMenu.setEnabled(t); frmMenu.setEnabled(t); playMenu.setEnabled(t); } private void enaFrmFBBtns(boolean t) { frmBMBtn.setEnabled(t); frmBBtn.setEnabled(t); frmFBtn.setEnabled(t); frmFMBtn.setEnabled(t); } private void enaDrawBtns(boolean t) { freeBtn.setEnabled(t); snglBtn.setEnabled(t); polyBtn.setEnabled(t); undoBtn.setEnabled(t); lupeBtn.setEnabled(t); } private void imgSetPixel(int x,int y,int op) { int ofs,bitptn; if((x>=0) && (x<imgWidth) && (y>=0) && (y<imgHeight)) { ofs = x / 8 + y * imgByteWidth; bitptn = 0x80 >> (x & 0x07); switch(op) { case 0: drawingImg[ofs] &= (byte)(~bitptn); break; case 1: drawingImg[ofs] |= (byte)bitptn; break; case 2: drawingImg[ofs] ^= (byte)bitptn; break; default: } } } private void imgDrawLine(int x1,int y1,int x2,int y2,int op) { int w,h,dx,dy,accum; w = x2 - x1; dx = 1; if(w < 0) { w = -w; dx = -dx; } h = y2 - y1; dy = 1; if(h < 0) { h = -h; dy = -dy; } h++; w++; if((w > 0) || (h > 0)) { accum = 0; if(w > h) { do { imgSetPixel(x1,y1,op); x1 += dx; accum += h; if(accum >= w) { accum -= w; y1 += dy; } } while(x1 != x2); } else { do { imgSetPixel(x1,y1,op); y1 += dy; accum += w; if(accum >= h) { accum -= h; x1 += dx; } } while(y1 != y2); } imgSetPixel(x2,y2,op); } } private void imgDrawHLine(int x1,int x2,int y,int op) { int ofs,endofs,bp1,bp2; if((y >= 0) && (y < imgHeight)) { if(! ((x1 < 0) && (x2 < 0)) || ((x1 >= imgWidth) && (x2 >= imgWidth)) ) { if(x1 > x2) { int t = x1; x1 = x2; x2 = t; } if(x1 < 0) x1 = 0; if(x2 >=imgWidth) x2 = imgWidth - 1; ofs = x1 / 8 + y * imgByteWidth; bp1 = (0x100 >> (x1 & 0x07)) - 1; endofs = x2 / 8 + y * imgByteWidth; bp2 = ~((0x80 >> (x2 & 0x07)) - 1); if(ofs == endofs) { switch(op) { case 0: drawingImg[ofs] &= (byte)(~(bp1 & bp2)); break; case 1: drawingImg[ofs] |= (byte)(bp1 & bp2); break; case 2: drawingImg[ofs] ^= (byte)(bp1 & bp2); break; default: } } else { switch(op) { case 0: drawingImg[ofs] &= (byte)(~bp1); break; case 1: drawingImg[ofs] |= (byte)bp1; break; case 2: drawingImg[ofs] ^= (byte)bp1; break; default: } for(int i=ofs+1; i<endofs; i++) { switch(op) { case 0: drawingImg[i] =(byte)0; break; case 1: drawingImg[i] =(byte)0xff; break; case 2: drawingImg[i] = (byte)(~drawingImg[i]); break; default: } } switch(op) { case 0: drawingImg[endofs] &= (byte)(~bp2); break; case 1: drawingImg[endofs] |= (byte)bp2; break; case 2: drawingImg[endofs] ^= (byte)bp2; break; default: } } } } } private void imgFillRect(int x1,int y1,int x2,int y2,int op) { if(! ((y1 < 0) && (y2 < 0)) || ((y1 >= imgHeight) && (y2 >= imgHeight)) ) { if(y1 > y2) { int t = y1; y1 = y2; y2 = t; } if(y1 < 0) y1 = 0; if(y2 >= imgHeight) y2 = imgHeight - 1; for(int y=y1; y<=y2; y++) { imgDrawHLine(x1,x2,y,op); } } } private void imgDrawVLine(int x,int y1,int y2,int op) { int ofs,bp; if((x >= 0) && (x < imgWidth)) { if(! ((y1 < 0) && (y2 < 0)) || ((y1 >= imgHeight) && (y2 >= imgHeight)) ) { if(y1 > y2) { int t = y1; y1 = y2; y2 = t; } if(y1 < 0) y1 = 0; if(y2 >=imgHeight) y2 = imgHeight - 1; ofs = x / 8 + y1 * imgByteWidth; bp = 0x80 >> (x & 0x07); for(int i = y1; i <= y2; i++) { switch(op) { case 0: drawingImg[ofs] &= (byte)(~bp); break; case 1: drawingImg[ofs] |= (byte)bp; break; case 2: drawingImg[ofs] ^= (byte)bp; break; default: } ofs += imgByteWidth; } } } } private void imgDrawRect(int x1,int y1,int x2,int y2,int op) { if(! ((y1 < 0) && (y2 < 0)) || ((y1 >= imgHeight) && (y2 >= imgHeight)) ) { if(x1 > x2) { int t = x1; x1 = x2; x2 = t; } if(y1 > y2) { int t = y1; y1 = y2; y2 = t; } if(x1 < 0) x1 = 0; if(x2 >= imgWidth) x2 = imgWidth - 1; if(y1 < 0) y1 = 0; if(y2 >= imgHeight) y2 = imgHeight - 1; imgDrawHLine(x1,x2,y1,op); if((y2 != y1)) { if((y2-y1) > 1) { imgDrawVLine(x1,y1+1,y2-1,op); if(x1 != x2) imgDrawVLine(x2,y1+1,y2-1,op); } imgDrawHLine(x1,x2,y2,op); } } } private void captureImg(int x1,int y1,int x2,int y2) { int srcofs,dstofs,bx1,bx2,dbx,bp,shift; if(! ((x1 < 0) && (x2 < 0) || (x1 >= imgWidth) && (x2 >= imgWidth) || (y1 < 0) && (y2 < 0) || (y1 >= imgHeight) && (y2 >= imgHeight)) ) { if(x1 > x2) { int t = x1; x1 = x2; x2 = t; } if(y1 > y2) { int t = y1; y1 = y2; y2 = t; } if(x1 < 0) x1 = 0; if(x2 >= imgWidth) x2 = imgWidth - 1; if(y1 < 0) y1 = 0; if(y2 >= imgHeight) y2 = imgHeight - 1; bx1 = x1 / 8; bx2 = x2 / 8; shift = 8 - (x1 & 0x07); srcofs = y1 * imgByteWidth; dstofs = 0; for(int iy=y1;iy<=y2;iy++) { dbx = 0; for(int ix=bx1;ix<=bx2;ix++) { bp = drawingImg[srcofs+ix] * 256; if(ix < (imgByteWidth-1)) bp |= drawingImg[srcofs+ix+1] & 0xff; else bp |= 0xff; ccImg[dstofs+dbx] = (byte)(bp >> shift); dbx++; } srcofs += imgByteWidth; dstofs += imgByteWidth; } ccWidth = x2 - x1 + 1; ccHeight = y2 - y1 + 1; } else { ccWidth = 0; ccHeight = 0; } } private void pasteImg(int x,int y,boolean xor) { int ofs,sbx,bp,bcnt; int w,h,sx0,sy0; w = ccWidth; h = ccHeight; sx0 = 0; sy0 = 0; if((w != 0) && (h != 0)) { if((x+w >= 0) && (y+h >= 0) && (x < imgWidth) && (y < imgHeight)) { if(x < 0) { sx0 = -x; w = w + x; x = 0; } if(x+w > imgWidth) { w = imgWidth - x; } if(y < 0) { sy0 = -y; h = h + y; y = 0; } if(y+h > imgHeight) { h = imgHeight - y; } ofs = sy0 * imgByteWidth; for(int iy=0; iy<h; iy++) { sbx = sx0 / 8; int ix = 0; int i = sx0 & 0x07; bp = (ccImg[ofs+sbx] & 0xff) << i; while(ix < w) { if(xor) { if(bp <= 127) imgSetPixel(x+ix,y+iy,2); } else { if(pasteModeOr) { if(bp <= 127) imgSetPixel(x+ix,y+iy,0); } else { if(bp > 127) imgSetPixel(x+ix,y+iy,1); else imgSetPixel(x+ix,y+iy,0); } } bp = (bp + bp) & 0xff; i++; if(i>7) { sbx++; bp = ccImg[ofs+sbx] & 0xff; i=0; } ix++; } ofs += imgByteWidth; } } } } private void setUndo() { for(int i=0; i<animeFrmImgBytes; i++) { // 画面イメージを undoImg[i] = drawingImg[i]; // undoバッファに保存 } canundo=true; // 「undo可能だがまだ一度もundoしてない」 canredo=false; // 状態にする } private void drawTempLine(int x,int y) { if(inGrpPaste) { if((ccWidth != 0) && (ccHeight != 0)) { imgDrawRect(x-ccWidth/2,y-ccHeight/2, // 枠仮描画 x+ccWidth/2-1,y+ccHeight/2-1,2); pasteImg(x-ccWidth/2,y-ccHeight/2,true); // 仮ペースト drawCurX=x; // 仮描画位置更新 drawCurY=y; tempdraw=true; // 仮描画済み } } else if((drawLatX != x) || (drawLatY != y)) { // 長さが0でなければ if(inGrpCut || inGrpCopy) { imgDrawRect(drawLatX,drawLatY,x,y,2); } else { imgDrawLine(drawLatX,drawLatY,x,y,2); // 仮描画する } drawCurX=x; // 仮描画位置更新 drawCurY=y; tempdraw=true; // 仮描画済み } } private void cancelLine() { if(inGrpCut || inGrpCopy) { if(tempdraw) { imgDrawRect(drawLatX,drawLatY, // 仮描画線を消す drawCurX,drawCurY,2); } } else if(inGrpPaste) { if(tempdraw && (ccWidth != 0) && (ccHeight != 0)) { imgDrawRect(drawCurX-ccWidth/2,drawCurY-ccHeight/2, // 枠を消す drawCurX+ccWidth/2-1,drawCurY+ccHeight/2-1,2); pasteImg(drawCurX - ccWidth/2, drawCurY - ccHeight/2,true); // 仮ペーストをキャンセル } } else if(drawmode.equals(DrawMode.sngl) || // 仮描画するのは単直線かポリ直線のみ drawmode.equals(DrawMode.poly)) { if(tempdraw) { // 仮描画線を引いていたら if((drawLatX != drawCurX) || (drawLatY != drawCurY)) { imgDrawLine(drawLatX,drawLatY, // 仮描画線を消す drawCurX,drawCurY,2); } } } tempdraw=false; } MouseListener grpMLsn = new MouseAdapter() { // マウスボタンイベント public void mousePressed(MouseEvent e) { int x = e.getX(); int y = e.getY(); if(! lupeFrm.isVisible()) { // ルーペ非表示中 if(e.getButton()==MouseEvent.BUTTON1) { // 左ボタン押された if(inGrpCut || inGrpCopy) { grpSelecting = true; drawLatX = x; drawLatY = y; drawCurX = x; drawCurY = y; } else if(inGrpPaste) { if((ccWidth !=0) && (ccHeight != 0)) { cancelLine(); setUndo(); pasteImg(x-ccWidth/2,y-ccHeight/2,false); updateView(); undoBtn.setEnabled(true); } } else { if(!erasing) { // 消しゴム使用中でなければ if(drawmode.equals(DrawMode.free)) { // 自由曲線モード setUndo(); drawing=true; dragging=false; drawLatX=x; // 現在位置を最後の位置とする drawLatY=y; } else if(drawmode.equals(DrawMode.sngl)) { // 単直線モード setUndo(); drawing=true; drawLatX=x; // 現在位置を最後の位置とする drawLatY=y; drawCurX=x; // 仮描画用位置 drawCurY=y; } else if(drawmode.equals(DrawMode.poly)) { // ポリ直線モード if(drawing) { // すでに描画中なら if((drawLatX != x) || (drawLatY != y)) { plPoints.add(new Point(x,y)); // 現在の点を追加 } } else { plPoints.clear(); plPoints.add(new Point(x,y)); setUndo(); enaMenu(false); enaFrmFBBtns(false); enaDrawBtns(false); } drawing=true; // 描画中にする drawLatX=x; // 最後の位置を更新 drawLatY=y; drawCurX=x; // 仮描画用位置 drawCurY=y; } else { } } } } else if(e.getButton()==MouseEvent.BUTTON3) { // 右ボタン押された if(inGrpCut || inGrpCopy || inGrpPaste) { inGrpCut = false; inGrpCopy = false; if(inGrpPaste) { cancelLine(); updateView(); } inGrpPaste = false; grpSelecting = false; enaDrawBtns(true); enaFrmFBBtns(true); enaMenu(true); } else { if(plMenuVisible) { plMenu.setVisible(false); plMenuVisible = false; } else { if(drawing) { // 描画中で if(drawmode.equals(DrawMode.poly)) { // なおかつポリ直線モードなら plMenu.show(grpPnl,x,y); plMenuVisible = true; } } else { // 描画中でなければ setUndo(); imgDrawHLine(x-1,x+1,y-2,1); imgFillRect(x-2,y-1,x+2,y+1,1); imgDrawHLine(x-1,x+1,y+2,1); updateView(); erasing = true; // 消しゴム使用中にする } } } } } else { // ルーペ表示中 if(e.getButton()==MouseEvent.BUTTON1) { if((x >= lupeX) && (x < lupeX+lupePixels) && (y >= lupeY) && (y < lupeY+lupePixels)) { lupeOfsX = x - lupeX; lupeOfsY = y - lupeY; lupeDragging = true; } else { } } } } public void mouseReleased(MouseEvent e) { int x = e.getX(); int y = e.getY(); if(e.getButton()==MouseEvent.BUTTON1) { // 左ボタン離された if(! lupeDragging) { if(inGrpCut || inGrpCopy) { if(grpSelecting) { cancelLine(); if(drawLatX > x) { ccx2 = drawLatX; ccx1 = x; } else { ccx1 = drawLatX; ccx2 = x; } if(ccy1 > y) { ccy2 = drawLatY; ccy1 = y; } else { ccy1 = drawLatY; ccy2 = y; } if(ccx1 < 0) ccx1 = 0; if(ccx2 >= imgWidth) ccx2 = imgWidth - 1; if(ccy1 < 0) ccy1 = 0; if(ccy2 >= imgHeight) ccy2 = imgHeight - 1; captureImg(ccx1,ccy1,ccx2,ccy2); if(inGrpCut) { setUndo(); imgFillRect(ccx1,ccy1,ccx2,ccy2,1); } updateView(); enaMenu(true); enaDrawBtns(true); enaFrmFBBtns(true); inGrpCut = false; inGrpCopy = false; grpSelecting = false; } } else { if(drawmode.equals(DrawMode.free)) { // 自由曲線モード if(drawing && !dragging) { imgSetPixel(drawLatX,drawLatY,0); // ドラッグしてなければ1点だけ打つ updateView(drawLatX,drawLatY,drawLatX,drawLatY); } drawing=false; dragging=false; } else if(drawmode.equals(DrawMode.sngl)) { // 単直線モード if(drawing) { cancelLine(); // 仮描画した線を消す if((drawLatX != x) || (drawLatY != y)) { // 線の長さが0でなければ imgDrawLine(drawLatX,drawLatY, drawCurX,drawCurY,0); // 正式に線を引く } updateView(); } drawing=false; } else { } } } else { // ルーペドラッグ中 lupeX = x - lupeOfsX; lupeY = y - lupeOfsY; if(lupeX < 0) lupeX = 0; if(lupeX > imgWidth-lupePixels) lupeX = imgWidth-lupePixels; if(lupeY < 0) lupeY = 0; if(lupeY > imgHeight-lupePixels) lupeY = imgHeight-lupePixels; lupeDragging = false; grpPnl.repaint(); updateLupe(); } } else if(e.getButton()==MouseEvent.BUTTON3) { // 右ボタン離された erasing=false; // 消しゴム使用中を解除 } else { } } public void mouseExited(MouseEvent e) { // マウスが描画領域を出た grpInfoLbl.setText(""); if(inGrpPaste) { cancelLine(); updateView(); } } }; MouseMotionListener grpMmLsn = new MouseMotionAdapter() { // マウス移動イベント public void mouseDragged(MouseEvent e) { int minx,miny,maxx,maxy; int x = e.getX(); int y = e.getY(); grpInfoLbl.setText( "(" + Integer.toString(x) + "," + Integer.toString(y) + ")" ); // 座標表示 if(! lupeDragging) { if(grpSelecting) { cancelLine(); drawTempLine(x,y); updateView(); } else if(drawing) { if(drawmode.equals(DrawMode.free)) { // 自由曲線モード if((drawLatX != x) || (drawLatY != y)) { // カーソルが動いていたら imgDrawLine(drawLatX,drawLatY,x,y,0); // 線を引く int x0 = drawLatX; int y0 = drawLatY; drawLatX=x; // 最後の位置を更新 drawLatY=y; dragging=true; updateView(x0,y0,x,y); } } else if(drawmode.equals(DrawMode.sngl) || // 単直線モード または (drawmode.equals(DrawMode.poly) && // ポリ直線モードで描画中なら drawing)) { if(drawCurX < drawLatX) { // 更新領域の計算その1 minx = drawCurX; maxx = drawLatX; } else { minx = drawLatX; maxx = drawCurX; } if(drawCurY < drawLatY) { miny = drawCurY; maxy = drawLatY; } else { miny = drawLatY; maxy = drawCurY; } cancelLine(); // 仮描画線を消す drawTempLine(x,y); // 新しい仮描画線を書く if(x < minx) minx = x; // 更新領域の計算その2 if(x > maxx) maxx = x; if(y < miny) miny = y; if(y > maxy) maxy = y; updateView(minx,miny,maxx,maxy); } else { } } else if(erasing) { // 消しゴム使用中 imgDrawHLine(x-1,x+1,y-2,1); imgFillRect(x-2,y-1,x+2,y+1,1); imgDrawHLine(x-1,x+1,y+2,1); updateView(); } else { } } else { // ルーペドラッグ中 lupeX = x - lupeOfsX; lupeY = y - lupeOfsY; if(lupeX < 0) lupeX = 0; if(lupeX > imgWidth-lupePixels) lupeX = imgWidth-lupePixels; if(lupeY < 0) lupeY = 0; if(lupeY > imgHeight-lupePixels) lupeY = imgHeight-lupePixels; updateView(); updateLupe(); } } public void mouseMoved(MouseEvent e) { int minx,miny,maxx,maxy; int x = e.getX(); int y = e.getY(); grpInfoLbl.setText( "(" + Integer.toString(x) + "," + Integer.toString(y) + ")" ); // 座標表示 if(inGrpPaste) { cancelLine(); drawTempLine(x,y); updateView(); } else if(drawmode.equals(DrawMode.poly)) { // ポリ直線モードで if(drawing) { // 描画中なら if(drawCurX < drawLatX) { // 更新領域の計算その1 minx = drawCurX; maxx = drawLatX; } else { minx = drawLatX; maxx = drawCurX; } if(drawCurY < drawLatY) { miny = drawCurY; maxy = drawLatY; } else { miny = drawLatY; maxy = drawCurY; } cancelLine(); // 仮描画線を消す drawTempLine(x,y); // 新しい仮描画線を描く if(x < minx) minx = x; // 更新領域の計算その2 if(x > maxx) maxx = x; if(y < miny) miny = y; if(y > maxy) maxy = y; updateView(minx,miny,maxx,maxy); } } else { } } }; MouseListener lupeMLsn = new MouseAdapter() { // マウスボタンイベント public void mousePressed(MouseEvent e) { int x = e.getX() / lupeScale; int y = e.getY() / lupeScale; if((x >= 0) && (x < lupePixels) && (y >= 0) && (y < lupePixels)) { if(e.getButton()==MouseEvent.BUTTON1) { // 左ボタン押された setUndo(); imgSetPixel(lupeX+x,lupeY+y,0); lupeDragColor = 0; updateLupe(); } else if(e.getButton()==MouseEvent.BUTTON3) { // 右ボタン押された setUndo(); imgSetPixel(lupeX+x,lupeY+y,1); lupeDragColor = 1; updateLupe(); } else { } } } public void mouseExited(MouseEvent e) { // マウスが描画領域を出た lupeInfoLbl.setText(""); } }; MouseMotionListener lupeMmLsn = new MouseMotionAdapter() { // マウス移動イベント public void mouseDragged(MouseEvent e) { int x = e.getX() / lupeScale + lupeX; int y = e.getY() / lupeScale + lupeY; if((x >= lupeX) && (x < lupePixels+lupeX) && (y >= lupeY) && (y < lupePixels+lupeY)) { lupeInfoLbl.setText("(" + Integer.toString(x) + "," + Integer.toString(y) + ")"); // 座標表示 imgSetPixel(x,y,lupeDragColor); updateLupe(); } else { lupeInfoLbl.setText(""); } } public void mouseMoved(MouseEvent e) { int x = e.getX() / lupeScale + lupeX; int y = e.getY() / lupeScale + lupeY; if((x >= lupeX) && (x < lupePixels+lupeX) && (y >= lupeY) && (y < lupePixels+lupeY)) { lupeInfoLbl.setText("(" + Integer.toString(x) + "," + Integer.toString(y) + ")"); // 座標表示 } else { lupeInfoLbl.setText(""); } } }; MouseListener plEndLsn = new MouseAdapter() { public void mousePressed(MouseEvent e) { int x1,y1,x2,y2; if(e.getButton()==MouseEvent.BUTTON1) { cancelLine(); if(plPoints.size() >= 2) { x1 = plPoints.get(0).x; y1 = plPoints.get(0).y; for(int i=1; i<plPoints.size(); i++) { x2 = plPoints.get(i).x; y2 = plPoints.get(i).y; imgDrawLine(x1,y1,x2,y2,0); x1 = x2; y1 = y2; } plPoints.clear(); } updateView(); drawing = false; enaMenu(true); enaFrmFBBtns(true); enaDrawBtns(true); } plMenuVisible = false; } }; MouseListener plBackLsn = new MouseAdapter() { public void mousePressed(MouseEvent e) { int x1,y1,x2,y2; if(e.getButton()==MouseEvent.BUTTON1) { cancelLine(); if(plPoints.size() > 1) { x1 = plPoints.get(plPoints.size()-2).x; y1 = plPoints.get(plPoints.size()-2).y; x2 = plPoints.get(plPoints.size()-1).x; y2 = plPoints.get(plPoints.size()-1).y; plPoints.remove(plPoints.size()-1); imgDrawLine(x1,y1,x2,y2,2); drawLatX = x1; drawLatY = y1; updateView(); } } plMenuVisible = false; } }; MouseListener undoBtnLsn = new MouseAdapter() { // undoボタンイベント public void mousePressed(MouseEvent e) { cancelLine(); if(canredo) { // redo可(一度undoしている) if(canundo) { // undo可なら for(int i=0; i<animeFrmImgBytes; i++) { // undoバッファの内容を drawingImg[i] = undoImg[i]; // 画面に復帰 } } else { for(int i=0; i<animeFrmImgBytes; i++) { // redoバッファの内容を drawingImg[i] = redoImg[i]; // 画面に復帰 } } canundo = !canundo; // undo可をトグル } else { if(canundo) { // 描画後最初のundo for(int i=0; i<animeFrmImgBytes; i++) { // 現在の画面イメージを redoImg[i] = drawingImg[i]; // redoバッファに保存 drawingImg[i] = undoImg[i]; // undoバッファの内容を } // 画面に復帰 canundo=false; canredo=true; // redo可にする } } updateView(); if(lupeFrm.isVisible()) updateLupe(); drawing=false; dragging=false; erasing=false; } }; MouseListener freeBtnLsn = new MouseAdapter() { // freeボタン public void mousePressed(MouseEvent e) { drawmode=DrawMode.free; drawing=false; dragging=false; erasing=false; if(lupeFrm.isVisible()) { lupeFrm.setVisible(false); enaMenu(true); grpPnl.repaint(); } } }; MouseListener snglBtnLsn = new MouseAdapter() { // 単直線ボタン public void mousePressed(MouseEvent e) { drawmode=DrawMode.sngl; drawing=false; dragging=false; erasing=false; if(lupeFrm.isVisible()) { lupeFrm.setVisible(false); enaMenu(true); grpPnl.repaint(); } } }; MouseListener polyBtnLsn = new MouseAdapter() { // ポリ直線ボタン public void mousePressed(MouseEvent e) { drawmode=DrawMode.poly; drawing=false; dragging=false; erasing=false; if(lupeFrm.isVisible()) { lupeFrm.setVisible(false); enaMenu(true); grpPnl.repaint(); } } }; MouseListener lupeBtnLsn = new MouseAdapter() { // ルーペボタン public void mousePressed(MouseEvent e) { lupeBtn.setSelected(true); lupeFrm.setVisible(true); enaMenu(false); } }; MouseListener frmFBtnLsn = new MouseAdapter() { public void mousePressed(MouseEvent e) { if(curFrmNo < aniFrms.size()-1) { updateFrm(); curFrmNo++; prvFrmImg = drawingImg; drawingImg = aniFrms.get(curFrmNo).cloneImg(); if(curFrmNo < aniFrms.size()-1) { nxtFrmImg = aniFrms.get(curFrmNo+1).getImg(); } updateView(); updateLupe(); updateFrmInfo(); } else { int r = JOptionPane.showConfirmDialog(mainFrm,"新規フレームを作成しますか?", "AceDraw",JOptionPane.YES_NO_OPTION); if(r == JOptionPane.YES_OPTION) { updateFrm(); addNewFrm(); } } } }; MouseListener frmBBtnLsn = new MouseAdapter() { public void mousePressed(MouseEvent e) { if(curFrmNo > 0) { updateFrm(); curFrmNo--; nxtFrmImg = drawingImg; drawingImg = aniFrms.get(curFrmNo).cloneImg(); if(curFrmNo > 0) { prvFrmImg = aniFrms.get(curFrmNo-1).getImg(); } updateView(); updateLupe(); updateFrmInfo(); } } }; MouseListener frmFMBtnLsn = new MouseAdapter() { public void mousePressed(MouseEvent e) { int newcur = curFrmNo; if((curFrmNo < aniFrms.size()-1) && (aniFrms.get(curFrmNo).getMark())) { newcur++; } while(newcur < aniFrms.size()-1) { if(! aniFrms.get(newcur).getMark()) newcur++; else break; } if(curFrmNo != newcur) { updateFrm(); curFrmNo = newcur; drawingImg = aniFrms.get(curFrmNo).getImg(); if(curFrmNo > 0) { prvFrmImg = aniFrms.get(curFrmNo-1).getImg(); } if(curFrmNo < aniFrms.size()-1) { nxtFrmImg = aniFrms.get(curFrmNo+1).getImg(); } updateView(); updateLupe(); updateFrmInfo(); } } }; MouseListener frmBMBtnLsn = new MouseAdapter() { public void mousePressed(MouseEvent e) { int newcur = curFrmNo; if((curFrmNo > 0) && (aniFrms.get(curFrmNo).getMark())) { newcur--; } while(newcur > 0) { if(! aniFrms.get(newcur).getMark()) newcur--; else break; } if(curFrmNo != newcur) { updateFrm(); curFrmNo = newcur; drawingImg = aniFrms.get(curFrmNo).getImg(); if(curFrmNo > 0) { prvFrmImg = aniFrms.get(curFrmNo-1).getImg(); } if(curFrmNo < aniFrms.size()-1) { nxtFrmImg = aniFrms.get(curFrmNo+1).getImg(); } updateView(); updateLupe(); updateFrmInfo(); canundo = false; canredo = false; } } }; ItemListener frmPBtnLsn = new ItemListener() { public void itemStateChanged(ItemEvent e) { updateView(); updateLupe(); } }; ItemListener frmNBtnLsn = new ItemListener() { public void itemStateChanged(ItemEvent e) { updateView(); updateLupe(); } }; private boolean checkClean() { if(! fileClean) { int r = JOptionPane.showConfirmDialog(mainFrm,"アニメデータが変更されています。保存しますか?", "AceDraw",JOptionPane.YES_NO_CANCEL_OPTION); if(r == JOptionPane.YES_OPTION) { if(! doFileSave()) r = JOptionPane.CANCEL_OPTION; } if(r != JOptionPane.CANCEL_OPTION) { fileClean = true; return true; } else { return false; } } else { return true; } } private void doFileNew() { if(checkClean()) { aniFrms.clear(); aniFrms.add(new AnimeFrame()); curFrmNo = 0; fileName = ""; drawingImg = aniFrms.get(curFrmNo).cloneImg(); updateView(); updateFrmInfo(); } } private void doFileOpen() { File f; int n,p; int rlen = 0; int totalFrms = 0; long fsize; String s; boolean canRead = false; FileInputStream fi = null; AnimeFrame aniFrm; if(checkClean()) { n = fChoose.showOpenDialog(mainFrm); if(n==JFileChooser.APPROVE_OPTION ) { f = fChoose.getSelectedFile(); if(f != null) { s = fChoose.getName(f); canRead = true; if(s.length()>4) { if(s.substring(s.length()-4).toUpperCase().equals(".ACD")) { try { fi = new FileInputStream(f); } catch(Throwable fe) { JOptionPane.showMessageDialog(mainFrm,"ファイルのオープンに失敗しました", "AceDraw",JOptionPane.ERROR_MESSAGE); canRead = false; } if(canRead) { try { rlen = fi.read(fileHeadBuf); } catch(Throwable fe) { JOptionPane.showMessageDialog(mainFrm,"ファイルの入力中にエラーが発生しました", "AceDraw",JOptionPane.ERROR_MESSAGE); canRead = false; } } if(canRead) { fsize = f.length(); totalFrms = ((int)fileHeadBuf[8] & 0xff) + (((int)fileHeadBuf[9] & 0xff) << 8) + (((int)fileHeadBuf[10] & 0xff) << 16); curFrmNo = 0; aniFrms.clear(); if((rlen < animeFrmSize) || (fileHeadBuf[0] != 0x41) || (fileHeadBuf[1] != 0x43) || (fileHeadBuf[2] != 0x44) || (fileHeadBuf[3] != 0x00) || (totalFrms < 1) || (fileHeadBuf[11] != 0) || (fsize != (long)animeFrmSize * (totalFrms + 1)) ){ JOptionPane.showMessageDialog(mainFrm,"ファイルヘッダが壊れています", "AceDraw",JOptionPane.ERROR_MESSAGE); canRead = false; } if(canRead) { fileName = s; for(int i=0; i < totalFrms; i++) { try { fi.read(frameHeadBuf); fi.read(frameImgBuf); } catch(Throwable fe) { JOptionPane.showMessageDialog(mainFrm,"ファイルの入力中にエラーが発生しました", "AceDraw",JOptionPane.ERROR_MESSAGE); canRead = false; } if(!canRead) break; aniFrm = new AnimeFrame(); if(frameHeadBuf[0]!=0) aniFrm.setMark(true); aniFrm.setImg(frameImgBuf); aniFrms.add(aniFrm); } } } } else { JOptionPane.showMessageDialog(mainFrm,"ファイルの拡張子が.ACDではありません", "AceDraw",JOptionPane.ERROR_MESSAGE); canRead = false; } } } } if(canRead) { drawingImg = aniFrms.get(curFrmNo).cloneImg(); if(curFrmNo < totalFrms-1) { nxtFrmImg = aniFrms.get(curFrmNo+1).getImg(); } updateView(); updateFrmInfo(); } } } private String saveFileName() { File f = null; int n; String s = ""; n = fChoose.showSaveDialog(mainFrm); if(n == JFileChooser.APPROVE_OPTION) { f = fChoose.getSelectedFile(); s = f.getAbsolutePath(); } return s; } private boolean fileSave(String fn) { boolean canOut = false; File f = null; FileOutputStream fos = null; int lc,fc; int bOfs,eOfs; if((fn != null) && (fn.length()!=0)) { if(fn.indexOf('.')<0) { fn = fn + ".acd"; } else { if(! fn.substring(fn.indexOf('.')).toUpperCase().equals(".ACD")) { JOptionPane.showMessageDialog(mainFrm,"ファイルの拡張子が.ACDではありません", "AceDraw",JOptionPane.ERROR_MESSAGE); fn = ""; } } if(fn.length() > 0) { f = new File(fn); if(f.exists()) { int r = JOptionPane.showConfirmDialog(mainFrm,"同名ファイルが存在します。上書きしますか?", "AceDraw",JOptionPane.YES_NO_OPTION); if(r == JOptionPane.YES_OPTION) canOut = true; } else { canOut = true; } if(canOut) { try { fos = new FileOutputStream(f); } catch(Throwable fe) { JOptionPane.showMessageDialog(mainFrm,"ファイルの作成に失敗しました", "AceDraw",JOptionPane.ERROR_MESSAGE); } if(canOut) { for(int i=0; i<animeFrmSize; i++) fileHeadBuf[i]= 0; fileHeadBuf[0] = (byte)'A'; // ファイルID fileHeadBuf[1] = (byte)'C'; fileHeadBuf[2] = (byte)'D'; fileHeadBuf[3] = 0; fileHeadBuf[4] = 0; // バージョン番号 fileHeadBuf[5] = 1; fileHeadBuf[6] = 0; // リザーブ fileHeadBuf[7] = 0; fileHeadBuf[8] = (byte)(aniFrms.size() & 0xff); // フレーム数 fileHeadBuf[9] = (byte)((aniFrms.size() >> 8) & 0xff); fileHeadBuf[10] = (byte)((aniFrms.size() >> 16) & 0xff); fileHeadBuf[11] = (byte)((aniFrms.size() >> 24) & 0xff); try { fos.write(fileHeadBuf); } catch(Throwable fe) { JOptionPane.showMessageDialog(mainFrm,"出力中にエラーが発生しました", "AceDraw",JOptionPane.ERROR_MESSAGE); canOut = false; } } for(int fr = 0; fr < aniFrms.size(); fr ++) { if(! canOut) break; if(aniFrms.get(fr).getMark()) frameHeadBuf[0] = 1; else frameHeadBuf[0] = 0; for(int i=1; i<128; i++) frameHeadBuf[i] = 0; frameImgBuf = aniFrms.get(fr).getImg(); if(canOut) { try { fos.write(frameHeadBuf); fos.write(frameImgBuf); } catch(Throwable fe) { JOptionPane.showMessageDialog(mainFrm,"出力中にエラーが発生しました", "AceDraw",JOptionPane.ERROR_MESSAGE); canOut = false; } } } // for try { fos.flush(); fos.close(); fileClean = true; } catch(Throwable fe) { JOptionPane.showMessageDialog(mainFrm,"出力ファイルのクローズに失敗しました", "AceDraw",JOptionPane.ERROR_MESSAGE); canOut = false; fileClean = false; } } } } return canOut; } private boolean doFilesaveAs() { boolean r =false; String nfn = saveFileName(); if((nfn != null) && (nfn.length() > 0)) { if(fileSave(nfn)) { fileName = nfn; r = true; } } return r; } private boolean doFileSave() { boolean r = false; if(fileName.length() == 0) { r = doFilesaveAs(); } else { r = fileSave(fileName); } return r; } private ActionListener fileActLsn = new ActionListener() { public void actionPerformed(ActionEvent e) { updateFrm(); if(e.getActionCommand().equals("New")) { doFileNew(); } else if(e.getActionCommand().equals("Open")) { doFileOpen(); } else if(e.getActionCommand().equals("Save")) { doFileSave(); } else if(e.getActionCommand().equals("saveAs")) { doFilesaveAs(); } else if(e.getActionCommand().equals("eXit")) { if(checkClean()) System.exit(0); } else { } } }; private void cutGrp() { enaMenu(false); enaDrawBtns(false); enaFrmFBBtns(false); inGrpCut = true; } private void copyGrp() { enaMenu(false); enaDrawBtns(false); enaFrmFBBtns(false); inGrpCopy = true; } private void pasteGrp() { enaMenu(false); enaDrawBtns(false); inGrpPaste = true; pasteModeOr = false; tempdraw = false; } private void pasteGrpOr() { enaMenu(false); enaDrawBtns(false); inGrpPaste = true; pasteModeOr = true; tempdraw = false; } private ActionListener grpActLsn = new ActionListener() { public void actionPerformed(ActionEvent e) { if(e.getActionCommand().equals("cuT")) { cutGrp(); } else if(e.getActionCommand().equals("Copy")) { copyGrp(); } else if(e.getActionCommand().equals("Paste")) { pasteGrp(); } else if(e.getActionCommand().equals("paste(Or)")) { pasteGrpOr(); } else { } } }; private void addNewFrm() { prvFrmImg = drawingImg; drawingImg = newImg(); AnimeFrame aniFrm = new AnimeFrame(); if(curFrmNo < aniFrms.size() - 1) { aniFrms.add(curFrmNo+1,aniFrm); } else { aniFrms.add(aniFrm); } curFrmNo++; updateView(); updateFrmInfo(); fileClean = false; } private void insertFrm() { nxtFrmImg = drawingImg; drawingImg = newImg(); AnimeFrame aniFrm = new AnimeFrame(); aniFrms.add(curFrmNo,aniFrm); updateView(); updateFrmInfo(); fileClean = false; } private void deleteFrm() { if(aniFrms.size() > 1) { int r = JOptionPane.showConfirmDialog(mainFrm,"このフレームを削除しますか?", "AceDraw",JOptionPane.YES_NO_OPTION); if(r == JOptionPane.YES_OPTION) { aniFrms.remove(curFrmNo); if(curFrmNo == aniFrms.size()) { curFrmNo--; drawingImg = aniFrms.get(curFrmNo).cloneImg(); if(curFrmNo > 0) { prvFrmImg = aniFrms.get(curFrmNo-1).getImg(); } else { prvFrmImg = newImg(); } } else { drawingImg = nxtFrmImg; if(curFrmNo < aniFrms.size() - 1) { nxtFrmImg = aniFrms.get(curFrmNo+1).getImg(); } else { nxtFrmImg = newImg(); } } updateView(); updateFrmInfo(); fileClean = false; } } } private ActionListener frmActLsn = new ActionListener() { public void actionPerformed(ActionEvent e) { updateFrm(); if(e.getActionCommand().equals("New")) { addNewFrm(); } else if(e.getActionCommand().equals("Insert")) { insertFrm(); } else if(e.getActionCommand().equals("Delete")) { deleteFrm(); } else { } } }; private void initProg() { drawingImg = newImg(); prvFrmImg = newImg(); nxtFrmImg = newImg(); undoImg = newImg(); redoImg = newImg(); ccImg = newImg(); plPoints = new ArrayList<Point>(); } private void doProg() { AnimeFrame aniFrm = new AnimeFrame(); aniFrms.add(aniFrm); curFrmNo = 0; canundo = false; canredo = false; fileClean = true; drawmode = DrawMode.none; grpSelecting = false; inGrpCut = false; inGrpCopy = false; inGrpPaste = false; pasteModeOr = false; ccWidth = 0; ccHeight = 0; lupeX = (imgWidth - lupePixels) / 2; lupeY = (imgHeight - lupePixels) / 2; FileNameExtensionFilter fFilt = new FileNameExtensionFilter("ACEdraw data", "acd"); fChoose.addChoosableFileFilter(fFilt); grpPnl.addMouseListener(grpMLsn); grpPnl.addMouseMotionListener(grpMmLsn); undoBtn.addMouseListener(undoBtnLsn); freeBtn.addMouseListener(freeBtnLsn); snglBtn.addMouseListener(snglBtnLsn); polyBtn.addMouseListener(polyBtnLsn); lupeBtn.addMouseListener(lupeBtnLsn); frmBMBtn.addMouseListener(frmBMBtnLsn); frmBBtn.addMouseListener(frmBBtnLsn); frmFBtn.addMouseListener(frmFBtnLsn); frmFMBtn.addMouseListener(frmFMBtnLsn); frmPBtn.addItemListener(frmPBtnLsn); frmNBtn.addItemListener(frmNBtnLsn); lupeFrm.addWindowListener(lupeWinLsn); lupeGrpPnl.addMouseListener(lupeMLsn); lupeGrpPnl.addMouseMotionListener(lupeMmLsn); mainFrm.addWindowListener(winLsn); } WindowListener winLsn = new WindowAdapter() { public void windowClosing(WindowEvent e) { updateFrm(); if(checkClean()) System.exit(0); } }; WindowListener lupeWinLsn = new WindowAdapter() { public void windowClosing(WindowEvent e) { lupeBtn.setSelected(false); enaMenu(true); freeBtn.setEnabled(true); snglBtn.setEnabled(true); polyBtn.setEnabled(true); } }; private void makeFrame() { JFrame.setDefaultLookAndFeelDecorated(true); JDialog.setDefaultLookAndFeelDecorated(true); mainFrm = new JFrame("AceDrawプロト4"); mainFrm.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); mainFrm.setResizable(false); JPanel toolBtnPnl = new JPanel(new GridLayout(4,1,2,0)); freeBtn =new JToggleButton("free"); snglBtn =new JToggleButton("single"); polyBtn =new JToggleButton("poly"); lupeBtn = new JToggleButton("lupe"); toolBtnPnl.add(freeBtn); toolBtnPnl.add(snglBtn); toolBtnPnl.add(polyBtn); toolBtnPnl.add(lupeBtn); ButtonGroup toolBtns = new ButtonGroup(); toolBtns.add(freeBtn); toolBtns.add(snglBtn); toolBtns.add(polyBtn); toolBtns.add(lupeBtn); plMenu = new JPopupMenu(); JMenuItem plItemEnd = new JMenuItem("End"); plItemEnd.addMouseListener(plEndLsn); JMenuItem plItemBack = new JMenuItem("Back"); plItemBack.addMouseListener(plBackLsn); plMenu.add(plItemEnd); plMenu.add(plItemBack); plMenuVisible = false; JPanel toolPnl = new JPanel(new BorderLayout(0,4)); undoBtn = new JButton("undo draw"); toolPnl.add(undoBtn,BorderLayout.CENTER); toolPnl.add(toolBtnPnl,BorderLayout.SOUTH); JPanel drawPnl = new JPanel(new BorderLayout()); grpInfoLbl = new JLabel(); grpInfoLbl.setFont(new Font("Monospaced",Font.PLAIN,10)); drawPnl.add(grpInfoLbl,BorderLayout.NORTH); drawPnl.add(toolPnl,BorderLayout.SOUTH); JPanel mainPnl = new JPanel(new BorderLayout(4,4)); JMenuBar mainMenu = new JMenuBar(); JPanel frmFBPnl = new JPanel(new GridLayout(1,6,2,2)); frmBMBtn = new JButton("<<"); frmBBtn = new JButton("<"); frmFBtn = new JButton(">"); frmFMBtn = new JButton(">>"); frmPBtn = new JToggleButton("P"); frmNBtn = new JToggleButton("N"); frmFBPnl.add(frmBMBtn); frmFBPnl.add(frmBBtn); frmFBPnl.add(frmFBtn); frmFBPnl.add(frmFMBtn); frmFBPnl.add(frmPBtn); frmFBPnl.add(frmNBtn); JPanel frmInfoPnl = new JPanel(new BorderLayout(2,2)); frmInfoLbl = new JLabel("1 / 1"); JLabel lblFrmFrame = new JLabel("Frame:"); frmInfoPnl.add(lblFrmFrame,BorderLayout.WEST); frmInfoPnl.add(frmInfoLbl,BorderLayout.CENTER); JPanel frmCtrlPnl = new JPanel(new BorderLayout(8,4)); frmCtrlPnl.add(frmInfoPnl,BorderLayout.NORTH); frmCtrlPnl.add(frmFBPnl,BorderLayout.CENTER); grpPnl.setPreferredSize(new Dimension(imgWidth,imgHeight)); mainPnl.add(grpPnl,BorderLayout.CENTER); mainPnl.add(drawPnl,BorderLayout.EAST); mainPnl.add(frmCtrlPnl,BorderLayout.SOUTH); mainPnl.setBorder(new EmptyBorder(4,4,4,4)); fileMenu = new JMenu("File"); fileMenu.setMnemonic(KeyEvent.VK_F); JMenuItem fileNew = new JMenuItem("New",KeyEvent.VK_N); fileNew.addActionListener(fileActLsn); JMenuItem fileOpen = new JMenuItem("Open",KeyEvent.VK_O); fileOpen.addActionListener(fileActLsn); JMenuItem fileSave = new JMenuItem("Save",KeyEvent.VK_S); fileSave.addActionListener(fileActLsn); JMenuItem filesaveAs = new JMenuItem("saveAs",KeyEvent.VK_A); filesaveAs.addActionListener(fileActLsn); JMenuItem fileeXit = new JMenuItem("eXit",KeyEvent.VK_X); fileeXit.addActionListener(fileActLsn); fileMenu.add(fileNew); fileMenu.add(fileOpen); fileMenu.add(fileSave); fileMenu.add(filesaveAs); fileMenu.add(fileeXit); mainMenu.add(fileMenu); grpMenu = new JMenu("Graphic"); grpMenu.setMnemonic(KeyEvent.VK_G); JMenuItem grpcuT = new JMenuItem("cuT",KeyEvent.VK_T); grpcuT.addActionListener(grpActLsn); JMenuItem grpCopy = new JMenuItem("Copy",KeyEvent.VK_C); grpCopy.addActionListener(grpActLsn); JMenuItem grpPaste = new JMenuItem("Paste",KeyEvent.VK_P); grpPaste.addActionListener(grpActLsn); JMenuItem grpPasteOr = new JMenuItem("paste(Or)",KeyEvent.VK_O); grpPasteOr.addActionListener(grpActLsn); grpMenu.add(grpcuT); grpMenu.add(grpCopy); grpMenu.add(grpPaste); grpMenu.add(grpPasteOr); mainMenu.add(grpMenu); frmMenu = new JMenu("fRame"); frmMenu.setMnemonic(KeyEvent.VK_R); JMenuItem frmNew = new JMenuItem("New",KeyEvent.VK_N); frmNew.addActionListener(frmActLsn); JMenuItem frmIns = new JMenuItem("Insert",KeyEvent.VK_I); frmIns.addActionListener(frmActLsn); JMenuItem frmDel = new JMenuItem("Delete",KeyEvent.VK_D); frmDel.addActionListener(frmActLsn); JMenuItem frmMove = new JMenuItem("Move",KeyEvent.VK_M); frmMove.setEnabled(false); JMenuItem frmCopy = new JMenuItem("Copy",KeyEvent.VK_C); frmCopy.setEnabled(false); JMenuItem frmSelF = new JMenuItem("Select frames",KeyEvent.VK_S); frmSelF.setEnabled(false); frmMenu.add(frmNew); frmMenu.add(frmIns); frmMenu.add(frmDel); frmMenu.add(frmMove); frmMenu.add(frmCopy); frmMenu.add(frmSelF); mainMenu.add(frmMenu); playMenu = new JMenu("Play"); playMenu.setMnemonic(KeyEvent.VK_P); JMenuItem playSt = new JMenuItem("Start",KeyEvent.VK_S); playSt.setEnabled(false); playMenu.add(playSt); mainMenu.add(playMenu); lupeFrm = new JFrame("AceDraw Lupe"); lupeGrpPnl.setPreferredSize(new Dimension(lupePixels * lupeScale, lupePixels * lupeScale)); lupeInfoLbl = new JLabel(" "); lupeInfoLbl.setFont(new Font("Monospaced",Font.PLAIN,10)); JPanel lupePnl = new JPanel(new BorderLayout(4,4)); lupePnl.setBorder(new EmptyBorder(4,4,4,4)); lupePnl.add(lupeGrpPnl,BorderLayout.CENTER); lupePnl.add(lupeInfoLbl,BorderLayout.SOUTH); lupeFrm.getContentPane().add(lupePnl); lupeFrm.pack(); lupeFrm.setResizable(false); mainFrm.getContentPane().add(mainPnl); mainFrm.setJMenuBar(mainMenu); mainFrm.pack(); mainFrm.setVisible(true); updateView(); } public static void main(final String[] args) { AceDrawProto4 myProg = new AceDrawProto4(); myProg.initProg(); myProg.makeFrame(); myProg.doProg(); } }
|