不知道以前有没有发过,最近改了一下,还有一点缺点。但是己经很好了

  1import java.awt.*;
  2import java.awt.event.*;
  3import java.awt.image.BufferedImage;
  4import java.awt.image.ImageObserver;
  5import java.io.File;
  6import java.util.*;
  7
  8import javax.swing.*;
  9import javax.swing.filechooser.FileFilter;
 10import javax.swing.text.*;
 11
 12//做复杂了,有空再搞一个
 13public class PictureCombine extends JFrame {
 14    private static final long serialVersionUID = 4471162236312833978L;
 15
 16    private final int winw, winh, maxw, maxh; // 屏幕长宽
 17
 18    private int cols, rows/*, tw, th, w, h*/;// 拼图的行列数与原图总长宽及每一小块图的长宽
 19    private double tw, th, w, h;
 20
 21    //    private int tw, th, w, h; // 画出的总长宽及一小块长宽
 22
 23    private int curcol, currow;
 24
 25    private Container c;
 26
 27    JTextField col, row;
 28
 29    JButton open, close, start, confusion, restart, look;
 30
 31    JLabel rowlabel = new JLabel ("行数"), collabel = new JLabel ("列数");
 32
 33    public Image img;
 34
 35    public static BufferedImage bufferimg;
 36
 37    public static PictureCombine picture_combine_;
 38
 39    File choosingPath_;
 40
 41    Canvas canvas;
 42
 43    Graphics bufferg;
 44
 45    int[][] imgdata;
 46
 47    static boolean hasstart = false, islook = false;
 48    MyKeyListener keyListener_ = new MyKeyListener();
 49    MyMouseListener mouseListener_ = new MyMouseListener();
 50    private JDialog aboutDlg_;
 51    
 52
 53    public PictureCombine() {
 54        super ("画图");
 55        winw = Toolkit.getDefaultToolkit().getScreenSize().width;
 56        winh = Toolkit.getDefaultToolkit().getScreenSize().height;
 57        cols = 3;
 58        rows = 3;
 59        col = new JTextField ("3");
 60        row = new JTextField ("3");
 61        col.setColumns (2);
 62        row.setColumns (2);
 63        open = new JButton ("打开新图");
 64        start = new JButton ("开始");
 65        restart = new JButton ("重新开始");
 66        confusion = new JButton ("打乱");
 67        look = new JButton ("查看原图");
 68        close = new JButton ("退出");
 69        JButton about = new JButton ("游戏说明");
 70        setDefaultCloseOperation (EXIT_ON_CLOSE);
 71        setUndecorated (true);
 72        c = getContentPane();
 73        c.setLayout (new BorderLayout());
 74        // setBounds (winw / 2 - 200, winh / 2 - 150, 400, 300);
 75        setBounds (00, winw, winh);
 76        JPanel panel = new JPanel();
 77        panel.setLayout (new FlowLayout());
 78        panel.add (rowlabel);
 79        panel.add (row);
 80        panel.add (collabel);
 81        panel.add (col);
 82        panel.add (open);
 83        panel.add (start);
 84        panel.add (restart);
 85        panel.add (confusion);
 86        panel.add (look);
 87        panel.add (close);
 88        panel.add(about);
 89        close.addActionListener (new ActionListener() {
 90            public void actionPerformed (ActionEvent e) {
 91                System.exit (0);
 92            }

 93        }
);
 94        open.addActionListener (new ActionListener() {
 95            public void actionPerformed (ActionEvent e) {
 96                browse();
 97                canvas.requestFocus();
 98            }

 99        }
);
100        start.addActionListener (new ActionListener() {
101            public void actionPerformed (ActionEvent e) {
102                startmethod();
103                canvas.setEnabled(true);
104                canvas.requestFocus();
105            }

106        }
);
107        restart.addActionListener (new ActionListener() {
108            public void actionPerformed (ActionEvent e) {
109                start.setEnabled (true);
110                col.setEnabled (true);
111                row.setEnabled (true);
112                confusion.setEnabled (false);
113                restart.setEnabled (false);
114                look.setEnabled (false);
115                canvas.setEnabled(false);
116                canvas.requestFocus();
117            }

118        }
);
119        confusion.addActionListener (new ActionListener() {
120            public void actionPerformed (ActionEvent e) {
121                radomnum();
122                drawbufferedimage();
123                canvas.requestFocus();
124            }

125        }
);
126        look.addActionListener (new ActionListener() {
127            public void actionPerformed (ActionEvent e) {
128                if (islook) {
129                    confusion.setEnabled (true);
130                    restart.setEnabled (true);
131                    look.setText ("查看原图");
132                    islook = false;
133                    canvas.paint (canvas.getGraphics());
134                    canvas.addKeyListener (keyListener_);
135                    canvas.addMouseListener (mouseListener_);
136                }
 else {
137                    confusion.setEnabled (false);
138                    restart.setEnabled (false);
139                    look.setText ("回到拼图");
140                    islook = true;
141                    canvas.paint (canvas.getGraphics());
142                    canvas.removeKeyListener(keyListener_);
143                    canvas.removeMouseListener(mouseListener_);
144                }

145                canvas.requestFocus();
146            }

147        }
);
148        about.addActionListener (new ActionListener() {
149            public void actionPerformed (ActionEvent e) {
150                if (aboutDlg_ == null{
151                    aboutDlg_ = new JDialog(PictureCombine.this"游戏说明"true);
152                    aboutDlg_.setSize(500400);
153                    aboutDlg_.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
154                    addKeyboardActionEscapExitHide(aboutDlg_);
155                    {
156                        JPanel panel = new JPanel();
157                        panel.setLayout(new BorderLayout());
158                        {
159                            String textAbout = "<html><br>游戏说明 ( 程序版本:1.0 )<br></html>";
160                            JLabel label = new JLabel(textAbout);
161                            label.setHorizontalAlignment(JLabel.CENTER);
162                            panel.add(label, BorderLayout.NORTH);
163                        }

164                        {
165                            JTextArea area = new JTextArea(2030);
166                            String textAbout = "  在开始游戏前,可先设置要把图片分成几行几列(3-9),如未设置刚默认设为3行3列。\n\n" +
167                                    "  “打开新图” 即选择一幅新的图片,以供游戏。\n\n" +
168                                    "  “开始”   在选择了图片后进行游戏。\n\n" +
169                                    "  “重新开始” 点击后可以重新选取图片,设置行数与列数。\n\n" +
170                                    "  “打乱”   把图片打乱,可以多次打乱。\n\n" +
171                                    "  “查看原图” 与“回到拼图”在拼图与原图点切换。\n\n" +
172                                    "  “退出”   离开并关闭游戏。\n\n\n" +
173                                    "                     Make by 沉思的狗 2007-07-30";
174                            area.setBorder(BorderFactory.createEmptyBorder(5555));
175                            area.setText(textAbout);
176                            area.setAutoscrolls(true);
177                            area.setEditable(false);
178                            area.setBackground(aboutDlg_.getBackground());
179                            area.setLineWrap(true);
180                            JScrollPane scrollpanel = new JScrollPane(area);
181                            scrollpanel.setBorder(BorderFactory.createEmptyBorder(0000));
182                            scrollpanel.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
183                            panel.add(scrollpanel, BorderLayout.CENTER);
184                        }

185                        aboutDlg_.getContentPane().add(panel);
186                    }

187
188                }

189                aboutDlg_.setLocationRelativeTo(PictureCombine.this);
190                aboutDlg_.setResizable(false);
191                aboutDlg_.show();
192                aboutDlg_.toFront();
193            }

194        }
);
195        start.setEnabled (false);
196        restart.setEnabled (false);
197        confusion.setEnabled (false);
198        look.setEnabled (false);
199        c.add (panel, BorderLayout.SOUTH);
200        canvas = new MyCanvas();
201        JPanel panelc = new JPanel();
202        panelc.add (canvas);
203        maxw = winw;
204        maxh = winh - 50;
205        canvas.setSize (maxw, maxh);
206        panelc.setPreferredSize (new Dimension (maxw, maxh));
207        c.add (panelc, BorderLayout.CENTER);
208        // System.out.println (maxw + " * " + maxh);
209        // addKeyListener (new MyKeyListener());
210        setVisible (true);
211        addKeyListener (new KeyListener() {
212            public void keyTyped (KeyEvent e) {
213                canvas.requestFocus();
214            }

215
216            public void keyPressed (KeyEvent e) {
217                canvas.requestFocus();
218            }

219
220            public void keyReleased (KeyEvent e) {
221                canvas.requestFocus();
222            }

223        }
);
224        KeyListener keyL = new KeyListener() {
225            public void keyTyped (KeyEvent e) {
226                if (isDirectKey(e))
227                    canvas.requestFocus();
228            }

229
230            public void keyPressed (KeyEvent e) {
231                if (isDirectKey(e))
232                    canvas.requestFocus();
233            }

234
235            public void keyReleased (KeyEvent e) {
236                if (isDirectKey(e))
237                    canvas.requestFocus();
238            }

239        }
;
240        KeyListener keyLUpDown = new KeyListener() {
241            public void keyTyped (KeyEvent e) {
242                keyUpDownForColRow(e);
243            }

244
245            public void keyPressed (KeyEvent e) {
246                keyUpDownForColRow(e);
247            }

248
249            public void keyReleased (KeyEvent e) {
250                //keyUpDownForColRow(e);
251            }

252        }
;
253        row.addKeyListener(keyL);
254        col.addKeyListener(keyL);
255        row.setDocument(new TextDocument());
256        col.setDocument(new TextDocument());
257        row.addKeyListener(keyLUpDown);
258        col.addKeyListener(keyLUpDown);
259        row.setCaretColor(Color.lightGray);
260        col.setCaretColor(Color.lightGray);
261        row.setText("3");
262        col.setText("3");
263        close.addKeyListener(keyL);
264        open.addKeyListener(keyL);
265        start.addKeyListener(keyL);
266        restart.addKeyListener(keyL);
267        confusion.addKeyListener(keyL);
268        look.addKeyListener(keyL);
269        about.addKeyListener(keyL);
270    }

271    
272    private void keyUpDownForColRow(KeyEvent e) {
273        switch(e.getKeyCode()) {
274        case KeyEvent.VK_UP:
275        case KeyEvent.VK_DOWN:
276        case KeyEvent.VK_LEFT:
277        case KeyEvent.VK_RIGHT:
278            JTextField field = (JTextField)e.getSource();
279            int num = 3;
280            try {
281                num = Integer.parseInt(field.getText());
282            }
 catch (Exception exp) {
283                return;
284            }

285            if (e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_LEFT) {
286                if (num > 3{
287                    field.setText(Integer.toString(--num));
288                }

289            }
 else {
290                if (num < 9{
291                    field.setText(Integer.toString(++num));
292                }

293            }

294            break;
295        default:
296            break;
297    }

298    }

299    private boolean isDirectKey(KeyEvent e) {
300        switch(e.getKeyCode()) {
301            case KeyEvent.VK_UP:
302            case KeyEvent.VK_W:
303            case KeyEvent.VK_DOWN:
304            case KeyEvent.VK_S:
305            case KeyEvent.VK_LEFT:
306            case KeyEvent.VK_A:
307            case KeyEvent.VK_RIGHT:
308            case KeyEvent.VK_D:
309                return true;
310            default:
311                return false;
312        }

313    }

314
315    public static PictureCombine getInstance() {
316        if (picture_combine_ == null{
317            picture_combine_ = new PictureCombine();
318        }

319        return picture_combine_;
320    }

321
322    public static void main (String[] args) {
323        // JFrame f = new picture_combine();
324        JFrame f = PictureCombine.getInstance();
325        f.setVisible (true);
326    }

327
328    protected void startmethod() {
329        // 打乱图的顺序
330
331        try {
332            cols = Integer.parseInt (col.getText());
333            rows = Integer.parseInt (row.getText());
334        }
 catch (Exception e) {
335            cols = rows = 3;
336        }
 finally {
337            if (cols > 10{
338                cols = 9;
339            }
else if (cols < 3{
340                cols = 3;
341            }

342            if (rows > 10{
343                rows = 9;
344            }
else if (rows < 3{
345                rows = 3;
346            }

347            col.setText ("" + cols);
348            row.setText ("" + rows);
349            double tem = (cols + 2.0/ cols;
350            if ( (tw * tem) > (double) maxw) {
351//                int tw1 = (int) Math.round (maxw / tem);
352//                int th1 = (int) Math.round (th / tem);
353                double tw1 = maxw / tem;
354                double th1 = th / tem;
355                Image imgtemp = getBufferedImage (tw, th, BufferedImage.TYPE_4BYTE_ABGR);
356                drawImage (imgtemp.getGraphics(), img, 00, tw1, th1, 00, tw, th, null);
357                img = imgtemp;
358                tw = tw1;
359                th = th1;
360            }

361            w = tw / cols;
362            h = th / rows;
363            imgdata = new int[rows][cols + 1];
364            hasstart = true;
365            canvas.getGraphics().clearRect (00, maxw, maxh);
366            radomnum();
367            drawbufferedimage();
368            col.setEnabled (false);
369            row.setEnabled (false);
370            start.setEnabled (false);
371            restart.setEnabled (true);
372            confusion.setEnabled (true);
373            look.setEnabled (true);
374            islook = false;
375            canvas.setEnabled (true);
376            currow = rows - 1;
377            curcol = cols - 1;
378            canvas.repaint();
379            canvas.requestFocus();
380        }

381    }

382
383    private void radomnum() {
384        boolean canBeCombined = false;
385        boolean flag = true;
386        int tem;
387        Random r = new Random(Calendar.getInstance().getTimeInMillis());
388        imgdata[rows - 1][cols] = rows * cols - 1;
389        while (!canBeCombined) {
390            for (int i = 0; i < rows; i++{
391                for (int k = 0; k < cols; k++{
392                    if (i == rows - 1 && k == cols - 1{
393                        imgdata[rows - 1][cols - 1= -1;
394                        curcol = cols - 1;
395                        currow = rows - 1;
396                        break;
397                    }

398                    while (flag) {
399                        tem = r.nextInt (cols * rows - 1);
400                        loop1: for (int i1 = 0; i1 <= i; i1++{
401                            for (int k1 = 0; k1 < cols; k1++{
402                                if (i1 == i && k1 >= k)
403                                    break loop1;
404                                flag = flag && (tem != imgdata[i1][k1]);
405                            }

406                        }

407                        if (flag) {
408                            imgdata[i][k] = tem;
409                            flag = false;
410                        }
 else {
411                            flag = true;
412                        }

413                    }

414                    flag = true;
415                }

416            }

417            int sum = 0;    //只有sum为偶数时才可以拼回原图 sum = SUM ( L (i) ) + J + K
418                            //L (i)是表示从第i+1号格子到第16号格子中比第i号格子的数字要小的个数
419                            //空格是在第J列第K行
420            sum += curcol;
421            sum += currow;
422            for (int i = 0; i < rows; i++{
423                for (int k = 0; k < cols; k++{
424                    for (int now = i * cols + k; now < cols * rows - 2; now++{
425                        int nowrow = now / cols;
426                        int nowcol = now % cols;
427                        if (imgdata[nowrow][nowcol] < imgdata[i][k]) {
428                            sum++;
429                        }

430                    }

431                }

432            }

433            if (sum % 2 == 1{
434                canBeCombined = true;
435            }

436        }

437    }

438
439    private void drawbufferedimage() {
440        // bufferimg = getBufferedImage (tw, th,
441        // BufferedImage.TYPE_4BYTE_ABGR);
442        bufferg = bufferimg.getGraphics();
443        clearRect (bufferg, 00, tw, th);
444        int k1, i1;
445        for (int i = 0; i < rows; i++{
446            for (int k = 0; k < cols; k++{
447                if (imgdata[i][k] == -1{
448                    fillRect (bufferg, w * k, h * i, w + 1, h + 1);
449                }
 else {
450                    i1 = imgdata[i][k] / cols;
451                    k1 = imgdata[i][k] % cols;
452                    drawImage (bufferg, img, w * k, h * i, w * k + w, h * i + h,
453                            w * k1, h * i1, w * k1 + w, h * i1 + h, null);
454                }

455            }

456        }

457        canvas.paint (canvas.getGraphics());
458    }

459
460    protected boolean browse() {
461        JFileChooser chooser = new JFileChooser (choosingPath_);
462
463         {
464            ConfigFileFilter filter = new ConfigFileFilter();
465            chooser.setFileFilter (filter);
466            chooser.setAcceptAllFileFilterUsed (false);
467            chooser.setDialogTitle ("选择图像");
468        }

469        int ret = chooser.showOpenDialog (this);
470        if (ret == JFileChooser.APPROVE_OPTION) {
471            choosingPath_ = chooser.getCurrentDirectory();
472            ImageIcon ii;
473            try {
474                ii = new ImageIcon (chooser.getSelectedFile().getAbsolutePath());
475            }
 catch (Exception e) {
476                return false;
477            }

478            Image imgtemp = ii.getImage();
479            if (imgtemp.getWidth (this<= maxw
480                    && imgtemp.getHeight (this<= maxh) {
481                tw = imgtemp.getWidth (this);
482                th = imgtemp.getHeight (this);
483                img = getBufferedImage (tw, th, BufferedImage.TYPE_4BYTE_ABGR);
484            }
 else {
485                double bw = (imgtemp.getWidth (this+ 0.0/ (maxw + 0.0);
486                double bh = (imgtemp.getHeight (this+ 0.0/ (maxh + 0.0);
487                if (bw >= bh) {
488                    tw = maxw;
489                    th = (int) Math.round ( (float) (imgtemp.getHeight (this+ 0.0/ bw);
490                }
 else {
491                    th = maxh;
492                    tw = (int) Math.round ( (float) (imgtemp.getWidth (this+ 0.0/ bh);
493                }

494            }

495            img = getBufferedImage (tw, th, BufferedImage.TYPE_4BYTE_ABGR);
496            drawImage (img.getGraphics(), imgtemp, 00, tw, th, 00,
497                    imgtemp.getWidth (this), imgtemp.getHeight (this), null);
498            bufferimg = getBufferedImage (tw, th, BufferedImage.TYPE_4BYTE_ABGR);
499            bufferg = bufferimg.getGraphics();
500            drawImage (bufferg, img, 00, tw, th, 00, tw, th, null);
501            canvas.repaint();
502            hasstart = false;
503            start.setEnabled (true);
504            restart.setEnabled (false);
505            confusion.setEnabled (false);
506            look.setText("查看原图");
507            look.setEnabled(false);
508            col.setEnabled (true);
509            row.setEnabled (true);
510        }

511        return true;
512    }

513    
514    private class TextDocument extends PlainDocument {
515        private static final long serialVersionUID = -7485623800986543697L;
516        private final char[] authchar = {'3''4''5''6''7''8''9'};
517
518        public void insertString(int offs, String str, AttributeSet a)
519                                             throws BadLocationException {
520            if ((getLength() + str.length()) > 1{
521                return;
522            }

523
524            char[] source = str.toCharArray();
525            char[] result = new char[source.length];
526            int j = 0;
527
528            for (int i = 0; i < result.length; i++{
529                if (0 <= Arrays.binarySearch(authchar, source[i])) {
530                    result[j++= source[i];
531                }
 else {
532                    
533                }

534            }

535            super.insertString(offs, new String(result, 0, j), a);     
536        }

537    }

538
539    private static class ConfigFileFilter extends FileFilter {
540
541        public String getDescription() {
542            return "图像文件——*.jpg;*.gif;*.bmp";
543        }

544
545        public boolean accept (File f) {
546            if (f != null{
547                if (f.isDirectory())
548                    return true;
549                String filename = f.getName().toLowerCase();
550                if (filename.endsWith (".jpg"|| filename.endsWith (".gif")
551                        || filename.endsWith (".bmp")) {
552                    return true;
553                }

554            }

555            return false;
556        }

557    }

558
559    class MyCanvas extends Canvas {
560        private static final long serialVersionUID = -2277597023033712620L;
561
562        MyCanvas() {
563            super();
564            addKeyListener (keyListener_);
565            addMouseListener (mouseListener_);
566        }

567
568        public void paint (Graphics g) {
569            // g.setColor (Color.yellow);
570            if (!islook) {
571                drawImage (g, bufferimg, (maxw - tw) / 2, (maxh - th) / 2,
572                         (maxw + tw) / 2, (maxh + th) / 200, tw, th, this);
573                if (PictureCombine.hasstart) {
574                    if (imgdata[rows - 1][cols] == -1{
575                        g.setColor (Color.WHITE);
576                        fillRect (g, (maxw + tw) / 2, (maxh + th) / 2 - h, w, h);
577                    }
 else {
578                        drawImage (g, img, (maxw + tw) / 2, (maxh + th) / 2 - h,
579                                 (maxw + tw) / 2 + w, (maxh + th) / 2, w * cols
580                                        - w, h * rows - h, w * cols, h * rows,
581                                this);
582                    }

583                }

584            }
 else {
585                clearRect (g, (maxw + tw) / 2, (maxh + th) / 2 - h, w, h);
586                drawImage (g, img, (maxw - tw) / 2, (maxh - th) / 2,
587                         (maxw + tw) / 2, (maxh + th) / 200, tw, th, this);
588            }

589        }

590    }

591    
592    class MyMouseListener extends MouseAdapter {
593
594        public void mouseReleased (MouseEvent e) {
595            Point p = e.getPoint();
596            try {
597                Robot robot = new Robot();
598                Rectangle r = getRectangle ( (maxw - tw) / 2 + w
599                        * curcol, (maxh - th) / 2 + h * currow - h, w,
600                        h);
601                if (r.contains (p)) {
602                    robot.keyPress (KeyEvent.VK_S);
603                    robot.keyRelease (KeyEvent.VK_S);
604                }

605                r = getRectangle ( (maxw - tw) / 2 + w * curcol,
606                         (maxh - th) / 2 + h * currow + h, w, h);
607                if (r.contains (p)) {
608                    robot.keyPress (KeyEvent.VK_W);
609                    robot.keyRelease (KeyEvent.VK_W);
610                }

611                r = getRectangle ( (maxw - tw) / 2 + w * curcol - w,
612                         (maxh - th) / 2 + h * currow, w, h);
613                if (r.contains (p)) {
614                    robot.keyPress (KeyEvent.VK_D);
615                    robot.keyRelease (KeyEvent.VK_D);
616                }

617                r = getRectangle ( (maxw - tw) / 2 + w * curcol + w,
618                         (maxh - th) / 2 + h * currow, w, h);
619                if (r.contains (p)) {
620                    robot.keyPress (KeyEvent.VK_A);
621                    robot.keyRelease (KeyEvent.VK_A);
622                }

623            }
 catch (Exception ee) {
624            }

625        }

626    
627    }

628
629    class MyKeyListener implements KeyListener {
630
631        public void keyTyped (KeyEvent e) {
632
633        }

634
635        public void keyPressed (KeyEvent e) {
636
637        }

638
639        public void keyReleased (KeyEvent e) {
640            if (hasstart) {
641                boolean flag = false;
642                switch (e.getKeyCode()) {
643                case KeyEvent.VK_UP:
644                case KeyEvent.VK_W:
645                    if (currow == rows - 1
646                            || (currow == rows - 1 && curcol == cols))
647                        break;
648                    imgdata[currow][curcol] = imgdata[currow + 1][curcol];
649                    imgdata[currow + 1][curcol] = -1;
650                    currow++;
651                    flag = true;
652                    break;
653                case KeyEvent.VK_DOWN:
654                case KeyEvent.VK_S:
655                    if (currow == 0 || (currow == rows - 1 && curcol == cols))
656                        break;
657                    imgdata[currow][curcol] = imgdata[currow - 1][curcol];
658                    imgdata[currow - 1][curcol] = -1;
659                    currow--;
660                    flag = true;
661                    break;
662                case KeyEvent.VK_LEFT:
663                case KeyEvent.VK_A:
664                    if (currow == rows - 1 && curcol == cols - 1{
665                        imgdata[currow][curcol] = imgdata[currow][curcol + 1];
666                        imgdata[currow][curcol + 1= -1;
667                        curcol++;
668                        boolean ok = true;
669                        for (int i = 0; i < rows; i++{
670                            for (int k = 0; k < rows; k++{
671                                ok = ok && (imgdata[i][k] == i * cols + k);
672                            }

673                        }

674                        drawbufferedimage();
675                        if (ok) {
676                            start.setEnabled (true);
677                            col.setEnabled (true);
678                            row.setEnabled (true);
679                            canvas.setEnabled (false);
680                            restart.setEnabled (false);
681                            confusion.setEnabled (false);
682                            look.setEnabled (false);
683                            JOptionPane.showMessageDialog (null"恭喜您,您完成了这幅图!",
684                                    "完成", JOptionPane.INFORMATION_MESSAGE);
685                        }

686                        break;
687                    }

688                    if (curcol >= cols - 1)
689                        break;
690                    imgdata[currow][curcol] = imgdata[currow][curcol + 1];
691                    imgdata[currow][curcol + 1= -1;
692                    curcol++;
693                    flag = true;
694                    break;
695                case KeyEvent.VK_RIGHT:
696                case KeyEvent.VK_D:
697                    if (currow == rows - 1 && curcol == cols) {
698                        imgdata[currow][curcol] = imgdata[currow][curcol - 1];
699                        imgdata[currow][curcol - 1= -1;
700                        curcol--;
701                        drawbufferedimage();
702                        break;
703                    }

704                    if (curcol == 0)
705                        break;
706                    imgdata[currow][curcol] = imgdata[currow][curcol - 1];
707                    imgdata[currow][curcol - 1= -1;
708                    curcol--;
709                    flag = true;
710                    break;
711                case KeyEvent.VK_TAB:
712                    canvas.requestFocus();
713                    break;
714                default:
715                    canvas.requestFocus();
716                    break;
717                }

718                if (flag) {
719                    drawbufferedimage();
720                }

721            }

722        }

723    }

724    
725    private void fillRect(Graphics g, double x, double y, double width, double height) {
726        fillRect(g, (int)x, (int)y, (int)width, (int)height);
727    }

728    private void fillRect(Graphics g, int x, int y, int width, int height) {
729        g.fillRect(x, y, width, height);
730    }

731    
732    private void clearRect(Graphics g, double x, double y, double width, double height) {
733        clearRect(g, (int)x, (int)y, (int)width, (int)height);
734    }

735    private void clearRect(Graphics g, int x, int y, int width, int height) {
736        g.clearRect(x, y, width, height);
737    }

738    
739    private void drawImage(Graphics g, Image img, double dx1, double dy1, double dx2, double dy2, 
740            double sx1, double sy1, double sx2, double sy2, ImageObserver observer) {
741        drawImage(g, img, (int)dx1, (int)dy1, (int)dx2, (int)dy2, (int)sx1, (int)sy1, (int)sx2, (int)sy2, observer);
742    }

743    private void drawImage(Graphics g, Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) {
744        g.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer);
745    }

746    
747    private BufferedImage getBufferedImage(double width, double height, int imageType) {
748        return getBufferedImage((int)width, (int)height, imageType);
749    }

750    private BufferedImage getBufferedImage(int width, int height, int imageType) {
751        return new BufferedImage (width, height, imageType);
752    }

753    
754    private Rectangle getRectangle(double x, double y, double width, double height) {
755        return getRectangle((int)x, (int)y, (int)width, (int)height);
756    }

757    private Rectangle getRectangle(int x, int y, int width, int height) {
758        return new Rectangle(x, y, width, height);
759    }

760    /**
761     * <p>After call this function, when you putdown ESCAPE button, the Window will be hide.</p>
762     * @param compnemt RootPaneContainer (now can be JApplet, JDialog, JFrame, JInternalFrame, JWindow)
763     * @return true if success, else return false.
764     */

765    public boolean addKeyboardActionEscapExitHide(RootPaneContainer compnemt) {
766        KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
767        Action action = new AbstractAction(){
768            private static final long serialVersionUID = -1527956543338809497L;
769            public void actionPerformed(ActionEvent e) {
770                Object obj = e.getSource();
771                if (obj instanceof Component) {
772                    Component comp = (Component)obj;
773                    while (comp != null{
774                        if (comp instanceof Window || comp instanceof JInternalFrame || comp instanceof JApplet) {
775                            comp.setVisible(false);
776                            break;
777                        }

778                        comp = comp.getParent();
779                    }

780                }

781            }

782        }
;
783        return addKeyboardAction(compnemt, keyStroke, "DogActionMapKey_EscapExitHide", action, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
784    }

785    
786    /**
787     * <p>快捷键.</p>
788     * @param condition one of (JComponent.WHEN_FOCUSED | JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT | JComponent.WHEN_IN_FOCUSED_WINDOW)
789     * @return true if success, else return false.
790     */

791    public boolean addKeyboardAction(RootPaneContainer compnemt, KeyStroke keyStroke, String actionMapKey, Action action, int condition) {
792        if (compnemt == null || keyStroke == null || actionMapKey == null || action == null{
793            return false;
794        }

795        JRootPane rootPane = compnemt.getRootPane();
796        if (rootPane != null{
797            try {
798                rootPane.getInputMap(condition).put(keyStroke, actionMapKey);
799                rootPane.getActionMap().put(actionMapKey, action);
800                return true;
801            }
 catch (Exception e) {
802                return false;
803            }

804        }

805        return false;
806    }

807}

808