點(diǎn)擊查看:2015計(jì)算機(jī)等級考試二級Java入門教程章節(jié)匯總
點(diǎn)擊查看:2015計(jì)算機(jī)等級考試二級Java入門教程第十四章匯總
14.1 使用模式/視圖技術(shù)
在我們開始繪制一個(gè)草圖之前需要提出一個(gè)概念,這就是在Sktche程序中將增加打算如何管理一張草圖的數(shù)據(jù),因?yàn)檫@會影響處理事件的位置和方式。我們已經(jīng)定義了一個(gè)應(yīng)用程序窗口類Sketcher,但是這個(gè)類并不是存儲草圖基本數(shù)據(jù)的最佳地方。有的時(shí)候我們希望把草圖保存在一個(gè)文件中,串行化是最簡單的實(shí)現(xiàn)方式。如果我們打算使用串行化存儲一張草圖,那么在實(shí)現(xiàn)SketchFrame類時(shí)就不必把所有的東西與建立Sketch的有關(guān)數(shù)據(jù)混在一起。另外,如果我們從GUI定義中分離出定義草圖的基本數(shù)據(jù),就會使程序更容易實(shí)現(xiàn)。這又回到了我們在第11章中提到的MVC技術(shù),它被應(yīng)用于Swing組件額度定義中。
理論上,我們應(yīng)該為此目的特別地設(shè)計(jì)一個(gè)類來管理草圖數(shù)據(jù),這個(gè)類就是草圖模式。
表示模式類中數(shù)據(jù)的視圖類(viem)將顯示草圖并處理用戶交互,因此,這個(gè)類將組合瀏覽功能和草圖的控制器。通常,GUI的建立和操作并不特別指定在SketchFrame類中我們將要處理的視圖。這不僅是我們在Sketcher程序中實(shí)現(xiàn)操作的方法,而且也是一種很好的途徑。
模式對象將包含構(gòu)成草圖文本和圖形的混合體。我們將調(diào)用模式類SketchModel及描述這個(gè)模式的視圖類SketchView,但在下一章,我們才把視圖加到程序中。下面的示意圖將說明在Sketcher中類之間的關(guān)系。
應(yīng)用程序?qū)ο髮⑷尕?fù)責(zé)管理程序中所包含的各種對象之間的連接。只要應(yīng)用程序類擁有使每個(gè)對象都可用的方法,任何可訪問應(yīng)用程序?qū)ο蟮膶ο蠖伎梢耘c任何其他的對象進(jìn)行通信,因此應(yīng)用程序扮演了一個(gè)對象之間通信的通道角色。
注意,SketchFrame不是視圖類,它只定義應(yīng)用程序窗口和與之關(guān)聯(lián)的GUI組件。當(dāng)我們在下一章中創(chuàng)建SketchView對象時(shí),將把SketchView對象插入到SketschFrame對象的內(nèi)容窗格中,并使用布局管理器來管理內(nèi)容窗格。由于視圖類的定泛獨(dú)立于應(yīng)用程序類。所以我們從菜單中分離出了草圖視圖和用來與應(yīng)用程序進(jìn)行交互的其他組件。這樣做的好處是顯不文檔的區(qū)域可以獨(dú)立于應(yīng)用程序窗口而擁有自己的坐標(biāo)系統(tǒng)。
為了在Sketcher中實(shí)現(xiàn)模式/視圖結(jié)構(gòu),我們需要為模式和視圖定義相應(yīng)的類,至少是一個(gè)框架。包含定義草圖數(shù)據(jù)的類可以定義成這種結(jié)構(gòu)形式:
import java.util;
class sketchModel extends observable
{
//Detail of the rest of class to be filled in later...
}
顯然在這個(gè)類中會有很多操作要做,我們將在以后逐漸將它們添加進(jìn)來。由于這個(gè)類擴(kuò)展了()Observable類,所以可以利用它把視圖類注冊為一個(gè)觀察器,并自動地通告所有的發(fā)生變化的視圖。在有多個(gè)視圖時(shí),這個(gè)工具將得到視圖自己的內(nèi)容。
我們可以把視圖類定義為派生于JComponent的組件。這樣將會內(nèi)置組件操作的所有方法,若需要的話,可以重載其中的任何一個(gè)方法。視圖類也需要實(shí)現(xiàn)fObjectveru接口以便可以用模式對它進(jìn)行注冊。這是一個(gè)框架:
import javax.swing.*;
import java.util,*; //For observer
calss sketchview extends JComponent
implements Observer
{
public SketchView(Skctcher theApp)
{
this.theApp=theApp;
}
//Method called by Observable object when it changes
public void update(Observable o,object rectangle)
{
//code to respond to changes in the model...
}
private Sketcher theApp; //The application object
}
為了顯示模式的內(nèi)容,視圖肯定需要對它進(jìn)行訪問,因此構(gòu)造函數(shù)要有一個(gè)自變量負(fù)責(zé)把應(yīng)用程序?qū)ο髠鬟f給它。由于在視圖中存儲的是應(yīng)用程序?qū)ο螅皇悄J降囊,并且添加到?yīng)用程序?qū)ο笾械囊粋(gè)方法可返回模式的引用,所以我們可以讓視圖對象獨(dú)立于模式對象。如果模式表示了一個(gè)完全不同的對象,比如加載了一個(gè)新文件。我們并不需要改變視圖對象,只要新模式把視圖注冊為觀察器,視圖就會在發(fā)生變化的模式通告時(shí)自動地重畫草圖。
為了把模式與它的視圖集成到Sketcher應(yīng)用程序中,我們需要為Stetcher類增加一些代碼:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Sketcher
{
public static void main(String[] args)
{
theApp = new Sketcher(); // Create the application object
theApp.init(); // ... and initialize it
}
public void init()
{
window = new SketchFrame("Sketcher", this); // Create the app window
Toolkit theKit = window.getToolkit(); // Get the window toolkit
Dimension wndSize = theKit.getScreenSize(); // Get screen size
// Set the position to screen center & size to 2/3 screen size
window.setBounds(wndSize.width/6, wndSize.height/6, // Position
2*wndSize.width/3, 2*wndSize.height/3); // Size
window.addWindowListener(new WindowHandler()); // Add window listener
sketch = new SketchModel(); // Create the model
view = new SketchView(this); // Create the view
sketch.addObserver((Observer)view); // Register the view with the model
window.getContentPane().add(view, BorderLayout.CENTER);
window.setVisible(true);
}
// Return a reference to the application window
public SketchFrame getWindow()
{
return window;
}
// Return a reference to the model
public SketchModel getModel()
{
return sketch;
}
// Return a reference to the view
public SketchView getView()
{
return view;
}
// Handler class for window events
class WindowHandler extends WindowAdapter
{
// Handler for window closing event
public void windowClosing(WindowEvent e)
{
window.dispose(); // Release the window resources
System.exit(0); // End the application
}
}
private SketchModel sketch; // The data model for the sketch
private SketchView view; // The view of the sketch
private static SketchFrame window; // The application window
private static Sketcher theApp; // The application object
}
SketchFrame構(gòu)造函數(shù)需要做如下修改:
public SketchFrame(String title, Sketcher theApp)
{
setTitle(title); // Set the window title
this.theApp = theApp;
// Rest of the constractor as before…
}
需要在SketchFrarme類中增加theApp變量。
private Stretcher theApp.s
在Sketcher類中有些返回應(yīng)用程序窗口、模式和視圖引用的新方法,這些方法的每個(gè)都可從能夠引用應(yīng)用程序的地方訪問。
建立了模式和視圖對象之后,我們把視圖注冊為模式的觀察器這樣使模式發(fā)生變化時(shí)能夠通知給視圖。然后,我們將View添加到Window對象的內(nèi)容窗格中,這是主應(yīng)用程序窗口。由于內(nèi)容窗格的BorderLayout管理器把它加到了中心,所以view將占據(jù)窗格中其余的所有空間。
現(xiàn)在,我們粗略地知道了前進(jìn)的方向,讓我們上路,繼續(xù)前進(jìn)。
相關(guān)推薦:
2015計(jì)算機(jī)等級考試二級Java入門教程章節(jié)匯總
北京 | 天津 | 上海 | 江蘇 | 山東 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
廣東 | 河北 | 湖南 | 廣西 | 河南 |
海南 | 湖北 | 四川 | 重慶 | 云南 |
貴州 | 西藏 | 新疆 | 陜西 | 山西 |
寧夏 | 甘肅 | 青海 | 遼寧 | 吉林 |
黑龍江 | 內(nèi)蒙古 |