ã¯ããã«
[åãæ¶ã]ããã³[ããçŽã]ãã¿ã³ã䜿çšãããšããŠãŒã¶ãŒã¢ã¯ã·ã§ã³ããã£ã³ã»ã«ããŠè¿ãããšãã§ãããªã¹ãã§å®è¡ããããã¹ãŠã®ã¢ã¯ã·ã§ã³ã®ãªã¹ãã衚瀺ã§ããŸãããããã¯ãã¯ãŒãããã»ããµãéçºç°å¢ãã°ã©ãã£ãã¯ããã³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ã®æ©èœãžã®ã¢ã¯ã»ã¹ãæäŸããããžãã¹ããžãã¯ã®ã«ãŒãã¯ã©ã¹ã®ãããªãã¯ã¡ãœããã®ãªã¹ãã§ãã
ããŒã ãã¿ãŒã³
ã¢ãã«ã®ç¶æ
ã倿Žããã¡ãœããã¯ãããŸããŸãªãã©ã¡ãŒã¿ãŒãæã¡ãéåžžã¯ã¢ãã«ã®ããŸããŸãªã¯ã©ã¹ã§å®çŸ©ã§ããŸãã ãã©ã¡ãŒã¿ãšã¡ãœããã®ã¿ãŒã²ãããªããžã§ã¯ãã«é¢ããæ
å ±ãå®å
šã«ã«ãã»ã«åããããšã§ãããã¹ãŠã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);
ã芧ã®ãšããããã®ã¯ã©ã¹ã«ã¯ãã»ã«ã®ã¢ãã¬ã¹ãšãã®å€ãä¿åããããã®å€æ°ããããŸãã ãŸããã¡ã¢ãªãç¯çŽããããã«ãå€ãä¿åãã倿°ã¯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) {
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ã䜿çšããŠã³ã³ãã€ã«ããã³å®è¡ã§ããŸãã