ã¯ããã«
[åãæ¶ã]ããã³[ããçŽã]ãã¿ã³ã䜿çšãããšããŠãŒã¶ãŒã¢ã¯ã·ã§ã³ããã£ã³ã»ã«ããŠè¿ãããšãã§ãããªã¹ãã§å®è¡ããããã¹ãŠã®ã¢ã¯ã·ã§ã³ã®ãªã¹ãã衚瀺ã§ããŸãããããã¯ãã¯ãŒãããã»ããµãéçºç°å¢ãã°ã©ãã£ãã¯ããã³CADãšãã£ã¿ãŒãã·ã¹ãã ãªã©ã®ã¢ããªã±ãŒã·ã§ã³ã®äºå®äžã®æšæºã§ããµãŠã³ããšãããªã®ç·šéãšç·šéã ãããã¯ãŠãŒã¶ãŒã«ãšãŠã銎æã¿ãããã®ã§ãåŸè ã¯èªåã®ååšãäžãããããã®ãšããŠèªèããŸãã ããããéçºè ã®èŠ³ç¹ããèŠããšãåãæ¶ãã®ååšã®èŠä»¶ã¯ããããžã§ã¯ãã®ã¢ãŒããã¯ãã£å šäœã«åœ±é¿ããèŠå ã®1ã€ã§ãããéçºãããžã§ã¯ãã®ããåæã®æ®µéã§æ±ºå®ãããŸãã
ãªãŒãã³ãœãŒã¹ã«ã¯ãå ã«æ»ã/ããçŽãæ©èœãå®éã«å®è£ ããæ¹æ³ã«é¢ããããªãã®æ å ±ããããŸãã E.ã¬ã³ããã«ããå€å žçãªæ¬ããªããžã§ã¯ãæåããã°ã©ãã³ã°ã®æ¹æ³ã ããã¶ã€ã³ãã¿ãŒã³ãã§ã¯ããã®ç®çã«å¯ŸãããããŒã ããã¿ãŒã³ã®é©åæ§ã«ã€ããŠç°¡åã«èª¬æããŠããŸããã€ã³ã¿ãŒãããã«é¢ããäž»é¡ã«é¢ããå€ãã®äžè¬æ å ±ããããŸãããååã«å®å šã§ååã«éçºãããå®è£ äŸãèŠã€ããããšãã§ããŸããã§ããã ãã®èšäºã§ã¯ããã®ã®ã£ãããåããããšããèè ã®çµéšã«åºã¥ããŠãå ã«æ»ã/ããçŽãããµããŒãããã¢ããªã±ãŒã·ã§ã³ã¢ãŒããã¯ãã£ã®è©³çŽ°ãªäŸã瀺ããŸããããã¯ãä»ã®ãããžã§ã¯ãã®åºç€ãšããŠäœ¿çšã§ããŸãã
èšäºã®ã³ãŒãäŸã¯Javaèšèªã§æäŸãããŠããŸãããJavaåºæã®ãã®ã¯ãªããããã§çŽ¹ä»ãããã¹ãŠã®ã¢ã€ãã¢ã¯ãªããžã§ã¯ãæåèšèªã«é©ããŠããŸãïŒèè èªèº«ãDelphiã§å®è£ ããŸããïŒã
ããŸããŸãªããŒãºãšã¢ããªã±ãŒã·ã§ã³ã®ã¿ã€ãã«ã¯ãããŸããŸãªãå ã«æ»ãã¢ãã«ããååšããããšã«æ³šæããŠãã ãããç·åœ¢-å³å¯ã«éã®é åºã§æäœããã£ã³ã»ã«ããå Žåãããã³éç·åœ¢-å®è¡ããã¢ã¯ã·ã§ã³ã®å±¥æŽããä»»æã®æäœããã£ã³ã»ã«ããå Žå ããŒã¿ã¢ãã«ãžã®åæãããå€æŽ ãã€ãŸãç°ãªãã¹ã¬ããã§ã®ããŒã¿ã¢ãã«ã®å éšç¶æ ã®åæå€æŽãèš±å¯ãããŠããªãã·ã¹ãã ã§ã®ç·åœ¢Undoã®å®è£ ã«ã€ããŠèª¬æããŸãã å¯èœãªundoã¢ãã«ã®åé¡ã¯ãããšãã°Wikipediaã®èšäºã§æäŸãããŠããŸã ã
åœç¶ãã¢ããªã±ãŒã·ã§ã³ã¯ãã¥ãŒïŒViewïŒããã®ããŒã¿ã¢ãã«ïŒModelïŒã®åé¢ãå®è£ ããUndoæ©èœã¯ãã®ã¯ã©ã¹ã®1ã€ã®undoïŒïŒããã³redoïŒïŒã¡ãœããã®åœ¢åŒã§ããŒã¿ã¢ãã«ã¬ãã«ã§å®è£ ããããšä»®å®ããŸãã
å®äŸ
説æã®ããã®äŸãšããŠããã®èšäºã§ã¯ãã¹ãã¬ããã·ãŒãããããã¿ã€ãã³ã°ããã¢ããªã±ãŒã·ã§ã³ã®ããŒã¿ã¢ãã«ïŒMS Excel / LibreOffice Calcã®ã¹ã¿ã€ã«ïŒã«ã€ããŠæ€èšããŸãã å€ãšãµã€ãºãå€æŽã§ããã»ã«ãè¡ãšå-亀æããã»ã«ã§æ§æãããã·ãŒãïŒç°¡åã«ããããã«1ã€ã®ã¿ïŒãããããããã®ã¢ã¯ã·ã§ã³ã¯ãã¹ãŠãã£ã³ã»ã«ãããŸãã ãœãŒã¹ã³ãŒããšé¢é£ããåäœãã¹ãã¯https://github.com/inponomarev/undoredoã§å ¥æã§ããMavenã䜿çšããŠã³ã³ãã€ã«ããã³å®è¡ã§ããŸãã
ãã®äŸã®äž»ãªãšã³ãã£ãã£ã¯æ¬¡ã®ãšããã§ãã
- worksheet-ã¯ã©ã¹Worksheet ã
- è¡ãšå- è¡ãšåã¯ã©ã¹ïŒ AxisElementã¯ã©ã¹ã®åå«ïŒã
- cells-ã¯ã©ã¹Cell ã
çµæã®åçŽãªããŒã¿ã¢ãã«ã¯ã次ã®å³ã®ã¯ã©ã¹å³ã«ç€ºãããŠããŸãã
ã¹ãã¬ããã·ãŒãã®å®è£ ã®è©³çŽ°ã«ã€ããŠã¯èª¬æããŸãããããœãŒã¹ã³ãŒãèšèšã®åºæ¬ååã«ã€ããŠç°¡åã«èª¬æããŸãã ã¹ãã¬ããã·ãŒãã·ãŒãã¯ãå¢çãç»é¢ãã¯ããã«è¶ ããããŒã¿ã®2次å é åãšããŠãŠãŒã¶ãŒã«è¡šç€ºãããŸãããããŒã¿ã¢ãã«ã«2次å é åã䜿çšããããšã¯ãã¡ã¢ãªæ¶è²»éãŸãã¯äžè¬çãªæäœã®é床ã®èŠ³ç¹ããæ£åœåãããŸããã ããšãã°ãMS Excelã®ä»¥åã®ããŒãžã§ã³ã§65536åãšè¡ãèš±å¯ãããŠããå Žåã32ãããã·ã¹ãã ã§ã¯65536 2 ïŒã€ãŸã40åã»ã«ïŒã«ã¡ã¢ãªãå²ãåœãŠãããšã¯æè¡çã«äžå¯èœã§ãã
解決çã¯ãããªãŒãšããã·ã¥ããŒãã«ã«åºã¥ãèŸæžã䜿çšããŠãå€æŽãããå€ã®ã¿ãä¿åããèŸæžã«ãªãå€ãããã©ã«ãå€ã«çœ®ãæããããšã§ãã
Rowããã³Columnã®ã€ã³ã¹ã¿ã³ã¹ãæ ŒçŽããã«ã¯ã Worksheetã¯ã©ã¹ã®èŸæžTreeMap <IntegerãRow> rowsããã³TreeMap <IntegerãColumn> columnã䜿çšããŸã ã Cellã€ã³ã¹ã¿ã³ã¹ãä¿åããã«ã¯ã Rowã¯ã©ã¹ã®HashMap <ColumnãCell> cellsèŸæžã䜿çšããŸãã ãã®ããã·ã¥ããŒãã«ã®å€ã¯Cellãªããžã§ã¯ããžã®åç §ã§ãããããŒã¯åãªããžã§ã¯ãã§ãã ãã®ããŒã¿ã¹ãã¬ãŒãžãžã®ã¢ãããŒãã«ããã ã¯ãŒã¯ã·ãŒãã®ã³ã³ãã³ãã§å®éã«å¿ èŠãªãã¹ãŠã®æäœã«äœ¿çšãããé床ãšã¡ã¢ãªã®æé©ãªãã©ã³ã¹ãèŠã€ããããšãã§ããŸãã
ã¢ãã«ã«ãŒãã¯ã©ã¹ãšãã£ã³ã»ã«å¯èœãªã¡ãœãã
ãã®äŸã®Worksheetã¯ã©ã¹ã¯äžå¿ã§ãã1ïŒä»ã®ãã¹ãŠã®ããžãã¹ããžãã¯ãªããžã§ã¯ãã®æäœã¯ããã®ç¹å®ã®ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã®ååŸããå§ãŸããŸãã2ïŒä»ã®ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã¯ã Worksheetãªããžã§ã¯ãã®ã³ã³ããã¹ãã§ã®ã¿æ©èœããŸãã3ïŒ saveïŒ...ïŒã¡ãœãããä»ããŠéçã¡ãœããloadïŒ...ïŒã¯ãã¹ããªãŒã ã«ä¿åããã¹ããªãŒã ããã·ã¹ãã å šäœã®ç¶æ ã埩å ããŸãã ãã®ã¯ã©ã¹ãã¢ãã«ã®ã«ãŒãã¯ã©ã¹ãšåŒã³ãŸãã ååãšããŠãModel-View-Controllerã¢ãŒããã¯ãã£ã§ã¢ããªã±ãŒã·ã§ã³ãéçºããå Žåãã¢ãã«ã®ã«ãŒãã¯ã©ã¹ãäœã§ããããå€æããã®ã«å°é£ã¯ãããŸããã Undo / Redoã®æ©èœã«åºæã®ã¡ãœãããæäŸãããã®ã¯åœŒã§ãã
ã¢ãã«ã®ç¶æ ãå€ããã¡ãœãããç¹å®ããã®ãé£ãããªãã¯ãã§ãã ãããã¯ãåŒã³åºãçµæãå ã«æ»ãå¿ èŠãããã¡ãœããã§ãã ãã®äŸã§ã¯ã次ã®ãšããã§ãã
- setCellValueïŒint rowãint colãString valueïŒ -ã»ã«å€ãèšå®ããŸãïŒç°¡åã«ããããã«ãã»ã«ã¯æååå€ã®ã¿ãåãå ¥ãããšä¿¡ããŠããŸãïŒïŒã
- insertValuesïŒint topãint leftãString [] [] valueïŒ-2次å é åã®å€ïŒããšãã°ãã¯ãªããããŒãããååŸïŒãã»ã«ã«è²Œãä»ããŸãã
- setRowHeightïŒint rowãint heightïŒ ã setColWidthïŒint colãint widthïŒ -è¡ã®é«ããšåã®å¹ ãèšå®ãã
- insertColumnLeftïŒint colNumïŒ ã insertRowAboveïŒint rowNumïŒ -åãšè¡ãæ¿å ¥ãã
- deleteColumnïŒint colNumïŒ ã deleteRowïŒint rowNumïŒ -åãšè¡ãåé€ãã
- moveColumnïŒint fromãint toïŒ ã moveRowïŒint fromãint toïŒ -åãšè¡ãã³ã³ãã³ããšãšãã«ç§»åããæçµçãªå/è¡ã®ã³ã³ãã³ãã眮ãæããŸãã
ãã¡ãããå®éã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãããã«å€ãã®å¯èœæ§ããããŸãã ãããã¯ããããã察å¿ããããŒã ã®ã¯ã©ã¹ïŒåŸã§èª¬æããŸãïŒãšäžèŽããå¿ èŠããããã¡ãœããã¯ç¹å¥ãªæ¹æ³ã§æžãæããå¿ èŠããããŸãã
ã¹ã¿ãã¯ã®åãæ¶ããšããçŽã
ç·åœ¢Undoã¢ãã«ã§ã¯ãããã¥ã¡ã³ãã«å¯ŸããŠå®è¡ãããã¢ã¯ã·ã§ã³ã®ã·ãŒã±ã³ã¹ãä¿æãããããªæ¹æ³ã§æäœããã£ã³ã»ã«ãããŸãã ããšãã°ãæåã«åãããã¥ã¡ã³ãã«è¿œå ããã次ã«å¹ ãå€æŽãããå Žåããããã®æäœã®ãã£ã³ã»ã«ã¯éã®é åºã§ã®ã¿å¯èœã§ãããè¿ãããã®ã¯çŽæ¥ã§ãã ãããã£ãŠããã£ã³ã»ã«ããŠåŸ©å ããæäœãæ ŒçŽããã«ã¯ãã¢ãã«ã®ã«ãŒãã¯ã©ã¹ã®äžéšã§ãããªã³ã¯ãªã¹ãã§2ã€ã®ã¹ã¿ãã¯ã䜿çšããã®ãèªç¶ã§ãã ã¢ãã«ã®ç¶æ ãå€æŽããã¡ãœãããåŒã³åºããããšãRedoã¹ã¿ãã¯ããªã»ãããããUndoã¹ã¿ãã¯ã次ã®å€ã§è£å ãããŸãã Undoã³ãã³ããå®è¡ãããšãUndoã¹ã¿ãã¯ããå€ãååŸãããRedoã¹ã¿ãã¯ã«ããã·ã¥ãããŸãã ããçŽãã³ãã³ãã®å®è¡ã¯ãããããã°ãåã³å€ãå ã«æ»ãã¹ã¿ãã¯ã«æ»ãå¿ èŠããããŸãïŒå³ãåç §ïŒã
ãããã®ã¹ã¿ãã¯ã®å 容ã¯ã Commandã¯ã©ã¹ã®åå«ãªããžã§ã¯ãã§ããããã«ã€ããŠã¯åŸã§èª¬æããŸãã 以äžã¯ãUndo / Redoã®æ©èœãžã®ã¢ã¯ã»ã¹ãæäŸããããžãã¹ããžãã¯ã®ã«ãŒãã¯ã©ã¹ã®ãããªãã¯ã¡ãœããã®ãªã¹ãã§ãã
- undoïŒïŒ -ã¢ãã«ã®ç¶æ
ãå€æŽããã¡ãœãããåŒã³åºãããããRedoã¹ã¿ãã¯ã«è»¢éããããšã«ããå®è¡ãããã¢ã¯ã·ã§ã³ãåãæ¶ããŸãã
Command cmd = undoStack.pop(); cmd.undo(); redoStack.push(cmd);
ç¹°ãè¿ãããåŒã³åºãã¯ãããããUndoã¹ã¿ãã¯ã䜿ãæãããããŸã§ãã§ãŒã³å ã®å€æŽãããŒã«ããã¯ããã¹ã¿ãã¯ã䜿ãæããããåŸãã¡ãœããã®ç¹°ãè¿ãåŒã³åºãã¯äœãããŸããã
- redoïŒïŒ -å ã«æ»ãåŒã³åºãã«ãã£ãŠãã£ã³ã»ã«ãããã¢ã¯ã·ã§ã³ãè¿ããå ã«æ»ãã¹ã¿ãã¯ã«æ»ããŸãã ç¹°ãè¿ãããåŒã³åºãã¯ãRedoã¹ã¿ãã¯ã䜿ãæãããããŸã§Undoã«ãã£ãŠåãæ¶ãããæäœãããŒã«ãªãŒããŒããŸãããã®åŸãredoïŒïŒã®åŒã³åºãã¯ç¡èŠãããŸãã ã¢ãã«ã®ç¶æ ãå€æŽããã¡ãœãããåŒã³åºããšãRedoã¹ã¿ãã¯å šäœããªã»ãããããŸãã
- getUndoStackïŒïŒ ã getRedoStackïŒïŒ -ãŠãŒã¶ãŒããã£ã³ã»ã«ãŸãã¯åè©Šè¡ã§ããæäœã®ãªã¹ããäœæã§ããããã«ãã¹ã¿ãã¯å šäœãè¿ããŸãã
- isUndoActiveïŒïŒ ã setUndoActiveïŒããŒã«å€ïŒ-Undoã¡ã«ããºã ãç¡å¹ã«ã§ããŸãïŒããã©ã«ãã§æå¹ïŒã 1ïŒããã¥ã¡ã³ãã®ç¶æ ãéåžžã«å€§ããå€æŽããå Žåã®ããã©ãŒãã³ã¹ã®åäžãšã¡ã¢ãªæ¶è²»ã®åæž2ïŒUndo / Redoæ©èœãå©çšã§ããªãã€ã³ã¿ãŒãã§ã€ã¹ãä»ããŠå€éšã¢ããªã±ãŒã·ã§ã³ããããã¥ã¡ã³ããæäœããå¿ èŠããããŸãã
ããŒã ãã¿ãŒã³
ã¢ãã«ã®ç¶æ ãå€æŽããã¡ãœããã¯ãããŸããŸãªãã©ã¡ãŒã¿ãŒãæã¡ãéåžžã¯ã¢ãã«ã®ããŸããŸãªã¯ã©ã¹ã§å®çŸ©ã§ããŸãã ãã©ã¡ãŒã¿ãšã¡ãœããã®ã¿ãŒã²ãããªããžã§ã¯ãã«é¢ããæ å ±ãå®å šã«ã«ãã»ã«åããããšã§ãããã¹ãŠã1ã€ã®æ«ã®äžã§æ«åœ¢ã«ãããããšãã§ããèšèšãã¿ãŒã³ããããŒã ãã«ããããšãã§ããŸãã ãã®ãã¿ãŒã³ã®éèªææ§ã¯ãäžéšã®ãšã³ãã£ãã£ãéåžžããªããžã§ã¯ãæåã³ãŒãã§ã¯ã©ã¹ãèšè¿°ãããšããäºå®ã«ãããŸãã ããã§ã¯ãã¯ã©ã¹ã¯æ¬è³ªã§ã¯ãªããã¢ãã«ã®ç¶æ ãå€æŽããã¡ãœããã«ãã£ãŠå®è¡ãããã¢ã¯ã·ã§ã³ãèšè¿°ããã¡ãœããèªäœãããã®ç¹æš©ããååŸãããŸãã
åã³ãã³ãã®ã¯ã©ã¹ã¯ãåºæ¬æœè±¡ã¯ã©ã¹Commandããç¶æ¿ããŸãã ã³ãã³ãèªäœã«ã¯ã execute ã undo ãããã³getDescriptionã® 3ã€ã®æœè±¡ã¡ãœããã®ã¿ããããŸãããããã®ãã©ã¡ãŒã¿ãŒã¯ãããŸããïŒéèŠã§ãïŒïŒã ããã«ãããå®è¡ãŸãã¯ãã£ã³ã»ã«ãããæäœã«ã€ããŠãäœãç¥ããªããã«ãŒãã¯ã©ã¹ã®undoïŒïŒããã³redoïŒïŒã¡ãœããã䜿çšããŠã³ãã³ããå®è¡ããã³ãã£ã³ã»ã«ã§ããŸãã getDescriptionïŒïŒã¡ãœããã¯ãã¢ã¯ã·ã§ã³ã®ããã¹ã説æãè¿ãå¿ èŠããããŸãããã®èª¬æã¯ããã£ã³ã»ã«ããã¢ã¯ã·ã§ã³ã®ãªã¹ãã§ãŠãŒã¶ãŒãå©çšã§ããŸãã
Commandã¯ã©ã¹ã®ç¶æ¿è ã¯ããã®æœè±¡ã¡ãœããã®å®è£ ã«å ããŠãã³ãã³ãèµ·åãã©ã¡ãŒã¿ãŒã«é¢ããæ å ±ãšãæ¢ã«å®è¡ãããã³ãã³ãããã£ã³ã»ã«ããå®è¡ãããã³ãã³ãã®ããã¹ã説æã衚瀺ããããã«å¿ èŠãªæ å ±ãå«ãä»»æã®æ°ã®è¿œå ãã£ãŒã«ããå«ãããšãã§ããŸãã ãã®å Žåã executeïŒïŒã¡ãœããã«ã¯ãéåžžãã¢ãã«ã®ç¶æ ãå€æŽããã¡ãœããã«å«ãŸããã³ãŒããå«ãŸããŠããå¿ èŠããããŸãããã¡ãœããã³ãŒãã®ä»£ããã«ãã®ã³ãŒãã¯ã³ãã³ãã¯ã©ã¹ã®ãã£ãŒã«ãã䜿çšããå¿ èŠããããŸãã ããŒã ã¯ã以åã®æ¹æ³ãšåãæ¹æ³ã§ãã¢ãã«ãªããžã§ã¯ãã®å éšç¶æ ãæäœããŸãã ãããã£ãŠãããŒã ã¯ã¢ãã«ãªããžã§ã¯ãã®é衚瀺ïŒãã©ã€ããŒãïŒãã£ãŒã«ãã«ã¢ã¯ã»ã¹ã§ããå¿ èŠããããŸãã Javaã§ã¯ã察å¿ããã¢ãã«ã¯ã©ã¹ã«ã³ãã³ãã®åå«ã¯ã©ã¹ããã¹ãããå Žåã«äŸ¿å©ã§ãã ããšãã°ãã¢ããªã±ãŒã·ã§ã³ã§ã¯ã SetSizeã³ãã³ã㯠AxisElementã¢ãã«ã¯ã©ã¹ã«ãã¹ããããæ®ãã®ã³ãã³ãã¯Worksheetã«ãã¹ããããŠããŸã ã
undoïŒïŒã¡ãœããã¯ã executeïŒïŒã¡ãœãããåŒã³åºããçµæãåãæ¶ãããšãã§ããã¯ãã§ãã ããã«å¿ èŠãªãã¹ãŠã®æ å ±ã¯ãããŒã ã¯ã©ã¹ã®ãã£ãŒã«ãã«ä¿åããå¿ èŠããããŸãã undoïŒïŒã¡ãœãããåŒã³åºãããæç¹ã§ãããžãã¹ããžãã¯ãªããžã§ã¯ãã®ç¶æ ã¯ã察å¿ããexecuteïŒïŒã¡ãœããã®å®è¡çŽåŸã®ç¶æ ãšåžžã«åãã«ãªãããšãç解ããã°ãåé¡ã¯åçŽåãããŸãã ãã®åŸããŠãŒã¶ãŒãä»ã®æäœãå®è¡ããå ŽåãçŸåšã®ã³ãã³ãã®åãæ¶ãïŒïŒãè¡ãåã«ããã®åŸã«åŒã³åºããããã¹ãŠã®ã³ãã³ãã«å¯ŸããŠåãæ¶ãïŒïŒãå®è¡ããå¿ èŠããããŸãã å®éã«ã¯ããã®ååãç解ãããšã undoïŒïŒã¡ãœããã®èšè¿°ãéåžžã«å®¹æã«ãªããã³ãã³ãã«ä¿åãããæ å ±éãåæžãããŸãã
ã»ã«ã®å€ãèšå®ããã³ãã³ãã®å®è£ ãæ€èšããŠãã ããã
final class SetCellValue extends Command { private final int row; private final int col; private String val; public SetCellValue(int row, int col, String newValue) { this.row = row; this.col = col; this.val = newValue; } @Override public String getDescription() { return (" "); } private void changeVal() { String oldValue = getCellValue(row, col); Row r = rows.get(row); Column c = columns.get(col); //.... cell row col... cell.setValue(val); //.... val = oldValue; } @Override public void execute() { changeVal(); } @Override public void undo() { changeVal(); } }
ã芧ã®ãšããããã®ã¯ã©ã¹ã«ã¯ãã»ã«ã®ã¢ãã¬ã¹ãšãã®å€ãä¿åããããã®å€æ°ããããŸãã ãŸããã¡ã¢ãªãç¯çŽããããã«ãå€ãä¿åããå€æ°ã¯1ã€ã ãã§ããexecuteïŒïŒã¡ãœããããŸã å®è¡ãããŠããªãå Žåã¯æ°ããå€æ°ã executeïŒïŒã¡ãœãããæ¢ã«å®è¡ãããŠããå Žåã¯å€ãå€æ°ã§ãã ã€ãŸãã executeïŒïŒããã³undoïŒïŒã¡ãœãããé çªã«å®è¡ããããšããäºå®ãããã§äœ¿çšãããŸãã getDescriptionïŒïŒã¡ãœããã¯ã¯ã©ã¹å€æ°ã䜿çšããŠãã³ãã³ãã®ãã詳现ãªèª¬æãæäŸã§ããŸãã
ã¡ãœãããã³ãã¬ãŒãã®ãã£ã³ã»ã«
ã³ãã³ãã¯ãã£ã³ã»ã«å¯èœãªã¡ãœããã§ã©ã®ããã«äœ¿çšãããŸããïŒ éåžžããã®ãããªã¡ãœããããã©ã¡ãŒã¿ãŒãèæ ®ããŠã¢ãã«ã§ããã€ãã®ã¢ã¯ã·ã§ã³ãå®è¡ããå Žåãããããã¹ãŠãå ã«æ»ãã·ã¹ãã ã§ã¯ãå³å¯ã«æ¬¡ã®3ã€ã®æäœãå®è¡ããå¿ èŠããããŸãã
- 察å¿ããã³ãã³ãã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãïŒ ã³ãã³ãã®åå«ã¯ã©ã¹ïŒã
- ã¡ãœãããã©ã¡ãŒã¿ãšå Žåã«ãã£ãŠã¯è¿œå æ å ±ã§ã³ãã³ããã£ãŒã«ããåæåããŸãã
- ã«ãŒããªããžã§ã¯ãã®executeïŒCommand cmdïŒã¡ãœãããå®è¡ããæ°ããäœæããã³åæåãããã³ãã³ãããã©ã¡ãŒã¿ãŒãšããŠæž¡ããŸãã
ãã®äŸã§ã¯ã setCellValueã¡ãœããã®å®è£ ã¯æ¬¡ã®ããã«ãªããŸãã
public void setCellValue(int row, int col, String value) { Command cmd = new SetCellValue(row, col, value); execute(cmd); }
ä»ã®ãã¹ãŠã®ãã£ã³ã»ã«å¯èœãªã¡ãœããã¯äŒŒãŠããŸãã
ã«ãŒãã¯ã©ã¹ã®executeïŒCommand cmdïŒã¡ãœããã¯ã³ãã³ãã¢ã¯ã·ã§ã³ãå®è¡ããREDOã¹ã¿ãã¯ããã³ãããã³ãã³ããå ã«æ»ãã¹ã¿ãã¯ã«ããã·ã¥ããŸãã
undoStack.push(cmd); redoStack.clear(); cmd.execute();
ãã®ç¬éãããããŒã ã¯ãã£ã³ã»ã«/ç¹°ãè¿ãããã¢ã¯ã·ã§ã³ã®ãã§ãŒã³ã®äžéšã«ãªããŸãã äžèšã®ããã«ãã«ãŒãã¯ã©ã¹ã§undoïŒïŒã¡ãœãããåŒã³åºããšãUndoã¹ã¿ãã¯ã®æäžéšã«ããã³ãã³ãã®undoïŒïŒã¡ãœãããåŒã³åºãããRedoã¹ã¿ãã¯ã«è»¢éãããŸãã 次ã«ãã«ãŒãã¯ã©ã¹ã®redoïŒïŒã¡ãœãããåŒã³åºããšãRedoã¹ã¿ãã¯ã®æäžéšã§ã³ãã³ãã®executeïŒïŒã¡ãœãããå®è¡ãããUndoã¹ã¿ãã¯ã«ããã·ã¥ãããŸãã
ã³ãã³ãã¯ã©ã¹ã®åå©çš
ãã®ãããéåžžã¯1ã€ã®ã¡ãœãããèšè¿°ããå¿ èŠãããã¿ã¹ã¯ã®å Žåãå ã«æ»ãæ©èœãåããã·ã¹ãã ã§ã¯ãã¯ã©ã¹å šäœãäœæããå¿ èŠããããŸããããã«ãããã³ãŒãã®éãšãã®ãµããŒãã®è€éãã«ã€ããŠæ£åœãªæããçããŸããå®éã®ãããžã§ã¯ãã§ã¯ããã£ã³ã»ã«ãããã¡ãœããã®æ°ã¯æ°åã«ãªããŸãã
å®éãã³ãã³ãã¯ã©ã¹ã¯ããã®æ±çšæ§ãšè€æ°ã®ãã£ã³ã»ã«ãããã¡ãœããã«1ã€ã®ã³ãã³ãã¯ã©ã¹ã䜿çšããŠãããããå€§å¹ ã«å°ãããªããŸãã ããšãã°ãå®éã«ã¯ã SetCellValueã¯ã©ã¹ã®ã¡ã€ã³ã³ãŒãã¯ãå€æ°ã®1ã€ã®å€ãå€æŽãããã¹ãŠã®ã¡ãœããã«äœ¿çšã§ããŸãã ãã£ãŒã«ããè¿œå ããããã¯ã©ã¹ããã©ã¡ãŒã¿ãŒåããããšã§ãã³ãã³ãã¯ã©ã¹ãããæ±çšçã«ããããšãã§ããŸãã
ããšãã°ãããŒãã«ã®è¡ãšåã®äž¡æ¹ãåé€ããããã«äœ¿çšããããŠãããŒãµã«åé€ã³ãã³ããèããŸãã
final class Delete<T extends AxisElement> extends Command { private final int num; private final T deleted; private final TreeMap<Integer, T> map; Delete(TreeMap<Integer, T> map, int num) { this.num = num; this.map = map; deleted = map.get(num); } @Override public String getDescription() { return String.format(" %s %d", map == columns ? "" : "", num); } @Override public void execute() { internalDelete(map, num); } @Override public void undo() { internalInsert(map, num); map.put(num, deleted); } } private static <T extends AxisElement> void internalDelete(TreeMap<Integer, T> map, int num) { //... // num // > num //... } private static <T extends AxisElement> void internalInsert(TreeMap<Integer, T> map, int num) { //... // >= num //... } }
deleteColumnããã³deleteRowã¡ãœããã§ã®äœ¿çšã¯æ¬¡ã®ãšããã§ãã
public void deleteColumn(int colNum) { Command cmd = new Delete<Column>(columns, colNum); execute(cmd); } public void deleteRow(int rowNum) { Command cmd = new Delete<Row>(rows, rowNum); execute(cmd); }
ãã¯ã
ç¶æ ãå€æŽããã¡ãœããåŒã³åºãããUndoã¹ã¿ãã¯ã«æ ŒçŽããã«ã¯åäœãå°ããããããšãå€æããå ŽåããããŸãã 2次å ãªã¹ãïŒã¯ãªããããŒããªã©ïŒããããã¥ã¡ã³ãã«å€ã貌ãä»ããã«ã¯ãããã·ãŒãžã£insertValuesïŒint topãint leftãString [] [] valueïŒãæ€èšããŠãã ããã ã«ãŒãå ã®ãã®ããã·ãŒãžã£ã¯ããããã¡ã®ã»ã«ã®å€ã§ããã¥ã¡ã³ãã»ã«ã1ã€ãã€æŽæ°ããŸãã ãããã£ãŠã4Ã4ããŒãã«ã®äžéšãæ¿å ¥ãããšãå ã«æ»ãã¡ã«ããºã ã®èŠ³ç¹ãããããã¥ã¡ã³ãã»ã«ã«16ã®å€æŽãå ããããŸãã ããã¯ããŠãŒã¶ãŒãæ¿å ¥ã®çµæããã£ã³ã»ã«ããå Žåã[å ã«æ»ã]ãã¿ã³ã16åæŒãå¿ èŠããããŸãããè¡šã§ã¯ã16åã®ã»ã«ã以åã®å€ã次ã ãšåŸ©å ããããšãæå³ããŸãã
ãã¡ãããããã¯ééã£ãŠããŸãããã®ãããªæäœã®çµæã¯ããã£ã³ã»ã«ããŠå šäœãšããŠåŸ©å ãããã£ã³ã»ã«ãããæäœã®ãªã¹ãã«1è¡ã§è¡šç€ºããå¿ èŠããããŸãã ãããå¯èœã«ããããã«ããã¯ãã䜿çšãããŸãã
ãã¯ããå®è£ ãããšããèãæ¹ã¯åçŽã§ããããã¯ãå³ã«ç€ºãããã«ã ã³ãã³ãã¯ã©ã¹ã®ç¹å¥ãªåå«ã§ããããã®äžã«ä»ã®ã³ãã³ãã®ãã§ãŒã³ãå«ãŸããŠããŸãã
MacroCommandã¯ã©ã¹ã®executeïŒïŒã¡ãœããã¯ãç¬èªã®ã³ãã³ããªã¹ããå®è¡ãããããã®executeïŒïŒã¡ãœãããå®è¡ããŸãã åããã¯ãã®undoïŒïŒã¡ãœãããåŒã³åºããšãåãã³ãã³ãã®ãªã¹ããéã®é åºã§å®è¡ãããããã®undoïŒïŒã¡ãœãããåŒã³åºããŸãã
ã¢ãã«/ãã¥ãŒ/ã³ã³ãããŒã©ãŒã¢ãŒããã¯ãã£ã§æ§ç¯ãããã¢ããªã±ãŒã·ã§ã³ã®ã¯ãªããããŒãããŒã¹ãã¡ãœããã«é¡äŒŒãããã¯ãã¡ãœããã¯ãååãšããŠã¢ãã«ã®äžéšã§ã¯ãããŸããããã³ã³ãããŒã©ãŒã¬ãã«ã§å®è£ ãããŸãã å€ãã®å Žåããããã¯ãããçš®ã®æ¥åžžçãªäœæ¥ã®èªååã®ã¿ãè¡šãããã®å¿ èŠæ§ã¯ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®çš®é¡ã«å¿ããŠãååšããå Žåãšååšããªãå ŽåããããŸãã ããã«ãå€ãã®å Žåãè€æ°ã®ãŠãŒã¶ãŒã¢ã¯ã·ã§ã³ã1ã€ã«ã°ã«ãŒãåããå¿ èŠããããŸããããšãã°ãããã¹ããšãã£ã¿ãŒã¯ãåã ã®æåãå ¥åããããã®ãšã³ããªã§å ã«æ»ãã¹ã¿ãã¯ãè©°ãŸãããã®ã§ã¯ãªããåèªãšæã®ãŠãŒã¶ãŒå ¥åã1ã€ã®ãã¯ãã¢ã¯ã·ã§ã³ã«ã°ã«ãŒãåããŸãã
ãããã£ãŠããã¯ããµããŒãã¯ãã¢ããªã±ãŒã·ã§ã³ã«äŸåããªãæ¹æ³ã§ãæœè±¡ã¬ãã«ã§å®è£ ã§ããŸãã ããã¯ããããªãã¯ã¡ãœããbeginMacroïŒæååã®èª¬æïŒãšendMacroïŒïŒãã¢ãã«ã«ãŒãã¯ã©ã¹ã«è¿œå ããããšã§å®è¡ãããŸãã ã¡ãœããã¯ããã¯ãã¢ã¯ã·ã§ã³ã®ååŸã«åŒã³åºãããŸãã beginMacroïŒ...ïŒãããã£ã³ã»ã«ãããæäœã®ãªã¹ãã§ãŠãŒã¶ãŒã䜿çšã§ããæååãã©ã¡ãŒã¿ãŒã§åŒã³åºãããšã«ããã MacroCommandåã®ãªããžã§ã¯ããçæããUndoã¹ã¿ãã¯ãå éšãã¯ãã¹ã¿ãã¯ã§äžæçã«çœ®ãæããŸãã ãããã£ãŠãbeginMacroãåŒã³åºããåŸãã«ãŒãã¯ã©ã¹ã®executeïŒ...ïŒã¡ãœããã«ã³ãã³ãã転éãããšãUndoã¹ã¿ãã¯ã«çŽæ¥æžã蟌ãŸããã®ã§ã¯ãªããçŸåšã®ãã¯ãã®å éšã¹ã¿ãã¯ã«æžã蟌ãŸããŸãïŒé çªã«ããã§ã«Undoã¹ã¿ãã¯ã«æžã蟌ãŸããŸãïŒ ïŒ endMacroïŒïŒåŒã³åºãã¯ããã¹ãŠããã®å Žæã«æ»ããŸãã ãã¯ããçžäºã«ãã«ãã¬ãã«ã§ãã¹ãããããšãã§ããŸãã
æªä¿åã®å€æŽã远跡ãã
å ã«æ»ãæ©èœã䜿çšãããšãããã¥ã¡ã³ãã«ä¿åãããŠããªãå€æŽã远跡ããä¿¡é Œã§ããæ¹æ³ãæäŸãããŸãã ããã¯ãã¢ããªã±ãŒã·ã§ã³ã®ãä¿åããã¿ã³ã®æ£ããåäœãå®è£ ããããã«å¿ èŠã§ãã
- ãä¿åããã¿ã³ã¯ãæªä¿åã®å€æŽãååšããå Žåã«ã®ã¿ã¢ã¯ãã£ãã«ããå¿ èŠããããŸãïŒããã§ãªãå Žåã¯ä¿åããå¿ èŠã¯ãããŸãããããã¥ã¡ã³ãã¯å€æŽãããŠããŸããïŒã
- ããã¥ã¡ã³ããéãããšãã«ãæªä¿åã®å€æŽãååšããå Žåã«ã®ã¿å€æŽãä¿åãããã©ããããŠãŒã¶ãŒã«å°ããããšã¯çã«ããªã£ãŠããŸãã
ãã®äŸã§ã¯ãæªä¿åã®å€æŽã®ååšãisModifiedïŒïŒã¡ãœããã«ãã£ãŠè¿ãããŸãã 次ã®ããã«å®è£ ãããŸããsave ïŒ...ïŒã¡ãœãããåŒã³åºããããã³ã«ãUndoã¹ã¿ãã¯ã®çŸåšã®ããããlastSavedPointå€æ°ã«ä¿åãããŸãã isModifiedã¡ãœãããåŒã³åºããããšã Undoã¹ã¿ãã¯ã®çŸåšã®ããããlastSavedPointå€ãšæ¯èŒãããŸããçããå Žåãä¿åãããŠããªãå€æŽã¯ãããŸããã å ã«æ»ãã¡ã«ããºã ãç¡å¹ã«ãããšã isModifiedïŒïŒã¡ãœããã¯åžžã«trueãè¿ããŸã ã
ãããã«
ç§ãã¡ã®æèŠã§ã¯ãä»ã®ãããžã§ã¯ãã®ãã³ãã¬ãŒããšããŠååã«æ®éçãªäŸã䜿çšããŠãç·åœ¢ãã«ãã¬ãã«ã®å ã«æ»ã/ããçŽããå®è£ ããããã®åºæ¬ååãæ€èšããŸããã
å ã«æ»ããšããçŽãã®æ©èœããã¢ããªã±ãŒã·ã§ã³ã®ã¢ãŒããã¯ãã£ãšéçºè ã®ããæèã«å¯ŸããŠéåžžã«æ·±å»ãªèŠæ±ãããããšã¯é©ãããšã§ã¯ãããŸããã ããããModel / View / Controllerã¢ãŒããã¯ãã£ã®å³å¯ãªéµå®ãé©åã«èšèšãããã¢ãã«ïŒã·ã¹ãã ã®ã¢ãã«ã®ç¶æ ãå€æŽããã¡ãœãããå ã«æ»ãããšã¯ãè²»çšãããããïŒãªã©ãé¢åãªäœæ¥ã«ãããããããäœæäžã®ããã°ã©ã ã®é«å質ãšä¿¡é Œæ§ãåŸãããŸããæçµçã«ã¯ãŠãŒã¶ãŒã®æºè¶³ã«ã€ãªãããŸãã
* * *
ãã®èšäºã§èª¬æãããŠããäŸã®å®å šãªãœãŒã¹ã³ãŒããšå¯Ÿå¿ããåäœãã¹ãã¯https://github.com/inponomarev/undoredoã§å ¥æã§ããMavenã䜿çšããŠã³ã³ãã€ã«ããã³å®è¡ã§ããŸãã