`
yanyanquan
  • 浏览: 448387 次
  • 性别: Icon_minigender_1
  • 来自: 江门
社区版块
存档分类
最新评论

通过Java Swing看透MVC设计模式

阅读更多
一个好的用户界面(GUI)的设计通常可以在现实世界找到相应的表现。例如,如果在您的面前摆放着一个类似于soft/" class="wordstyle">电脑键盘按键的一个简单的按钮,然而就是这么简单的一个按钮,我们就可以看出一个GUI设计的规则,它由两个主要的部分构成,一部分使得它具有了按钮应该具有的动作特性,例如可以被按下。另外一部分则负责它的表现,例如这个按钮是代表了A还是B。
  看清楚这两点你就发现了一个很强大的设计方法,这种方法鼓励重用reuse,而不是重新设计redesign。你发现按钮都有相同的机理,你只要在按钮的顶上喷上不同的字母便能制造出“不同”的按钮,而不用为了每个按钮而重新设计一份图纸。这大大减轻了设计工作的时间和难度。
  如果您把上述设计思想应用到软件开发领域,那么取得相似的效果一点都不让人惊奇。一个在软件开发领域应用的非常广泛的技术Model/View/Controller(MVC)便是这种思想的一个实现。
  这当然很不错,但是或许您又开始疑惑这和java基础类JFC(Java Foundation Class)中的用户界面设计部分(Swing)又有什么关系呢?好的,我来告诉你。
  尽管MVC设计模式通常是用来设计整个用户界面(GUI)的,JFC的设计者们却独创性的把这种设计模式用来设计Swing中的单个的组件(Component),例如表格Jtable,树Jtree,组合下拉列表框JcomboBox等等等等。这些组件都有一个Model,一个View,一个Controller,而且,这些model,view,controller可以独立的改变,就是当组件正在被使用的时候也是如此。这种特性使得开发GUI界面的工具包显得非常的灵活。
  好,来吧,让我来告诉你它是如何工作的。
  MVC设计模式
  就象我刚才指出的一样,MVC设计模式把一个软件组件区分为三个不同的部分,model,view,controller。
Swing看透MVC设计模式[转]" style="CURSOR: pointer" alt="通过Java Swing看透MVC设计模式[转]" src="http://www.gyct.net/article/UploadPic/2006-12/2006122142746253.gif" align=center vspace=1 border=1 >
  Model是代表组件状态和低级行为的部分,它管理着自己的状态并且处理所有对状态的操作,model自己本身并不知道使用自己的view和controller是谁,系统维护着它和view之间的关系,当model发生了改变系统还负责通知相应的view。
  View代表了管理model所含有的数据的一个视觉上的呈现。一个Model可以有一个以上的View,但是Swing中却很少有这样的情况。
  Controller管理着model和用户之间的交互的控制。它提供了一些方法去处理当model的状态发生了变化时的情况。
  使用键盘上的按钮的例子来说明一下:Model就是按钮的整个机械装置,View/Controller就是按钮的表面部分。
  下面的图解释了如何把一个JFC开发的用户界面分为model,view,controller,注意,view/Controller被合并到了一起,这是MVC设计模式通常的用法,它们提供了组件的用户界面(UI)。
Swing看透MVC设计模式[转]" style="CURSOR: pointer" alt="通过Java Swing看透MVC设计模式[转]" src="http://www.gyct.net/article/UploadPic/2006-12/2006122142746854.gif" align=center vspace=1 border=1 >
用Button的例子详细说明
  为了更好的理解MVC设计模式和Swing用户界面组件之间的关系,让我们更加深入的进行分析。我将采用最常见的组件button来说明。
  我们从model来开始。
  Model
  一个按钮的model所应该具备的行为由一个接口ButtonModel来完成。一个按钮model实例封装了其内部的状态,并且定义了按钮的行为。它的所有方法可以分为四类:
  1、查询内部状态
  2、操作内部状态
  3、添加和删除事件监听器
  4、发生事件
  其他的用户界面组件有它们各自的与组件相关的Model,但是所有的组件Model都提供这四类方法。
  View & Controller
  上面的图中讲述一个按钮的view/controller由一个接口ButtonUI完成。如果一个类实现了这个接口,那么它将会负责创建一个用户界面,处理用户的操作。它的所有方法可以被分为三大类:
  1、绘制Paint
  2、返回几何类型的信息
  3、处理AWT事件
  其他用户界面组件有他们自己的组件相关的View/Controller,但是他们都提供上述三类方法。
  程序员通常并不会直接和model以及view/controller打交道,他们通常隐藏于那些继承自java.awt.Component的组件里面了,这些组件就像胶水一样把MVC三者合三为一。也正是由于这些继承的组件对象,一个程序员可以很方便的混合使用Swing组件和AWT组件,然后,我们知道,Swing组件有很多都是直接继承自相应的AWT组件,它能提供比AWT组件更加方便易用的功能,所以通常情况下,我们没有必要混合使用两者。
  一个实例
  现在我们已经明白了Java类与MVC各个部分的对应关系,我们可以更加深入一点去分析问题了。下面我们将要讲述一个小型的使用MVC模式开发的例子。因为JFC十分的复杂,我只能把我的例子局限于一个用户界面组件里面(如果你猜是一个按钮的例子,那么你对了!)
  让我们来看看这个例子的所有部分吧。
  Button类
  最显而易见的开始的地方就是代表了按钮组件本省的代码,因为这个类是大部分程序员会接触的。
  就像我前面提到的,按钮用户界面组件类实际上就是model和view/controller的之间的黏合剂。每个按钮组件都和一个model以及一个controller关联,model定义了按钮的行为,而view/controller定义了按钮的表现。而应用程序可以在任何事件改变这些关联。让我们看看得以实现此功能的代码。




public void setModel(ButtonModel buttonmodel)
{
 if (this.buttonmodel != null)
 {
  this.buttonmodel.removeChangeListener(buttonchangelistener);
  this.buttonmodel.removeActionListener(buttonactionlistener);
  buttonchangelistener = null;
  buttonactionlistener = null;
 }
 this.buttonmodel = buttonmodel;
 if (this.buttonmodel != null)
 {
  buttonchangelistener = new ButtonChangeListener();
  buttonactionlistener = new ButtonActionListener();
  this.buttonmodel.addChangeListener(buttonchangelistener);
  this.buttonmodel.addActionListener(buttonactionlistener);
 }
 updateButton();
}
public void setUI(ButtonUI buttonui)
{
 if (this.buttonui != null)
 {
  this.buttonui.uninstallUI(this);
 }
 this.buttonui = buttonui;
 if (this.buttonui != null)
 {
  this.buttonui.installUI(this);
 }
 updateButton();
}
public void updateButton()
{
 invalidate();
}

  在进入下一节之前,你应该多花一些时间来仔细阅读一下Button类的源代码。
ButtonModel类
  ButtonModel维护着三种类型的状态信息:是否被按下(pressed),是否“武装上了”(armed),是否被选择(selected)。它们都是boolean类型的值。
  一个按钮被按下(pressed)是指当鼠标在按钮上面的时候,按下鼠标但是还没有松开鼠标按钮的状态,及时用户此时把鼠标拖拽到按钮的外面也没有改变这种状态。
  一个按钮是否“武装了”(armed)是指按钮被按下,并且鼠标还在按钮的上面。
  一些按钮还可能被选择(selected),这种状态通过重复的点击按钮取得true或者false的值。
  下面的代码是状态pressed的一个缺省的实现。状态armed以及selected实现的代码与之类似。ButtonModel类应该被继承,这样可以覆盖缺省的状态定义,实现有个性的按钮。
private boolean boolPressed = false;
public boolean isPressed()
{
 return boolPressed;
}
public void setPressed(boolean boolPressed)
{
 this.boolPressed = boolPressed;
 fireChangeEvent(new ChangeEvent(button));
}

  按钮的模型button model还负责通知其他对象(事件监听器)它们所感兴趣的事件。从下面的代买中我们可以看出当按钮的转台发生改变的时候就会发出一个ChangeEvent。下面就是代码:
private Vector vectorChangeListeners = new Vector();
public void addChangeListener(ChangeListener changelistener)
{
 vectorChangeListeners.addElement(changelistener);
}
public void removeChangeListener(ChangeListener changelistener)
{
 vectorChangeListeners.removeElement(changelistener);
}
protected void fireChangeEvent(ChangeEvent changeevent)
{
 Enumeration enumeration = vectorChangeListeners.elements();
 while (enumeration.hasMoreElements())
 {
  ChangeListener changelistener =(ChangeListener)enumeration.nextElement();
  changelistener.stateChanged(changeevent);
 }
}

  在进入下一节之前,你应该多花一些时间来仔细阅读一下ButtonModel类的源代码。
  ButtonUI类
  按钮的view/controller是负责构建表示层的。缺省情况下它仅仅是用背景色画一个矩形而已,他们的子类继承了他们并且覆盖了绘制的方法,使得按钮可以有许多不同的表现,例如MOTIF,soft/" class="wordstyle">Windows 95,Java样式等等。
public void update(Button button, Graphics graphics)
{
}
public void paint(Button button, Graphics graphics)
{
 Dimension dimension = button.getSize();
 Color color = button.getBackground();
 graphics.setColor(color);
 graphics.fillRect(0, 0, dimension.width, dimension.height);
}

  ButtonUI类并不自己处理AWT事件,他们会使用一个定制的事件监听器把低级的AWT事件翻译为高级的Button模型期望的语义事件。下面就是安装/卸载事件监听器的代码。
private static ButtonUIListener buttonuilistener = null;
public void installUI(Button button)
{
 button.addMouseListener(buttonuilistener);
 button.addMouseMotionListener(buttonuilistener);
 button.addChangeListener(buttonuilistener);
}
public void uninstallUI(Button button)
{
 button.removeMouseListener(buttonuilistener);
 button.removeMouseMotionListener(buttonuilistener);
 button.removeChangeListener(buttonuilistener);
}

  View/Controller实际上就是一些方法。他们不维护任何自己的状态信息。因此,许多按钮的实例可以共享一个ButtonUI实例。ButtonUI是通过在方面的参数列表里面加上按钮的引用来区分各个不同的按钮。
  同样,希望你能多花一些时间来看看ButtonUI类,然后咱们进入下一节。
  ButtonUIListener类
  ButtonUIListener类可以帮助Button类去转变鼠标或者键盘的输入为对按钮模型的操作。这个监听器类实现了:MouseListener,MouseMotionListener,ChangeListener接口,并且处理一下事件:
public void mouseDragged(MouseEvent mouseevent)
{
 Button button = (Button)mouseevent.getSource();
 ButtonModel buttonmodel = button.getModel();
 if (buttonmodel.isPressed())
 {
  if (button.getUI().contains(button, mouseevent.getPoint()))
  {
   buttonmodel.setArmed(true);
  }
  else
  {
   buttonmodel.setArmed(false);
  }
 }
}
public void mousePressed(MouseEvent mouseevent)
{
 Button button = (Button)mouseevent.getSource();
 ButtonModel buttonmodel = button.getModel();
 buttonmodel.setPressed(true);
 buttonmodel.setArmed(true);
}
public void mouseReleased(MouseEvent mouseevent)
{
 Button button = (Button)mouseevent.getSource();
 ButtonModel buttonmodel = button.getModel();
 buttonmodel.setPressed(false);
 buttonmodel.setArmed(false);
}
public void stateChanged(ChangeEvent changeevent)
{
 Button button = (Button)changeevent.getSource();
 button.repaint();
}

  总结
  我希望你能按照上面讲述的方法去做。如果不能,那么所有的努力都将白费。这个例子以及Swing用户界面组件的好处在于你不用去花时间去弄明白他们底层是如何设计实现的就可以很方便的使用他们了。


分享到:
评论

相关推荐

    通过JavaSwing看透MVC设计模式PPT学习教案.pptx

    在Swing的实现中,MVC模式不仅用于整个GUI的设计,也应用于单个组件,如JTable、JTree、JComboBox等。\n\n**Model(模型)**\n模型是组件状态和低级别行为的代表,它负责管理自身状态并处理对状态的修改。模型本身并...

    在Java Swing中实现MVC设计模式(英文)

    在Java Swing中实现MVC...以上所述的MVC模式在Java Swing应用中的实现,不仅体现了设计模式在实际编程中的运用,而且还展示了如何将面向对象的原则应用到图形用户界面编程中,进而构建出结构清晰、便于维护的软件系统。

    java课程设计作业-模仿大富翁游戏,使用Java Swing (GUI) 实现的单机游戏,遵循MVC设计模式

    java课程设计作业——模仿大富翁游戏,使用Java Swing (GUI) 实现的单机游戏,遵循MVC设计模式 A Java Swing (GUI) game. 单机版的大富翁游戏,纯Java实现,采用MVC设计模式。 所有素材来自 大富翁客户端+冒险岛...

    auto_order.rar_JAVA Swing mvc_mvc java swing_swing mvc_swing mvc

    标签"java_swing_mvc mvc_java_swing swing_mvc swing_mvc_de"进一步强调了主题,涵盖了Java Swing与MVC模式的结合,以及可能涉及的解构(decomposition)过程,这是将MVC模式应用到代码中的关键步骤。 在压缩包的...

    java swing的mvc模式的简单框架

    通过使用Java Swing的MVC模式,开发者可以更轻松地维护和扩展GUI应用,因为模型、视图和控制器之间的职责清晰,互不干扰。这种设计模式还有助于提高代码的可重用性和可测试性,使得软件更容易适应未来的需求变化。...

    Java Swing MVC使用.rar

    在Java Swing中应用MVC模式,可以提升GUI应用程序的可读性和可维护性。 1. **Model(模型)** Model是应用程序的核心部分,负责管理数据和业务逻辑。在Swing中,一个`JTable`或`JList`可以作为一个模型,它们分别...

    java swing mvc设计模式 分层思想 自助订餐系统

    Java Swing MVC设计模式与分层思想在自助订餐系统中的应用 Java Swing 是Java平台上的一个图形用户界面(GUI)工具包,它为开发者提供了一系列组件来构建桌面应用程序。在这个自助订餐系统中,开发人员利用Swing...

    Java-Swing-MVC使用

    ### Java Swing MVC ...通过以上示例,我们可以看到Java Swing中实现MVC架构的具体过程。这种架构模式使得代码结构更加清晰,也提高了代码的可维护性和扩展性。在实际项目中,可以根据具体需求进行适当的调整和优化。

    java Swing MVC 实例

    在这个实例中,我们将深入探讨Swing MVC模式的各个方面。 首先,Swing是Java的一个图形用户界面(GUI)工具包,它提供了丰富的组件和功能来创建桌面应用程序。MVC(Model-View-Controller)模式是一种软件设计模式...

    JAVA数据库MVC设计模式

    **标题与描述解析** 标题“JAVA数据库MVC设计模式”提到了两个主要概念:Java编程语言和MVC(Model-View-Controller)设计模式。...通过这个项目,开发者可以深入理解Java GUI编程、JDBC数据库操作以及MVC模式的应用。

    JAVA swing (MVC)FTP客户端 (2)_javaftp客户端_familiarku3_

    总的来说,这个“JAVA Swing (MVC) FTP客户端”项目涵盖了Java GUI编程、网络通信、MVC设计模式等多个关键知识点,为学习和实践提供了有价值的实例。通过这个项目,开发者不仅可以掌握Swing的用法,还能深入理解FTP...

    swing中mvc模式

    Swing是Java GUI库的一部分,它提供了一套丰富的组件用于构建桌面应用程序。在设计复杂的用户界面时,模型-视图-控制器(Model-View-...通过理解和应用Swing中的MVC模式,可以创建出更专业、更易维护的桌面应用程序。

    javaswing课程设计——课程表

    此外,可以利用MVC(Model-View-Controller)设计模式来组织代码,将数据模型、用户界面和业务逻辑分离,提高代码的可维护性和可扩展性。 总的来说,这个课程设计项目将涵盖Java GUI编程、数据库操作、数据持久化等...

    java swing漂亮界面(超酷) javaswing教程

    本教程“Java Swing漂亮界面(超酷) Java Swing教程”着重于如何利用Swing来设计吸引人的、用户友好的GUI。在实际开发中,良好的界面设计能够极大地提升用户的使用体验,从而增加软件的吸引力。 首先,Swing提供了...

    (java swing毕业设计)学生信息管理(文档+视频+源码).zip

    (java swing毕业设计)学生信息管理(文档+视频+源码)(java swing毕业设计)学生信息管理(文档+视频+源码)(java swing毕业设计)学生信息管理(文档+视频+源码)(java swing毕业设计)学生信息管理(文档+视频+源码)(java ...

    输出MVC设计模式中MVC分别代表什么意思以及在java中的具体体现1

    * 桌面应用:MVC设计模式也可以应用于桌面应用程序中,例如Java Swing应用程序。 * 移动应用:MVC设计模式也可以应用于移动应用程序中,例如 Android 和 iOS 应用程序。 MVC设计模式是一种常用的软件设计模式,广泛...

    基于Java Swing + MySQL的图书管理系统,优秀Java毕业设计系统,小白必看!

    基于Java Swing + MySQL的图书管理系统,优秀Java毕业设计系统,小白必看! 基于Java Swing + MySQL的图书管理系统,优秀Java毕业设计系统,小白必看! 基于Java Swing + MySQL的图书管理系统,优秀Java毕业设计系统...

    java swing漂亮界面 超酷 javaswing教程

    在“Java Swing漂亮界面 超酷 JavaSwing教程”中,我们主要会探讨如何利用Swing来设计美观且用户友好的界面。Swing组件的一大优点是它们是轻量级的,这意味着它们完全由Java代码实现,而不是依赖于操作系统提供的...

Global site tag (gtag.js) - Google Analytics