加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

java 实验(五) GUI程序设计

(2010-12-01 10:41:07)
分类: 大学实验报告

一、实验目的和要求

1. 掌握基本GUI部件的使用

2. 理解并掌握GUI事件驱动的程序设计

3. 理解并掌握MVC(模型-视图-控制器)模式

二、实验内容和原理
http://s10/middle/6ea6cd6a496503bc82109&690

采用MVC的方式重新实现地址薄维护程序。界面如图1所示:

图1 地址薄应用程序的用户界面

MVC三者之间的关系可参考图2。视图类AddressBookJFrame中的方法setAddress用于将参数的值在界面上显示,而方法getAddress()用于将界面上的值生成一个Address类型的对象。在控制器AddressBookController中有相应的实现了ActionListerner接口的类(如图3),用来侦听视图中相应命令按钮的事件,视图中的一类add方法(如addAddActionListerner)用于注册侦听器。对模型,书中的例子是用随机访问文件,你可以使用数据库,通过JDBC建立与数据库的连接;也可以用顺序文本文件,先把文件读入到一个Collection(如ArrayList)中,再在从集合上读指定位置记录,或者把记录添加到集合中,最后再把集合中的数据写入文件中。

三、实验环境

1. 硬件环境:

2. 软件环境:JDK1.5

图2 模型-视图-控制器参考实现图

class AddActionListener implements ActionListener {

public void actionPerformed(ActionEvent e) {

Address address;

try {

address = addressBookJFrame.getAddress();

addressBookModel.writeAddress(address);

} catch (IOException ex) {

ex.printStackTrace();

}

}

}

class FirstActionListener implements ActionListener {

public void actionPerformed(ActionEvent e) {

Address address;

try {

address = addressBookModel.readFirst();

addressBookJFrame.setAddress(address);

} catch (IOException ex) {

ex.printStackTrace();

}

}

}

图3 侦听Add按钮和First按钮的侦听器例

四、算法描述及实验步骤

1. 算法描述(可以用类图、流程图、伪代码或源程序描述)

http://s11/middle/6ea6cd6a496503bfeec7a&690

2. 实验步骤

l 分别为问题设计模型类、视图类和控制类

l 进行编译

l 进行测试,使用的测试用例:

输入: 预期输出:

五、调试过程

1. 编译过程

(1)、返回语句之后的语句无法执行:

return readAddress(currentPosition); FixedLengthStringDB.getRst().absolute(length - 1);因为return语句执行完了之后,就直接返回而不会执行下面的语句。

改正:把下面的语句直接删掉,因为放在return语句之前就失去意义了。

2. 调试过程

(1)、读完最后一条语句之后无法停止读取而是读取第一条记录。这是因为读完只有一条语句之后,结果集指向的位置为rst.afterLast(),而对应的位置的行号为rst.getRow()的值为0,在直径rst.next();之后又会循环读取记录。

改正:改变readFixedLengthString(int position, String columnName)方法中的部分代码:

原来:else {

rst.absolute(position);

rst.next();

}

改成:else {

rst.absolute(position);

str = rst.getString(1);

if (position != getLengthOfRow()) {

rst.absolute(position);

rst.next();

}

这样子改是为了判断是否已经读到最后一条记录,如果是的话,就不执行rst.next();语句,而rst.absolute(position);语句则是把指针设为原来的位置,然后再执行rst.next();因为getLengthOfRow()已经把指针放到末尾了所以要重新设位置。

(2)、读到最后一条记录,然后往回读的过程中,倒数第二条记录被隐藏掉,不能读取。原因是通过上面的修改,读取最后一条记录时,并没有执行rst.next();语句,而在readPrevious()方法中返回值为return readAddress(currentPosition - 2);这就直接导致倒数第二条记录无法读取。

改正:在原来的基础上加上else if语句,如下所示:

if (currentPosition > 1 && currentPosition!=length){

return readAddress(currentPosition - 2);

}

else if(currentPosition == length)

return readAddress(currentPosition - 1);

使得读取最后一条记录时返回值为:return readAddress(currentPosition - 1);

六、实验结果

输入:往数据库增加5条记录,具体内容如下:

+--------------+------------+-----------+--------+--------+

| studentName | street | city | state | zip |

+--------------+------------+-----------+--------+--------+

| ganwenxin | zhetiaojie | nanping | fujian | 125478 |

| huangronghan | natiaojie | zhangzhou | fujian | 123547 |

| huangzhitan | natiaojie | putian | fujian | 356214 |

| liteng | natiaojie | zhangzhou | fujian | 145269 |

| xuyouliang | natiaojie | xiamen | fujian | 123654 |

+--------------+------------+-----------+--------+--------+

在界面中进行查找:

点First按钮:

http://s2/middle/6ea6cd6a496503c0c0951&690

点Next按钮:

http://s10/middle/6ea6cd6a496503c789599&690

点Last按钮:

http://s11/middle/6ea6cd6a496503c88c22a&690

点Previous按钮:

http://s10/middle/6ea6cd6a496503c978f99&690

增加操作:加入一条记录,xuqihong zhetiaojie quanzhou fujian 125478

这是数据库就多出一条记录:

http://s1/middle/6ea6cd6a496503ca4b1e0&690

在界面上也可以找到记录:

http://s9/middle/6ea6cd6a496503caac5c8&690

结果分析:结果正确

七、总结

通过这次上机实验,我主要学到以下内容:

(1)、使用MVC的设计模式,同个这种设计模式,把视图层,模式层,控制层分开了,能够更清晰的进行设计,并且带来良好的扩展性。

(2)、巩固了GUI的知识,并且对GUI的相关应用更加熟悉,比如说三种常用的布局管理器,如何把组件添加到容器中,并设置组件的属性等。

(3)、掌握了对事件的处理,如何给按钮添加事件。

(4)、在这次实验中,实验涉及的范围很广,设计的灵活性也较高,特别是将数据库与界面之间进行关联,通过各种方法来传递值,在这次实验中,更重要的是获得程序设计上的经验。

这次实验,还存在很清晰,特别是数据库方面的内容,比如说程序中ResultSet这个类,以下几点不足:

(1)、逻辑不是类里面的方法很多,但是要通过选择这些适合的方法来进行设计却不容易,很容易出现BUG。

(2)、对知识的综合应用的能力还欠缺,设计的时候经常拆东墙补西墙,一个BUG修护好了,又有新的问题出现。

附录:

package com.john.project5;

public class Address {

// Specify the size of five string fields in the record

final static int NAME_SIZE = 32;

final static int STREET_SIZE = 32;

final static int CITY_SIZE = 12;

final static int STATE_SIZE = 5;

final static int ZIP_SIZE = 5;

final static int RECORD_SIZE =

(NAME_SIZE + STREET_SIZE + CITY_SIZE + STATE_SIZE + ZIP_SIZE);

private String name;

private String street;

private String city;

private String state;

private String zip;

public Address() {

this("","", "", "", "");

}

public Address(String name, String street, String city,

String state, String zip) {

this.setName(name);

this.setStreet(street);

this.setCity(city);

this.setState(state);

this.setZip(zip);

}

public String getName() {

return name;

}

public void setName(String name) {

name = name.trim();

this.name = name;

}

public String getStreet() {

return street;

}

public void setStreet(String street) {

this.street = street;

}

public String getCity() {

return city;

}

public void setCity(String city) {

this.city = city;

}

public String getState() {

return state;

}

public void setState(String state) {

this.state = state;

}

public String getZip() {

return zip;

}

public void setZip(String zip) {

this.zip = zip;

}

public String getFullAddress() {

return street + '\n' + city + ", " + state + ' ' + zip + '\n';

}

}

package com.john.project5;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JTextField;

import javax.swing.JLabel;

import javax.swing.border.BevelBorder;

import java.awt.GridLayout;

import java.awt.BorderLayout;

import java.io.IOException;

import java.sql.SQLException;

public class AddressBookJFrame extends JFrame{

//存储的默认情况下为e:\new_raf.sql

private AddressBookModelRAF abm = new AddressBookModelRAF();

private Address address = new Address();

//类属性 5个文本框 + 5个按钮

//创建文本框,用于显示Name\Sreeet\City\State\Zip

private JTextField jtfName = new JTextField(Address.NAME_SIZE);

private JTextField jtfStreet = new JTextField(Address.STREET_SIZE);

private JTextField jtfCity = new JTextField(Address.CITY_SIZE);

private JTextField jtfState = new JTextField(Address.STATE_SIZE);

private JTextField jtfZip = new JTextField(Address.ZIP_SIZE);

//创建按钮

private JButton jbtAdd = new JButton("Add");

private JButton jbtFirst = new JButton("First");

private JButton jbtNext = new JButton("Next");

private JButton jbtPrevious = new JButton("Previous");

private JButton jbtLast = new JButton("Last");

//类方法

//构造方法

public AddressBookJFrame(){

//初始化数据库连接

FixedLengthStringDB db = new FixedLengthStringDB();

System.out.println(" *****数据库连接成功***** ");

//调用事件侦听器的函数,使按钮产生相应事件

add_All_ActionListener();

System.out.println("*****添加事件侦听器成功*****");

//调用initComponents方法,使容器用户界面可以显示

initComponents();

System.out.println(" ****用户界面加载成功**** ");

}

//用于设计应用程序的窗口界面

private void initComponents(){

//生成Zip模块

JPanel zip = new JPanel();

zip.add(new JLabel("Zip"),new BorderLayout().WEST);

zip.add(jtfZip,new BorderLayout().CENTER);

//生成State模块

JPanel state = new JPanel();

state.add(new JLabel("State"),new BorderLayout().WEST);

state.add(jtfState,new BorderLayout().CENTER);

JPanel z_s = new JPanel();

z_s.add(state,new BorderLayout().WEST);

z_s.add(zip,new BorderLayout().CENTER);

JPanel city = new JPanel();

city.add(new JLabel("City "),new BorderLayout().WEST);

city.add(jtfCity,new BorderLayout().CENTER);

JPanel z_s_City = new JPanel();

z_s_City.add(city,new BorderLayout().CENTER);

z_s_City.add(z_s,new BorderLayout().EAST);

JPanel street = new JPanel();

street.add(new JLabel("Street"),new BorderLayout().WEST);

street.add(jtfStreet,new BorderLayout().CENTER);

JPanel name = new JPanel();

name.add(new JLabel("Name"),new BorderLayout().EAST);

name.add(jtfName,new BorderLayout().CENTER);

JPanel show_Panel = new JPanel(new GridLayout(3,1,0,0));

show_Panel.add(name);

show_Panel.add(street);

show_Panel.add(z_s_City);

//

show_Panel.setBorder(new BevelBorder(BevelBorder.RAISED));

JPanel control_Panel = new JPanel();

control_Panel.add(jbtAdd);

control_Panel.add(jbtFirst);

control_Panel.add(jbtNext);

control_Panel.add(jbtPrevious);

control_Panel.add(jbtLast);

JPanel window = new JPanel();

window.add(show_Panel,new BorderLayout().CENTER);

window.add(control_Panel,new BorderLayout().SOUTH);

//添加部件window,使之可以在程序运行后显示在窗口中

add(window);

}

public void setAddress(Address address){

jtfName.setText(address.getName());

jtfStreet.setText(address.getStreet());

jtfCity.setText(address.getCity());

jtfState.setText(address.getState());

jtfZip.setText(address.getZip());

}

public void getAddress(){

//把文本框的值以字符串的形式传递到Address类中相应的属性

address.setName(jtfName.getText());

address.setStreet(jtfStreet.getText());

address.setCity(jtfCity.getText());

address.setState(jtfState.getText());

address.setZip(jtfZip.getText());

// return address;

}

//创建5个按钮的侦听器,使单击按钮时产生相应的事件

public void add_All_ActionListener(){

//Add按钮

jbtAdd.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e){

try {

getAddress();

abm.writeAddress(address);

Address newAddress = new Address();

setAddress(newAddress);

} catch (SQLException e2) {

e2.printStackTrace();

}

};

});

//First按钮

jbtFirst.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e){

try {

address = abm.readFirst();

setAddress(address);

} catch (SQLException e1) {

e1.printStackTrace();

}

};

});

//Next按钮

jbtNext.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e){

try {

address = abm.readNext();

setAddress(address);

} catch (SQLException e1) {

e1.printStackTrace();

}

};

});

//Previous按钮

jbtPrevious.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e){

try {

address = abm.readPrevious();

setAddress(address);

} catch (SQLException e1) {

e1.printStackTrace();

}

};

});

//Last按钮

jbtLast.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e){

try {

address = abm.readLast();

setAddress(address);

} catch (SQLException e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

}

};

});

}

//定义主函数,在主函数中通过创建对象来调用构造函数,使窗体添加

public static void main(String[] args) {

AddressBookJFrame frame = new AddressBookJFrame();

frame.setLocation(200, 150);

frame.setSize(500, 250);

frame.setTitle("Address Book Input Frame");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setVisible(true);

}

}

package com.john.project5;

public abstract class AddressBookModel {

public abstract void writeAddress(Address address) throws Exception ;

public abstract Address readFirst() throws Exception ;

public abstract Address readNext() throws Exception ;

public abstract Address readPrevious() throws Exception;

public abstract Address readLast() throws Exception;

}

package com.john.project5;

import java.io.*;

import java.sql.SQLException;

import javax.swing.JOptionPane;

public class AddressBookModelRAF extends AddressBookModel{

public AddressBookModelRAF() {

}

public void writeAddress(Address address) throws SQLException {

FixedLengthStringDB.writeFixedLengthString(FixedLengthStringDB.toString(address));

}

public Address readFirst() throws SQLException {

return readAddress(0);

}

public Address readNext() throws SQLException {

int currentPosition = FixedLengthStringDB.getRst().getRow();

FixedLengthStringDB.getRst().last();

int length = FixedLengthStringDB.getRst().getRow();

if (currentPosition <= length)

return readAddress(currentPosition);

else{

JOptionPane.showMessageDialog(null,"已经是最后一条记录!");

return readAddress(currentPosition - 1);

}

}

public Address readPrevious() throws SQLException {

int currentPosition = FixedLengthStringDB.getRst().getRow();

int length = FixedLengthStringDB.getLengthOfRow();

FixedLengthStringDB.getRst().absolute(currentPosition);

if (currentPosition > 1 && currentPosition!=length){

return readAddress(currentPosition - 2);

}

else if(currentPosition == length)

return readAddress(currentPosition - 1);

else{

JOptionPane.showMessageDialog(null,"已经是第一条记录!");

return readAddress(0);

}

}

public Address readLast() throws SQLException {

FixedLengthStringDB.getRst().last();

int lastPosition = FixedLengthStringDB.getRst().getRow();

return readAddress(lastPosition);

}

private Address readAddress(int position) throws SQLException{

// int length = FixedLengthStringDB.getLengthOfRow();

if ( position >=0 ) {

String name = FixedLengthStringDB.readFixedLengthString(

position,"studentName");

String street = FixedLengthStringDB.readFixedLengthString(

position,"street");

String city = FixedLengthStringDB.readFixedLengthString(

position,"city");

String state = FixedLengthStringDB.readFixedLengthString(

position,"state");

String zip = FixedLengthStringDB.readFixedLengthString(

position,"zip");

return new Address(name, street, city, state, zip);

} else {

return null;

}

}

}

package com.john.project5;

import java.io.DataInput;

import java.io.DataOutput;

import java.io.IOException;

import java.sql.*;

import javax.sound.midi.SysexMessage;

import javax.swing.JOptionPane;

public class FixedLengthStringDB {

//定义类属性

private static Connection conn;

private static Statement stmt;

private static ResultSet rst;

private static String driverName = new String("com.mysql.jdbc.Driver");

private static String url = new String("jdbc:mysql://localhost/addressBook");

private static String user = new String("john");

private static String password = new String("john");

//定义类方法

//定义构造函数,用于加载数据库

public FixedLengthStringDB() {

initalizeDB();

}

public static ResultSet getRst() {

return rst;

}

private static void initalizeDB() {

try {

//加载驱动

Class.forName(driverName);

System.out.println("驱动器已加载...");

} catch (ClassNotFoundException e) {

System.out.println("驱动器无法加载,请检查驱动路径是否正确!");

System.out.println(e.getMessage());

}

try {

//建立连接

conn = DriverManager.getConnection(url, user, password);

System.out.println("MySQL连接已建立...");

} catch (SQLException e) {

System.out.println("MySql连接无法建立,请检查连接路径是否正确!");

System.out.println(e.getMessage());

}

try {

//创建Statement

stmt = conn.createStatement();

System.out.println("Statement创建完毕!");

} catch (SQLException e) {

System.out.println("创建Statement的时候出现异常!");

System.out.println(e.getMessage());

}

try {

rst = stmt.executeQuery("select * from Address;");

System.out.println("ResultSet初始化完毕!");

} catch (SQLException e) {

System.out.println("ResultSet初始化异常!");

System.out.println(e.getMessage());

}

}

public static String readFixedLengthString(int position, String columnName)

throws SQLException {

String queryString = "Select " + columnName + " From Address ;";

rst = stmt.executeQuery(queryString);

String str = new String("");

if (position == 0) {

rst.first();

str = rst.getString(1);

rst.next();

} else {

rst.absolute(position);

str = rst.getString(1);

if (position != getLengthOfRow()) {

rst.absolute(position);

rst.next();

}

}

return new String(str);

}

public static String toString(Address address) {

String value = new String("");

value += "('" + address.getName() + "','"

+ address.getStreet() + "','" + address.getCity() + "','"

+ address.getState() + "','" + address.getZip() + "')";

String column = new String("");

column += "(studentName,street,city,state,zip)";

String updateString = "insert into Address" + column + " values "

+ value + ";\n";

return new String(updateString);

}

public static void writeFixedLengthString(String updateString)

throws SQLException {

System.out.println("语句没语法问题!");

try {

stmt.executeUpdate(updateString);

System.out.println("执行语句没有问题!");

} catch (SQLException e) {

JOptionPane.showMessageDialog(null, "无法实现添加功能,请检查Name是否重复!");

System.out.println(e.getMessage());

System.exit(0);

}

}

public static int getLengthOfRow() throws SQLException {

getRst().last();

return rst.getRow();

}

}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有