Undo Manager

Status
Nicht offen für weitere Antworten.
G

Guest

Gast
Hallo,
ich kämfe nun seit Tagen mit einer undo-funktion in einem Editor und komme einfach nicht auf einen
grünen Zweig.

Zunächst mal ne dumme Frage: Es muss Doch möglich sein egal welches Object ich "undo-en" möchte also für selbst erzeugte Objekte (z.B. spezielle Ellipsen in einem Editor) eine undo-Funktion zu generieren oder?

Ich weiß nicht wohin ich den undo-Manager klatschen soll. Eher in die Klasse die die Ellipsen darstellt oder dorthin wo der Editor vorhanden ist?

Mein code ist so aufgebaut:
Code:
public class c1 extends JPanel implements ActionListener {

//Im Konstruktor werden die Oberfläche gebaut also toolbar etc...
public  void actionPerformed {ActionEvent e) {
   //Hier stehen dann aufrufe von Funktionen/Klassen die eben z.B die speziellen Ellipsen erzeugen
   if(e.getSource() == toolBarButtonEllipse)
         menuItemEllipse();
}


private void menuItemEllipse() {
     view.setMouseInputHandler(new NewEllipseMouseInputHandler());
}


//Und hier die Klasse NewEllipseMouseInputHandler

protected class NewEllipseMouseInputHandler extends MouseAdapter implements MouseMotionListener {
     //hier kommen dann der Aufruf einer neuen Ellipse der Klasse Ellipse 
    //Hier befindet man sich also nur im MouseHandler.....
}

}


Ich weiß jetzt nicht ob das reicht so aber der code ist ziemlich groß....
im Moment bin ich etwas ratlos wohin ich denn ode wie ich ich den undoManager platzieren soll...

danke für jeden ratschlag[/code]
 

byte

Top Contributor
Guck Dir mal das Command-Pattern an. Damit kannst Du recht flexibel Undo-Funktionalität realisieren.
 

André Uhres

Top Contributor
Code:
//package undo;
import java.awt.*;
import java.awt.event.*;
import javax.swing.undo.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
/**
* The lunch applet presents the Lunch button, which, when invoked
* launches the main frame
 *
 *[url]http://www.javaworld.com/javaworld/jw-06-1998/jw-06-undoredo.html[/url]
*/
public class LunchApplet extends JApplet {
  //Initialize the applet
  public void init() {
       // set look & feel
     String laf = UIManager.getSystemLookAndFeelClassName();
     try {
	UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName() );
     } catch ( UnsupportedLookAndFeelException exc ) {
	System.err.println("Warning: UnsupportedLookAndFeel: " + laf);
     } catch (Exception exc) {
	System.err.println("Error loading " + laf + ": " + exc);
     }
     JButton lunchBtn = new JButton("Lunch");
     lunchBtn.addActionListener( new ActionListener () {
        public void actionPerformed( ActionEvent evt ) {
       	   UndoPanel  app = new UndoPanel();
   	   JFrame frame  = new JFrame();
   	   frame.getContentPane().add(app);
   	   frame.setSize(600,300);
   	   frame.setVisible(true);
     }});
     getContentPane().add(lunchBtn);
  }
  //Start the applet
  public void start() {
  }
  //Stop the applet
  public void stop() {
  }
  //Destroy the applet
  public void destroy() {
  }
}
/**
* The Add Edit class records the changes which occured to the
* list after performing an add action. The add edit supports
* undo / redo of add action.
*/
class AddEdit extends AbstractUndoableEdit {
  private Object element_;
  private int index_;
  private DefaultListModel model_;
  public AddEdit( DefaultListModel model, Object element, int index ) {
     model_=model;
     element_ = element;
     index_=index;
  }
  public void undo() throws CannotUndoException {
     model_.removeElementAt( index_ );
  }
  public void redo() throws CannotRedoException {
     model_.insertElementAt( element_, index_ );
  }
  public boolean canUndo() {
     return true;
  }
  public boolean canRedo() {
     return true;
  }
  public String getPresentationName() {
     return "Add";
  }
}
/**
* Same as AddEdit. The RemoveEdit records changes which
* occured after performing a remove action
*/
class RemoveEdit extends AbstractUndoableEdit {
   private Object element_;
   private int index_;
   private DefaultListModel model_;
   public RemoveEdit ( DefaultListModel model,Object element, int index ) {
    	model_ = model;
       	element_ = element;
       	index_=index;
   }
   public void undo() throws CannotUndoException {
       model_.insertElementAt( element_, index_);
   }
   public void redo() throws CannotRedoException {
   	model_.removeElementAt( index_);
   }
  public boolean canUndo() {
         return true;
  }
  public boolean canRedo() {
         return true;
  }
  public String getPresentationName() {
         return "Remove";
  }
}
/**
* The undo applet defines the undo / redo concept
* in swing. The applet allows you to add / remove
* objects to/from a list. It also supports undoing/
* redoing those operations
*/
class UndoPanel extends JPanel {
   JList elementList_;             // The list
   DefaultListModel elementModel_; // The list model
   JScrollPane scrollPane_;
   JButton addElementBtn_ ;
   JButton removeElementBtn_ ;
   JButton undoBtn_;
   JButton redoBtn_;
   int _lastElementID;
   /**
   * undo system elements
   */
   UndoManager undoManager_;         // history list
   UndoableEditSupport undoSupport_; // event support
   public UndoPanel() {
      elementModel_ = new DefaultListModel();
      elementList_ = new JList(elementModel_);
      scrollPane_ = new JScrollPane(elementList_);
      elementList_.addListSelectionListener(new ListSelectionAdapter());
      // create the actions
      Action addAction  = new AddAction();
      Action removeAction = new RemoveAction();
      Action undoAction = new UndoAction();
      Action redoAction = new RedoAction();
      // create the buttons and register the actions
      addElementBtn_ = new JButton("Add Foo");
      addElementBtn_.addActionListener(addAction);
      removeElementBtn_ = new JButton("remove Foo");
      removeElementBtn_.addActionListener(removeAction);
      removeElementBtn_.setEnabled(false);
      undoBtn_ = new JButton("undo");
      undoBtn_.addActionListener(undoAction);
      redoBtn_ = new JButton("redo");
      redoBtn_.addActionListener(redoAction);
      // create the undo / redo panel
      JPanel undoPanel = new JPanel();
      undoPanel.setLayout(new GridLayout(1,2));
      undoPanel.setBorder(
                  BorderFactory.createTitledBorder(
                  LineBorder.createBlackLineBorder(),
                  "Undo/ Redo",
                  TitledBorder.LEFT,
                  TitledBorder.TOP));
      undoPanel.add(undoBtn_);
      undoPanel.add(redoBtn_);
      // create the actions panel
      JPanel actionPanel = new JPanel();
      actionPanel.setLayout(new GridLayout(1,2));
      actionPanel.setBorder(
                  BorderFactory.createTitledBorder(
                  LineBorder.createBlackLineBorder(),
                  "Actions",
                  TitledBorder.LEFT,
                  TitledBorder.TOP));
      actionPanel.add(addElementBtn_);
      actionPanel.add(removeElementBtn_);
      // create the task panel
      JPanel taskPanel= new JPanel();
      taskPanel.setLayout(new GridLayout(1,2));
      taskPanel.add(actionPanel);
      taskPanel.add(undoPanel);
      taskPanel.setSize(100,100);
      // add the task panel to the content pane
      setLayout(new BorderLayout());
      add(BorderLayout.SOUTH,taskPanel);
      add(BorderLayout.CENTER,scrollPane_);
      // initilize the undo.redo system
      undoManager_= new UndoManager();
      undoSupport_ = new UndoableEditSupport();
      undoSupport_.addUndoableEditListener(new UndoAdapter());
      refreshUndoRedo();
  }
  /**
  * This method is called after each undoable operation
  * in order to refresh the presentation state of the
  * undo/redo GUI
  */
  public void refreshUndoRedo() {
     // refresh undo
     undoBtn_.setText( undoManager_.getUndoPresentationName() );
     undoBtn_.setEnabled( undoManager_.canUndo() );
     // refresh redo
     redoBtn_.setText( undoManager_.getRedoPresentationName() );
     redoBtn_.setEnabled( undoManager_.canRedo() );
  }
  /**
  * Add new element Action.
  */
  private class AddAction extends AbstractAction {
      public void actionPerformed(ActionEvent evt) {
          // always add to the end of the JList
          int NumOfElements = elementModel_.getSize();
          // however, give the the element is ID number
          Object element = new String("Foo " + _lastElementID);
          // record the effect
          UndoableEdit edit = new AddEdit(elementModel_,
                                     element, NumOfElements );
          // perform the operation
          elementModel_.addElement( element );
          // notify the listeners
          undoSupport_.postEdit( edit );
          // increment the ID
          _lastElementID ++ ;
     }
  }
  /**
  * The remove action
  */
  private class RemoveAction extends AbstractAction {
      public void actionPerformed( ActionEvent evt ) {
         int selectIdx = elementList_.getSelectedIndex();
         Object selectedElement = elementModel_.getElementAt( selectIdx );
         // create the edit
         UndoableEdit edit_ = new RemoveEdit( elementModel_,
                                     selectedElement, selectIdx );
         //perfrom the remove
         elementModel_.removeElementAt( selectIdx );
         // notify the listeners
       	 undoSupport_.postEdit( edit_ );
       	 //disable the remove button
       	 removeElementBtn_.setEnabled( false );
    }
  }
  /**
  *  undo action
  */
  private class UndoAction extends AbstractAction {
      public void actionPerformed( ActionEvent evt ) {
         undoManager_.undo();
    	 refreshUndoRedo();
      }
  }
  /**
  * inner class that defines the redo action
  */
  private class RedoAction extends AbstractAction {
     public void actionPerformed(ActionEvent evt ) {
     	undoManager_.redo();
     	refreshUndoRedo();
     }
  }
  /**
  * An undo/redo adpater. The adpater is notified when
  * an undo edit occur(e.g. add or remove from the list)
  * The adptor extract the edit from the event, add it
  * to the UndoManager, and refresh the GUI
  */
  private class UndoAdapter implements UndoableEditListener {
     public void undoableEditHappened (UndoableEditEvent evt) {
     	UndoableEdit edit = evt.getEdit();
     	undoManager_.addEdit( edit );
     	refreshUndoRedo();
     }
  }
  /**
  * The list selection adpater change the remove button state
  * according to the selection of the list
  */
  private class ListSelectionAdapter implements ListSelectionListener {
     public void valueChanged (ListSelectionEvent evt) {
     	if ( evt.getLastIndex() >= evt.getFirstIndex()) {
              removeElementBtn_.setEnabled(true);
        }
     }
  }
}
 
G

Guest

Gast
VIelen Dank für eure Ratschläge!

Ich habe mir alles angeschaut und bin dann auf die Idee eines Stacks gekommen aus dem ich dann popen kann und über ne EraseFunktion meinerseits alles realisieren kann. Es funktioniert!

Jetzt hab ich nur noch die Frage: Macht das so sinn? Ist das gut so? Professioneller wäre wohl die Verwendung des UndoMangers oder?

Danke euch!
 
G

Guest

Gast
Natürlich kann man damit NUR Objekte löschen aber keine Undo-Operationen an sich ausführen also z.B. wenn ein Objekt z.B verschoben wurde oder so....nehm ich jetzt mal schnell an...
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
GianaSisters Swing jTable Undo Problem. AWT, Swing, JavaFX & SWT 5
B AWT AWT und Undo - Redo AWT, Swing, JavaFX & SWT 8
S Undo/Redo..? AWT, Swing, JavaFX & SWT 3
T Grundsätzliche Frage zu undo/redo AWT, Swing, JavaFX & SWT 3
O JComboBox und Undo? AWT, Swing, JavaFX & SWT 2
S JComboBox -> undo Funktion hinzufügen! AWT, Swing, JavaFX & SWT 2
G Undo und Redo in Malprogramm AWT, Swing, JavaFX & SWT 4
R JTable und Undo AWT, Swing, JavaFX & SWT 3
D [Swing] Anordnung von Komponenten mit GridLayout Manager AWT, Swing, JavaFX & SWT 13
R Layout Manager null und Component wird nicht hinzugefügt AWT, Swing, JavaFX & SWT 3
A Layout-Manager, JScrollPane, ... Chaos AWT, Swing, JavaFX & SWT 5
D LayoutManager GUI skalieren und deren Komponenten mit Grid(Bag)Layout-Manager. AWT, Swing, JavaFX & SWT 5
M Passender Layout-Manager AWT, Swing, JavaFX & SWT 3
B Swing "Window Manager" - Gedankenprobleme AWT, Swing, JavaFX & SWT 9
R Welchen Layout Manager/ Wie strukturieren? AWT, Swing, JavaFX & SWT 14
P Swing welchen Layout Manager verwenden AWT, Swing, JavaFX & SWT 9
B Anderen Layout-Manager verwenden AWT, Swing, JavaFX & SWT 17
Furtano AWT mehrere Bilder in einen Frame zeichnen + Layout Manager AWT, Swing, JavaFX & SWT 10
J LayoutManager Welchen Layout/Design-Manager? AWT, Swing, JavaFX & SWT 4
A Problem mit Layout-Manager AWT, Swing, JavaFX & SWT 11
B Probleme mit Layout Manager (BoxLayout) AWT, Swing, JavaFX & SWT 4
S SWT Composite mit Layout Manager geht nicht AWT, Swing, JavaFX & SWT 4
A Welcher Layout Manager ist hier richtig? AWT, Swing, JavaFX & SWT 3
Luk10 Layout-Manager AWT, Swing, JavaFX & SWT 3
S LayoutManager Welcher Manager AWT, Swing, JavaFX & SWT 2
P Layout Manager oder manuell?? AWT, Swing, JavaFX & SWT 7
G Layout Manager AWT, Swing, JavaFX & SWT 5
Lazybone der Richtige Layout Manager AWT, Swing, JavaFX & SWT 2
M Welcher Layout Manager? AWT, Swing, JavaFX & SWT 5
I SWT Layout Manager und weiteres. AWT, Swing, JavaFX & SWT 6
R JFrame -- Variable Positionierung durch Window Manager? AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen


Oben