注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

千鸟

本blog所有日志均系原创 转载请注明出处

 
 
 

日志

 
 

undo/redo功能简单实现  

2007-03-26 14:30:11|  分类: J2SE |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

undo/redo 简单实现 

 

    LinkedList   //  在本例中用LinkedList来记录,需要显示出来的图形:Shape
    UndoableEdit // 系统类.所有需要重画的图形,都要用UndoableEdit包装起来,才能被 UndoManager.如:
          Shape temp = new Line2D.Double(0.0,0.0,Math.random()*100.0,Math.random()*100.0);
          UndoableEdit edit = new graphEdit(temp);
           
    UndoManager  // 系统类. 管理堆栈,将UndoableEdit作为元素.
         undo() :    撤消 最后加入的有效 UndoableEdit,以及它之后的所有无效编辑,将之放入redo的堆栈
         redo()  :   恢复最后撤消的 UndoableEdit,以及它之前的所有无效编辑,将之放入redo的堆栈

UndoManager源代码,颇简单.查看UndoManager 源代码发现 继承自CompoundEdit.用 Vector edits做堆栈记录,加入的元素是UndoableEdit.它的undo(), 获得堆栈顶部的edit,然后调用undoTo(edit),获得edit的再调用edit.undo();


    UndoListener //  实现ActionListener接口.在本例中处理Undo事件.调用UndoManager的Undo()方法.
    调用最后一个Shape的Undo()方法. 本例中执行的是.从LinkedList中移走Shape.再调用重画,就使画面实现了 撤消最后一个编辑动作(在本例中是Shape).

    RedoListener //  实现ActionListener接口.在本例中处理Redo事件.调用UndoListener相似.

 

   

   图为undo后,新画了个圆 

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.net.*;
import java.applet.*;
import java.util.LinkedList;
import java.util.Iterator;
import javax.swing.*;
import javax.swing.undo.*;
/**
 * A very simple applet demonstrating usage of javax.swing.undo package.
 */
public class undomgrtest extends JApplet {

    JButton linebutton;
    JButton circlebutton;
    JButton undobutton;
    JButton redobutton;
    JPanel buttonpanel;
    JGraphPanel graphpanel;
    LineListener linelistener;
    CircleListener circlelistener;
    UndoListener undolistener;
    RedoListener redolistener;
    LinkedList shapes;
    UndoManager undomgr;

    public void init() {

 // Force SwingApplet to come up in the System L&F
 String laf = UIManager.getSystemLookAndFeelClassName();
 try {
     UIManager.setLookAndFeel(laf);
     // If you want the Cross Platform L&F instead, comment out the above line and
     // uncomment the following:
     // UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
 } catch (UnsupportedLookAndFeelException exc) {
     System.err.println("Warning: UnsupportedLookAndFeel: " + laf);
 } catch (Exception exc) {
     System.err.println("Error loading " + laf + ": " + exc);
 }

        getContentPane().setLayout(new BorderLayout());
        linebutton = new JButton("Draw Line");
 circlebutton = new JButton("Draw Circle");
 undobutton = new JButton("Undo");
 redobutton = new JButton("Redo");
 graphpanel = new JGraphPanel(false);
 graphpanel.setPreferredSize(new Dimension(300,300));
 buttonpanel = new JPanel(false);
 buttonpanel.setLayout(new FlowLayout());
 buttonpanel.add(linebutton);
        buttonpanel.add(circlebutton);
 buttonpanel.add(undobutton);
 buttonpanel.add(redobutton);
 getContentPane().add(buttonpanel,BorderLayout.SOUTH);
 getContentPane().add(graphpanel,BorderLayout.NORTH);
 linelistener = new LineListener();
 linebutton.addActionListener(linelistener);
 circlelistener = new CircleListener();
 circlebutton.addActionListener(circlelistener);
 undolistener = new UndoListener();
 undobutton.addActionListener(undolistener);
 redolistener = new RedoListener();
 redobutton.addActionListener(redolistener);
 shapes = new LinkedList();
 undomgr = new UndoManager();
    }

    public void stop() {

    }
    class JGraphPanel extends JPanel{
 public JGraphPanel(boolean doublebuffer)
 {
     super(doublebuffer);
 }
 public void paintComponent(Graphics g) {
     Graphics2D g2 = (Graphics2D)g;
     g2.setColor(Color.white);
     g2.fill3DRect(0,0,getWidth(),getHeight(),true);
     Iterator it;
     Shape shape;
     g2.setColor(Color.black);
     for(it = shapes.iterator();it.hasNext();){
  shape = (Shape)it.next();
  g2.draw(shape);
  g2.drawString("goood/nggod",0,0);
     }
 }
    }
    class LineListener implements ActionListener{
 Shape temp;
 public void actionPerformed(ActionEvent e){
     temp = new Line2D.Double(0.0,0.0,Math.random()*100.0,Math.random()*100.0);
     shapes.add(temp);
     repaint();
     UndoableEdit edit = new graphEdit(temp);
     undomgr.addEdit(edit);
 }
    }
    class CircleListener implements ActionListener{
 Shape temp;
 public void actionPerformed(ActionEvent e){
     temp = new Ellipse2D.Double(100.0,100.0,Math.random()*100.0,Math.random()*100.0);
     shapes.add(temp);
     repaint();
     UndoableEdit edit = new graphEdit(temp);
     undomgr.addEdit(edit);

 }
    }
    class UndoListener implements ActionListener{
 public void actionPerformed(ActionEvent e){
     try{
  undomgr.undo();
  repaint();
     }catch(CannotUndoException ex){
  System.err.println("Can't Undo More");
     }
 }
    }
    class RedoListener implements ActionListener{
 public void actionPerformed(ActionEvent e){
     try{
  undomgr.redo();
  repaint();
     }catch(CannotRedoException ex){
  System.err.println("Can't Redo More");
     }
 }
    }

    class graphEdit extends AbstractUndoableEdit{
 Shape shape;
 public graphEdit(Shape _shape){
     shape = _shape;
 }
 public void undo(){
     shapes.remove(shape);
     //repaint();
     System.out.println("undo draw line");
 }
 public void redo(){
     shapes.add(shape);
    // repaint();
     System.out.println("redo draw line");
 }
    }
}

 

  评论这张
 
阅读(1223)| 评论(1)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017