2012-07-17 6 views
10

मैंने एक एक्सएमएल संपादक बनाया है और मैं अंतिम चरण में फंस गया हूं: पूर्ववत/फिर से कार्यक्षमता जोड़ना।जावा में कार्रवाइयों के लिए मैं एक सरल पूर्ववत/फिर से कैसे कार्यान्वित करूं?

जब उपयोगकर्ता JTree को तत्व, विशेषताओं या टेक्स्ट जोड़ते हैं तो मुझे केवल पूर्ववत/फिर से जोड़ना होगा।

मैं अभी भी इस पर काफी नया हूं लेकिन स्कूल में आज मैंने दो स्टैक ऑब्जेक्ट [] को पूर्ववत और फिर से नामित करने और उनमें किए गए कार्यों को जोड़ने के लिए प्रयास किया (असफल)।

उदाहरण के लिए, मेरे पास है:

Action AddElement() { 

// some code 
public void actionPerformed(ActionEvent e) { 

        performElementAction(); 
       } 
} 

performElementAction सिर्फ वास्तव में JTree के लिए एक तत्व कहते हैं।

मैं इस क्रिया को मेरे पूर्ववत स्टैक में जोड़ने के लिए एक तरीका जोड़ना चाहता हूं। क्या सिर्फ undo.push (पूरी कार्रवाई की गई) या कुछ करने का एक आसान तरीका है?

एक खलनायक की तरह लग के लिए क्षमा करें, लेकिन वह यह है कि मैं क्या हूँ :(

+0

अंतर्निहित पूर्ववत समर्थन पर नज़र रखना सुनिश्चित करें; मैंने इसका कभी भी उपयोग नहीं किया है और मुझे इसके लिए स्विंग ट्यूटोरियल नहीं मिल रहा है, लेकिन [यहां] (http://docs.oracle.com/javase/6/docs/api/javax/swing/undo/UndoManager.html) प्रबंधक है। –

उत्तर

7

Command Pattern पर एक नजर डालें, इसके उपयोग पूर्ववत/फिर से कार्यक्षमता को लागू करना शामिल है।

0

मैं एक कार्रवाई बनाने की कोशिश करेंगे कक्षा, एडिलेमेंटएक्शन क्लास को एक्शन से वंचित करने के साथ। AddElementAction में एक() और Undo() विधि हो सकती है जो तदनुसार तत्वों को जोड़/निकाल देगी। फिर आप पूर्ववत/फिर से करने के लिए क्रियाओं के दो ढेर रख सकते हैं, और बस कॉल करें()/पूर्ववत() इसे पॉप करने से पहले शीर्ष तत्व पर।

+0

देखें ['javax.swing.undo.UndoManager'] (http://docs.oracle.com/javase/6/docs/api/javax/swing/undo/UndoManager.html) –

1

यह tutorial कमांड पैटर्न के मूलभूत और स्विंग के लिए पूर्ववत/फिर से तंत्र की व्याख्या करता है। आशा करता हूँ की ये काम करेगा।

+0

वह लेख वास्तव में सहायक है। धन्यवाद। –

0

You have to define undo(), redo() operations along with execute() in Command interface itself

उदाहरण:

interface Command { 

    void execute() ; 

    void undo() ; 

    void redo() ; 
} 

अपने ConcreteCommand कक्षा में एक राज्य को परिभाषित करें। Execute() विधि के बाद वर्तमान स्थिति के आधार पर, आपको यह तय करना होगा कि आदेश पूर्ववत स्टैक या फिर से स्टैक में जोड़ा जाना चाहिए और तदनुसार निर्णय लेना चाहिए।

बेहतर समझने के लिए इस undo-redo कमांड आलेख पर एक नज़र डालें।

2

टी एल; डॉ: आप पूर्ववत समर्थन करते हैं और कमान और मेमेंटो पैटर्न (Design Patterns - Gama et. al) को लागू करने से कार्यों को फिर से कर सकते हैं।

मेमेंटो पैटर्न

यह सरल पैटर्न आप एक वस्तु के राज्यों को बचाने के लिए अनुमति देता है। बस ऑब्जेक्ट को एक नई कक्षा में लपेटें और जब भी उसका राज्य बदल जाए, इसे अपडेट करें।

public class Memento 
{ 
    MyObject myObject; 

    public MyObject getState() 
    { 
     return myObject; 
    } 

    public void setState(MyObject myObject) 
    { 
     this.myObject = myObject; 
    } 
} 

कमान पैटर्न

कमान पैटर्न मूल वस्तु और स्मृति चिन्ह वस्तु है, जो हम एक पूर्ववत् के मामले में की जरूरत है (कि हम पूर्ववत करें/फिर समर्थन करना चाहते हैं) संग्रहीत करता है।इसके अलावा, 2 तरीकों परिभाषित कर रहे हैं:

  1. निष्पादित: आदेश
  2. unExecute कार्यान्वित: आदेश को हटा

कोड:

public abstract class Command 
{ 
    MyObject myObject; 
    Memento memento; 

    public abstract void execute(); 

    public abstract void unExecute(); 
} 

तार्किक "को परिभाषित क्रियाएं "जो कमांड का विस्तार करती हैं (उदाहरण के लिए सम्मिलित करें):

public class InsertCharacterCommand extends Command 
{ 
    //members.. 

    public InsertCharacterCommand() 
    { 
     //instantiate 
    } 

    @Override public void execute() 
    { 
     //create Memento before executing 
     //set new state 
    } 

    @Override public void unExecute() 
    { 
     this.myObject = memento.getState()l 
    } 
} 

लागू करने पैटर्न:

यह अंतिम चरण पूर्ववत करें/फिर व्यवहार को परिभाषित करता। वे मूल विचार आदेशों का एक ढेर स्टोर करना है जो आदेशों की इतिहास-सूची के रूप में कार्य करता है। फिर से समर्थन करने के लिए, जब भी एक पूर्ववत आदेश लागू होता है तो आप द्वितीयक सूचक रख सकते हैं। ध्यान दें कि जब भी कोई नई वस्तु डाली जाती है, तो उसके वर्तमान स्थिति के बाद सभी आदेश हटा दिए जाते हैं; कि deleteElementsAfterPointer विधि द्वारा प्राप्त किया गया है नीचे परिभाषित:

private int undoRedoPointer = -1; 
private Stack<Command> commandStack = new Stack<>(); 

private void insertCommand() 
{ 
    deleteElementsAfterPointer(undoRedoPointer); 
    Command command = 
      new InsertCharacterCommand(); 
    command.execute(); 
    commandStack.push(command); 
    undoRedoPointer++; 
} 

private void deleteElementsAfterPointer(int undoRedoPointer) 
{ 
    if(commandStack.size()<1)return; 
    for(int i = commandStack.size()-1; i > undoRedoPointer; i--) 
    { 
     commandStack.remove(i); 
    } 
} 

private void undo() 
{ 
    Command command = commandStack.get(undoRedoPointer); 
    command.unExecute(); 
    undoRedoPointer--; 
} 

private void redo() 
{ 
    if(undoRedoPointer == commandStack.size() - 1) 
     return; 
    undoRedoPointer++; 
    Command command = commandStack.get(undoRedoPointer); 
    command.execute(); 
} 

निष्कर्ष:

क्या इस डिजाइन शक्तिशाली बनाता है तथ्य यह है कि आप (Command वर्ग का विस्तार करके) के रूप में आप की तरह के रूप में कई आदेशों जोड़ सकते हैं जैसे , RemoveCommand, UpdateCommand और इसी तरह से। इसके अलावा, एक ही पैटर्न किसी भी प्रकार के ऑब्जेक्ट पर लागू होता है, जिससे विभिन्न उपयोग मामलों में पुन: प्रयोज्य और संशोधित बनाया जाता है।

+0

आप पूर्ववत/फिर से चरणों की संख्या सीमित करने के बारे में कैसे जाएंगे? एक ढेर का आकार संभव नहीं है। – Atlas2k

+0

@ एटलस 2k आपके पास थ्रेसहोल्ड हो सकता है (उदा।, 'Int threshhold = 30') और फिर वर्तमान स्टैक आकार के आधार पर सभी "पुराने" कमांड को हटा दें। उदाहरण के लिए, यदि आप 'insertCommand() 'को कॉल करते हैं और आपका' commandStack.size()' 30 से बड़ा है, तो आप पहले तत्व ('commandStack.remove (0)') को हटा दें। मुख्य विचार यह है कि अपने ढेर को एक निश्चित थ्रेसहोल्ड आकार में सीमित करना है। हां, अधिक जटिल उपयोग-केस, लेकिन निश्चित रूप से करने योग्य :) –

+0

मैंने अपना अधिकतम स्टैक आकार सेट करने के लिए इसका पालन किया: http://ntsblog.homedev.com.au/index.php/2010/05/06/c-stack- साथ-अधिकतम सीमा / – Atlas2k

संबंधित मुद्दे