搭建Java桌面应用程序原型(三)
做出技术决策
在开发过程中,我要解决一些技术问题,做一些技术决策。下面的代码片段是简单的解释,但是在我以后的文章中会详细描述。这里重要的是理解原型的作用。使用原型来寻找技术问题的解决方案,测试不常见的API,并确保应用程序的性能。
对于多层板
在windows中构建一个画板这样的图形应用并不是一件非常复杂的事情。你要处理鼠标事件,画直线,矩形和椭圆。我们必须处理变形功能,例如从基本应用程序到专业图形编辑器的移动、缩放、重新排序、删除、复制、剪切和粘贴图片。您还可以包含一个可以编辑、重新控制大小和文本包装的文本框,等等。没有必要构建自己的样式文本编辑器,因为Swing已经提供了一些文本组件。
如何将Swing的文本编辑器与自己的绘图组件集成在一起?我考虑了两种解决方案。一个是实现一个类似JTable使用的单元格编辑器,但是如果你想改变文本框的大小或者移动它,你需要一点技巧。另一种解决方案是使用JDesktopPane并将文本组件放在JInternalFrame中。
对于第二种解决方案,Swing已经提供了调整大小和移动功能,但接下来的问题是,如何在带有文本注释的内置框架下绘制图像?还有在JDesktopPane上怎么画其他简单的图形,比如直线,矩形,椭圆?幸运的是,有一个简单的解决方案,因为JDesktopPane是一个真正的多层面板。原型MainPane类扩展了JDesktopPane,有两层。其中一个包含PaintView自定义组件,允许您绘制简单的图形。另一层包含文本注释。当然,如果一个带注释的图片是程序无法获取的,那么这个解决方案就是没有意义的。Main的getAnnotatedImage()方法使用下面的代码实现了这一点:
BufferedImage image = new BufferedImage(宽度,高度,BufferedImage。TYPE _ INT _ RGB);
graphics 2d g = image . create graphics();
print all(g);
g . dispose();
油漆外部油漆()
Swing组件的绘制通常是在paint()内部完成的,或者这个绘制方法被称为inside paint()。但是,当用鼠标在屏幕上绘制一个对象时,您不希望重新绘制其他组件,因为这将导致应用程序运行效率低下。例如,用户用铅笔画画,每个鼠标事件都会导致应用程序绘制一小段线段。在MOUSE_PRESSED和MOUSE_RELEASED之间有数百个MOUSE_DRAGGED事件。
当用户仅在屏幕上绘制一些图形时,数百次重绘PaintView组件是不可接受的。请注意,PaintView处理大多数绘制操作,而repaint需要重绘所有注释,包括文本注释。正确的解决方法是在处理每个鼠标事件时,使用getGraphics()在paint()之外获取图形上下文。
protected void tool action(mouse event e){
e . consume();
graphics 2d G2 =(graphics 2d)get graphics();
float zoom factor = model . getzoom factor();
g2.scale(zoomFactor,zoom factor);
float x = e . getx()/zoom factor;
float y = e . gety()/zoom factor;
current tool . action(e . getid(),x,y,G2);
G2 . dispose();
}
PaintView组件使用鼠标监视来处理鼠标事件。上述方法由每个事件调用,以委托currentTool对象的绘制。释放鼠标时,会调用repaint()请求刷新整个组件。因此,paint()仅在用户绘制完图形对象后调用一次。这是注册鼠标监控的代码:
protected void register listeners(){
addmouse listener(new mouse adapter(){
public void mouse pressed(mouse event e){
if(swing utilities . isleft mouse button(e)){
request focus();
current tool = model . create tool(abstract tool。DRAW _ STYLE);
tool action(e);
}
}
public void mouse released(mouse event e){
if(swing utilities . isleft mouse button(e)){
tool action(e);
model . setlastool(current tool);
current tool = null;
repaint();
}
}
});
addMouseMotionListener(new MouseMotionAdapter(){
public void mouse dragged(mouse event e){
if(swing utilities . isleft mouse button(e))
tool action(e);
}
});
...
}
PaintView类的完整代码将在以后的文章中描述。上面的代码片段仅仅展示了如何使用原型来做出技术决策。
摘要
它在原型应用程序的开发中起着重要的作用,让您可以测试您的想法并尽早获得用户反馈。我不认为原型是“真正的”开发开始时可以丢弃的代码片段。相反,原型应该是你的产品或应用的基础。这意味着您应该小心地编写代码,即使您的类或方法稍后将被重写。
0条评论