绘图应用程序中撤消/重做的命令模式 [英] Command Pattern for undo/redo in paint application

查看:157
本文介绍了绘图应用程序中撤消/重做的命令模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在一个小的绘图应用程序中实现撤消/重做。似乎命令模式非常适合使用,但我不确定如何最好地实现它。

I would like to implement undo/redo in a small paint application. It seems the Command Pattern fits the use nicely, but I am unsure how to best implement it.

根据我理解的模式,有必要在每个命令中包含:

As I understand the pattern, it is necessary to include in each command:


  1. 用于重做的绘画操作的详细信息(例如,行 - >开始和结束点,自由格式行 - > GeneralPath

  2. 更改撤消之前组件的状态。在这种情况下,这将是受命令影响的区域的小快照图像。

我的理解基于这一点命令需要是原子或自包含的,具有撤消/重做该操作所需的所有信息。

My understanding based on that is that each command needs to be 'atomic' or self contained, with all the information needed for undo/redo that operation.

不幸的是,这需要存储的信息比我先输入的信息多预料。对于一行,我们还必须考虑诸如颜色 Stroke RenderingHints 最初用于绘制它。这将我的简单的小命令变成了一些东西..内存中更笨重,并且有更多的样板代码可以生成(每个都是一个可序列化的bean 1 )。

Unfortunately that would require storing more information than I'd first anticipated. For a line we must also account for things like the Color, Stroke and RenderingHints used to draw it initially. This turns my 'simple little commands' into something ..more bulky in memory, and with more boiler-plate code to churn out (each will be a serializable bean1).

出于记忆保存的原因(大多数情况下),我想要欺骗命令的规范。也许每100次更新都会备份整个绘图区域,但是不存储已更改图像的任何部分,只需为每次新的绘制操作重建最后(最多)100个命令。但是在绘制每个部分之前确保 Graphics 对象的状态是正确的 - 这部分可能需要一行,但是 RenderingHints 在4个命令之前被更改了, Color 在98个命令之前被更改了,而 Stroke 已经更改了在最后的227个命令中保持不变。

For reasons of memory conservation (mostly) I was wanting to 'cheat' on the specification of the commands. Perhaps take a backup of the entire drawing area every 100th update, but otherwise store no part of the changed image, and simply rebuild the last (up to) 100 commands for each new paint operation. But that seems problematic to ensure that the state of the Graphics object is right before painting each part - this part might require a line, but the RenderingHints were changed 4 commands ago, the Color was changed 98 commands ago, while the Stroke has remained the same for the last 227 commands.

追求更高效的内存命令似乎将模式从原子方面抛到窗外。这反过来导致难以确定可能影响渲染的最早命令。

Pursuing a more memory efficient command seems to throw the pattern right out the window in terms of being 'atomic'. That in turn leads to difficulties in determining the earliest command that might affect the rendering.

我应该:


  • 寻找新的模式?

  • 尝试通过调整模式来实现我的特殊需求?

  • 把所有这些都扔进去废物箱是否过早优化并以最简单(也是最耗费内存的)方式对其进行编码,这种方式符合定义的命令模式?


  1. 每个都是一个可序列化的bean第二个想法,没有。我做了圆顶检查,发现 Graphics2D (它巧妙地封装了绘制时使用的许多参数)不可序列化。此外, BasicStroke 可序列化,但不会存储笔划的粗细。我可以创建许多属性的可序列化版本,但它似乎会产生更多的代码,所以我将放弃该规范。同样。我只会尝试在运行时存储对 BufferedImage 的引用。

  1. "each will be a serializable bean" On 2nd thoughts, no. I did dome checks to find that a Graphics2D (which neatly encapsulates many parameters used when drawing) is not serializable. Further, a BasicStroke is serializable, but the thickness of the stroke is not stored. I could create serializable versions of many of the attributes but it seems to make for a lot more code, so I'm going to abandon that spec. as well. I will only attempt to store a reference to a BufferedImage at run-time.


推荐答案

我会坚持使用命令模式并首先尝试一个天真的解决方案(=最需要内存的)。对于某些图形操作,甚至可能需要在命令对象中保留整个图像的副本(例如,考虑过滤器)。这在专业图像编辑应用程序中也是常见问题,它们通常具有记住的最后命令的存储器或步骤限制。如果内存消耗非常大,您可能会考虑将命令历史中最旧的条目交换到文件系统。我认为用户不会介意等待,直到更改被取消。

I would stick with command pattern and first try a naive solution (=the most memory-hungry). For some graphical operations it may be even necessary to keep a copy of the entire image in the command object (eg. think of filters). This is a common problem also in professional image editing applications, they often have a memory or step limit of last commands that are remembered. And if the memory consumption is really large you may think of swapping the oldest entries in command-history to file system. I think user will not mind waiting a second until the change is undone.

这篇关于绘图应用程序中撤消/重做的命令模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆