上圖是一個用Swing刻出來的簡單GUI, 目的是更新Database設定,Mailserver 設定....等等, 這邊GUI是依照Swing 的MVC 架構做出來的, Swing 的MVC包含了以下3個:
Model :包含了資料源和所有基於對這些資料的操作
View :Model 跟UI 介面的顯示
Control:在Model和View之間起到了溝通的作用,處理用戶在View上的輸入,並轉發給Model。這樣Model和View兩者之間可以做到鬆散耦合,甚至可以彼此不知道對方,而由Controller連接起這兩個部分。
在Oracle 的 Java SE Application Design With MVC 提到完整的MVC 細節如下:
GET
andPOST
HTTP requests. Depending on the context, a controller may also select a new view -- for example, a web page of results -- to present back to the user.整個GUI Project 結構如下:
實作是參考 Model-View-Controller (MVC) Structure 而來的。
首先是Model 的部份, 以GUI的Database Setting 來說是一個TabbedPanel裡的Item , 所以Model屬性會包含了所有相關元件的資料, 在這邊就是5種屬性, driverclassname,dburl,dbusername,dbuserpwd,databasetype, 我將這些封裝成一個JavaBean, 在DataBaseSettingModel裡面操作, DataBaseSettingModel針對DbSettingObject 做setter&getter 的動作,get時會從db拿值,set時會update db的資料。
DbSettingObject.java
package com.main.ui.dataobject; public class DbSettingObject { private String driverClassName; private String dbUrl; private String dbUserName; private String dbUserPwd; private String dataBaseType; public DbSettingObject(){ this.driverClassName = ""; this.dbUrl = ""; this.dbUserName = ""; this.dbUserPwd = ""; this.dataBaseType = ""; } public String getDriverClassName() { return driverClassName; } public void setDriverClassName(String driverClassName) { this.driverClassName = driverClassName; } public String getDbUrl() { return dbUrl; } public void setDbUrl(String dbUrl) { this.dbUrl = dbUrl; } public String getDbUserName() { return dbUserName; } public void setDbUserName(String dbUserName) { this.dbUserName = dbUserName; } public String getDbUserPwd() { return dbUserPwd; } public void setDbUserPwd(String dbUserPwd) { this.dbUserPwd = dbUserPwd; } public String getDataBaseType() { return dataBaseType; } public void setDataBaseType(String dataBaseType) { this.dataBaseType = dataBaseType; } @Override public String toString(){ StringBuffer tostring = new StringBuffer(); tostring.append("driverClassName = " driverClassName "\n"); tostring.append("dbUrl = " dbUrl "\n"); tostring.append("dbUserName = " dbUserName "\n"); tostring.append("dbUserPwd = " dbUserPwd "\n"); tostring.append("dataBaseType = " dataBaseType "\n"); return tostring.toString(); } }
DbSettingModel.java
package com.main.ui.model; import java.sql.SQLException; import com.main.dao.IQueryUiObjectDao; import com.main.dao.QueryDatabaseSettingDao; import com.main.ui.dataobject.DbSettingObject; public class DbSettingModel { private DbSettingObject dbObj; private IQueryUiObjectDao<DbSettingObject> queryDao; public DbSettingModel(){ queryDao = new QueryDatabaseSettingDao(); } public DbSettingObject getDbSettingObject(){ try { this.dbObj = queryDao.getDataObject(); } catch (SQLException e) { dbObj = new DbSettingObject(); } return dbObj; } public void setDbSettingObject(DbSettingObject obj){ try { queryDao.setDataObject(obj); } catch (SQLException e) { } this.dbObj = obj; } }
再來是View 的部份, DataBase Setting 的Panel設計如下
一個View Object 是extends JPanel ,建立的相關的UI, 取得或修改UI的顯示,view 會提供Controller 相關的method 來操作。
DbSettingView.java
package com.main.ui.view; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSeparator; import javax.swing.JTextField; import com.main.ui.dataobject.DbSettingObject; import com.main.ui.model.DbSettingModel; public class DbSettingView extends JPanel{ private JLabel passwd; private JLabel databaseType; private JTextField changeDbType; private JTextField changeUserName; private JTextField changePassword; private JTextField changeDbUrl; private JTextField changeDriverClassName; private JButton Save; private JSeparator jSeparator1; private JTextField passwordValue; private JTextField userNameValue; private JTextField dbUrlValue; private JTextField dbTypeValue; private JTextField driverClassNameValue; private JLabel dbUserName; private JLabel dbUrl; private JLabel DriverClassName; private DbSettingModel model ; public DbSettingView(DbSettingModel imodel){ this.model = imodel; initGUI(); initTextValues(); } private void initGUI() { try { { this.setPreferredSize(new java.awt.Dimension(498, 222)); this.setRequestFocusEnabled(false); this.setOpaque(false); this.setLayout(null); { DriverClassName = new JLabel(); this.add(DriverClassName); DriverClassName.setBounds(12, 12, 119, 19); DriverClassName.setText("Driver Class Name:"); } { dbUrl = new JLabel(); this.add(dbUrl); dbUrl.setText("DB Url :"); dbUrl.setBounds(12, 59, 95, 15); } { dbUserName = new JLabel(); this.add(dbUserName); dbUserName.setText("UserName :"); dbUserName.setBounds(12, 81, 95, 15); } { passwd = new JLabel(); this.add(passwd); passwd.setText("Password :"); passwd.setBounds(12, 102, 95, 15); } { databaseType = new JLabel(); this.add(databaseType); databaseType.setText("DB Type :"); databaseType.setBounds(12, 37, 95, 15); } { driverClassNameValue = new JTextField(); this.add(driverClassNameValue); driverClassNameValue.setBounds(143, 11, 146, 22); driverClassNameValue.setEnabled(false); } { dbTypeValue = new JTextField(); this.add(dbTypeValue); dbTypeValue.setBounds(143, 34, 146, 22); dbTypeValue.setEnabled(false); } { dbUrlValue = new JTextField(); this.add(dbUrlValue); dbUrlValue.setBounds(143, 56, 146, 22); dbUrlValue.setEnabled(false); } { userNameValue = new JTextField(); this.add(userNameValue); userNameValue.setBounds(143, 78, 146, 22); userNameValue.setEnabled(false); } { passwordValue = new JTextField(); this.add(passwordValue); passwordValue.setBounds(143, 99, 146, 22); passwordValue.setEnabled(false); } { jSeparator1 = new JSeparator(); this.add(jSeparator1); jSeparator1.setBounds(12, 133, 447, 7); } { Save = new JButton(); this.add(Save); Save.setText("Save"); Save.setBounds(394, 146, 65, 22); } { changeDriverClassName = new JTextField(); this.add(changeDriverClassName); changeDriverClassName.setEnabled(true); changeDriverClassName.setBounds(313, 11, 146, 22); } { changeDbUrl = new JTextField(); this.add(changeDbUrl); changeDbUrl.setEnabled(true); changeDbUrl.setBounds(313, 56, 146, 22); } { changePassword = new JTextField(); this.add(changePassword); changePassword.setEnabled(true); changePassword.setBounds(313, 99, 146, 22); } { changeUserName = new JTextField(); this.add(changeUserName); changeUserName.setEnabled(true); changeUserName.setBounds(313, 78, 146, 22); } { changeDbType = new JTextField(); this.add(changeDbType); changeDbType.setEnabled(true); changeDbType.setBounds(313, 34, 146, 22); } } } catch(Exception e) { e.printStackTrace(); } } private void initTextValues(){ System.out.println("init text values , dbSettingView"); if(this.model != null){ DbSettingObject obj = this.model.getDbSettingObject(); this.dbTypeValue.setText(obj.getDataBaseType()); this.dbUrlValue.setText(obj.getDbUrl()); this.userNameValue.setText(obj.getDbUserName()); this.passwordValue.setText(obj.getDbUserPwd()); this.driverClassNameValue.setText(obj.getDriverClassName()); } } public void changeSetting(DbSettingObject object){ this.dbTypeValue.setText(object.getDataBaseType()); this.dbUrlValue.setText(object.getDbUrl()); this.userNameValue.setText(object.getDbUserName()); this.passwordValue.setText(object.getDbUserPwd()); this.driverClassNameValue.setText(object.getDriverClassName()); } public DbSettingObject getCurrentSettingObject(){ DbSettingObject currentObject = new DbSettingObject(); currentObject.setDataBaseType(this.dbTypeValue.getText()); currentObject.setDbUrl(this.dbUrlValue.getText()); currentObject.setDbUserName(this.userNameValue.getText()); currentObject.setDbUserPwd(this.passwordValue.getText());; currentObject.setDriverClassName(this.driverClassNameValue.getText()); return currentObject; } public void addChangeSettingListener(ActionListener mal){ this.Save.addActionListener(mal); } public JLabel getPasswd() { return passwd; } public JLabel getDatabaseType() { return databaseType; } public JTextField getChangeDbType() { return changeDbType; } public JTextField getChangeUserName() { return changeUserName; } public JTextField getChangePassword() { return changePassword; } public JTextField getChangeDbUrl() { return changeDbUrl; } public JTextField getChangeDriverClassName() { return changeDriverClassName; } public JButton getSave() { return Save; } public JSeparator getjSeparator1() { return jSeparator1; } public JTextField getPasswordValue() { return passwordValue; } public JTextField getUserNameValue() { return userNameValue; } public JTextField getDbUrlValue() { return dbUrlValue; } public JTextField getDbTypeValue() { return dbTypeValue; } public JTextField getDriverClassNameValue() { return driverClassNameValue; } public JLabel getDbUserName() { return dbUserName; } public JLabel getDbUrl() { return dbUrl; } public JLabel getDriverClassName() { return DriverClassName; } }
再來建立Controller , 會傳入model 跟 view, 然後統過Constructor 新增view的listener , 在此操作Model 跟view 的相關動作。
DbSettingController.java
package com.main.ui.controller; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import com.main.ui.dataobject.DbSettingObject; import com.main.ui.model.DbSettingModel; import com.main.ui.view.DbSettingView; public class DbSettingController { private DbSettingModel model; private DbSettingView view; public DbSettingController(DbSettingModel iModel,DbSettingView iView ){ this.model = iModel; this.view = iView; this.view.addChangeSettingListener(new ChangeDbSettingListener()); } class ChangeDbSettingListener implements ActionListener { //Actionlistener for change database setting when "save" button on click public void actionPerformed(ActionEvent e) { DbSettingObject newSettingobject = getNewSettingObject(); DbSettingObject currentSettingObj = view.getCurrentSettingObject(); changeNewSettingObjectValues(newSettingobject, currentSettingObj); model.setDbSettingObject(newSettingobject);//update object & database values view.changeSetting(model.getDbSettingObject());//get object from database } private void changeNewSettingObjectValues(DbSettingObject newSettingobject,DbSettingObject currentSettingObj) { if(newSettingobject.getDriverClassName().length() <= 0){ newSettingobject.setDriverClassName(currentSettingObj.getDriverClassName()); } if(newSettingobject.getDbUrl().length() <= 0){ newSettingobject.setDbUrl(currentSettingObj.getDbUrl()); } if(newSettingobject.getDataBaseType().length() <= 0){ newSettingobject.setDataBaseType(currentSettingObj.getDataBaseType()); } if(newSettingobject.getDbUserName().length() <= 0){ newSettingobject.setDbUserName(currentSettingObj.getDbUserName()); } if(newSettingobject.getDbUserPwd().length() <= 0){ newSettingobject.setDbUserPwd(currentSettingObj.getDbUserPwd()); } } private DbSettingObject getNewSettingObject() { DbSettingObject newSettingobject = new DbSettingObject(); newSettingobject.setDataBaseType(view.getChangeDbType().getText()); newSettingobject.setDbUrl(view.getChangeDbUrl().getText()); newSettingobject.setDbUserName(view.getChangeUserName().getText()); newSettingobject.setDbUserPwd(view.getChangePassword().getText()); newSettingobject.setDriverClassName(view.getChangeDriverClassName().getText()); return newSettingobject; } // private DbSettingObject checkObjectContent(){ // // } } }
當我們的元系都設計好的時候,就可以建立起來
.... .... DbSettingModel dbSettingmodel = new DbSettingModel(); DbSettingView dbSettingPanel = new DbSettingView(dbSettingmodel); DbSettingController controller = new DbSettingController(dbSettingmodel,dbSettingPanel); tabbedPane.addTab("DataBase Setting", icon, dbSettingPanel,"change db setting values"); dbSettingPanel.setPreferredSize(new java.awt.Dimension(551, 211)); ... ...
Reference:
Java SE Application Design With MVC
Model-View-Controller (MVC) Structure
A Swing Architecture Overview
Building Graphical User Interfaces
with the MVC Pattern
Javaworld.com - MVC meets Swing
Javaworld(TW) Swing MVC and Model
沒有留言:
張貼留言