您的位置:首页 > 编程语言 > Java开发

Sphere,java,mvc 计算球的体积和表面积

2011-04-10 10:38 405 查看
mvc模式介绍

•模型-视图-控制器(Model-View-Controller,MVC) 模式将一个交互式应用程序分成3个组件.
–模型:包含核心功能和数据。
–视图:向用户显示信息。
–控制器:处理用户输入。
•视图和控制器组成了用户接口。
•变更-传播机制保证了模型和用户接口之间的一致性。

本文要实现的Java应用程序是当用户在图形化用户界面输入一个球体的半径时,程序将显示该球体的体积与表面积。

•该程序主要由三个类构成:
–Sphere类扮演Model的角色
–TextView类为View角色
SphereWindow类为Controller角色。

•Model类Sphere,必须扩展Observable类,
–在Observable类中,方法addObserver()将视图与模型相关联
–当模型状态改变时,通过方法notifyObservers()通知视图。
Sphere.java
package newspherepro;
import java.util.Observable;
/**
*
* <p>Title: The Model part of Application</p>
* <p>Description: This class represents an observable object,
* or "data" in the model-view paradigm. It can be subclassed to represent
* an object that the application wants to have observed. </p>
* <p>Copyright: Copyright (c) 2005</p>
* @author Smart Lee
* @version 1.1
*/
public class Sphere extends Observable {
// 定义球体半径
private double sphereRadius;
// 定义球体体积
private double sphereVolume;
// 定义球体表面积
private double sphereSuArea;
/**
* 根据球体半径值设置球体三个属性值
* @param sphereRadius double
*/
public void setRadius (double sphereRadius) {
this.sphereRadius = sphereRadius;
this.sphereVolume = 4 * Math.PI * Math.pow(sphereRadius, 3) / 3;
this.sphereSuArea = 4 * Math.PI * Math.pow(sphereRadius, 2);
//变化后通知视图做相应变化
setChanged();
notifyObservers();
}
/**
* 根据球体体积值设置球体三个属性值
* @param sphereVolume double
*/
public void setVolume(double sphereVolume) {
this.sphereVolume = sphereVolume;
this.sphereRadius = Math.pow(3 * sphereVolume / (4 * Math.PI), 1 / 3.0);
this.sphereSuArea = 3 * sphereVolume / sphereRadius;
setChanged();
notifyObservers();
}
/**
* 根据球体表面积值设置球体三个属性值
* @param sphereSuArea double
*/
public void setSuArea(double sphereSuArea) {
this.sphereSuArea = sphereSuArea;
this.sphereRadius = Math.pow(sphereSuArea / (4 * Math.PI), 1 / 2.0);
this.sphereVolume = sphereSuArea * sphereRadius /3;
setChanged();
notifyObservers();
}
/**
* 取得球体半径值
* @return double
*/
public double getRadius() {
return sphereRadius;
}
/**
* 取得球体体积值
* @return double
*/
public double getVolume() {
return sphereVolume;
}
/**
* 取得球体表面积值
* @return double
*/
public double getSuArea() {
return sphereSuArea;
}
}


TextView.java

package newspherepro;
import java.util.Observer;
import java.util.Observable;
import java.text.NumberFormat;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/**
*
* <p>Title: The View part of Application </p>
* <p>Description: A class can implement the Observer interface when it wants to
*  be informed of changes in observable objects. </p>
* <p>Copyright: Copyright (c) 2005</p>
* @author Smart Lee
* @version 1.1
*/
public class TextView extends JPanel implements Observer {
GridBagLayout gridBagLayout1 = new GridBagLayout();
private boolean textBlankFlag = true;
JLabel radiusLab = new JLabel();
JLabel volumeLab = new JLabel();
JLabel suAreaLab = new JLabel();
JTextField radiusTextField = new JTextField();
JTextField volumeTextField = new JTextField();
JTextField surfAreaTextField = new JTextField();
public TextView() {
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
//实现接口的方法
public void update (Observable o, Object arg) {
NumberFormat nf = NumberFormat.getInstance();
Sphere balloon = (Sphere) o;
if(textBlankFlag) {
radiusTextField.setText("");
volumeTextField.setText("");
surfAreaTextField.setText("");
textBlankFlag = false;
}
else {
radiusTextField.setText(nf.format(balloon.getRadius()));
volumeTextField.setText(nf.format(balloon.getVolume()));
surfAreaTextField.setText(nf.format(balloon.getSuArea()));
}
}
private void jbInit() throws Exception {
radiusLab.setFont(new java.awt.Font("Dialog", 0, 14));
radiusLab.setText("  Radius =");
this.setBackground(Color.lightGray);
this.setForeground(Color.black);
this.setLayout(gridBagLayout1);
volumeLab.setFont(new java.awt.Font("Dialog", 0, 14));
volumeLab.setText("  Volume =");
suAreaLab.setFont(new java.awt.Font("Dialog", 0, 14));
suAreaLab.setText("  Surface area =");
radiusTextField.setFont(new java.awt.Font("Dialog", 0, 14));
radiusTextField.setText("");
volumeTextField.setFont(new java.awt.Font("Dialog", 0, 14));
volumeTextField.setText("");
surfAreaTextField.setFont(new java.awt.Font("Dialog", 0, 14));
surfAreaTextField.addActionListener(new TextView_surfAreaTextField_actionAdapter(this));
this.add(radiusLab,     new GridBagConstraints(0, 0, 1, 2, 0.0, 0.0
,GridBagConstraints.NORTH, GridBagConstraints.NONE, new Insets(-1, 0, 0, 0), 86, 10));
this.add(volumeLab,   new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0
,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
this.add(suAreaLab,   new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0
,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
this.add(radiusTextField,  new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0
,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, -19, 0, 19), 147, 1));
this.add(volumeTextField, new GridBagConstraints(1, 1, 1, 2, 0.0, 0.0
,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, -19, 0, 19), 147, 3));
this.add(surfAreaTextField, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0
,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, -19, 0, 19), 147, 4));
}
void surfAreaTextField_actionPerformed(ActionEvent e) {
}
}
class TextView_surfAreaTextField_actionAdapter implements java.awt.event.ActionListener {
TextView adaptee;
TextView_surfAreaTextField_actionAdapter(TextView adaptee) {
this.adaptee = adaptee;
}
public void actionPerformed(ActionEvent e) {
adaptee.surfAreaTextField_actionPerformed(e);
}
}


SphereWindow类作为Controller,它主要新建Model与View,将view与Model相关联,并处理事件

package newspherepro;
import javax.swing.*;
import java.awt.event.*;
/**
* <p>Title: SphereWindow</p>
* <p>Description: The Controller part of the model-view paradigm</p>
* <p>Copyright: Copyright (c) 2005</p>
* @author Smart Lee
* @version 1.1
*/
public class SphereWindow extends SphereFrame implements
ActionListener, MouseListener, MouseMotionListener{
// 创建视图一
TextView tView = new TextView();
// 创建视图二
GraphicsView gView = new GraphicsView();
// 创建模型
Sphere model = new Sphere();
//Construct the application
public SphereWindow() {
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
//Main method
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch(Exception e) {
e.printStackTrace();
}
new SphereWindow();
}
private void jbInit() throws Exception {
// 添加视图
contentPane.add(tView);
contentPane.add(gView);
this.setVisible(true);
// 建立模型与视图一的关联
model.addObserver(tView);
tView.update(model, null);
// 建立模型与视图二的关联
model.addObserver(gView);
gView.update(model, null);
// 为视图一各控件添加事件监听器
tView.radiusTextField.addActionListener(this);
tView.volumeTextField.addActionListener(this);
tView.surfAreaTextField.addActionListener(this);
// 为视图二添加鼠标事件
gView.addMouseListener(this);
gView.addMouseMotionListener(this);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == tView.radiusTextField) {
JTextField jtf = (JTextField)e.getSource();
// 捕获异常字符
try {
double radius = Double.parseDouble(jtf.getText());
// 更改模型数据
model.setRadius(radius);
} catch (Exception ex) {
JOptionPane.showMessageDialog(null,"illegal character!");
}
// 调用视图二的绘图方法以更新视图
gView.repaint();
}
if (e.getSource() == tView.volumeTextField) {
JTextField jtf = tView.volumeTextField;
try {
double volume = Double.parseDouble(jtf.getText());
model.setVolume(volume);
} catch(Exception ex) {
JOptionPane.showMessageDialog(null,"illegal character!");
}
gView.repaint();
}
if (e.getSource() == tView.surfAreaTextField) {
JTextField jtf = (JTextField)e.getSource();
try {
double surfArea = Double.parseDouble(jtf.getText());
model.setSuArea(surfArea);
} catch(Exception ex) {
JOptionPane.showMessageDialog(null,"illegal character!");
}
gView.repaint();
}
}
public void mousePressed(MouseEvent e) {
int X = gView.getWidth() / 2;
int Y = gView.getHeight() / 2;
gView.bShowDim = true; // 控制是否显示点坐标
gView.x = e.getX();
gView.y = e.getY();
// 圆心坐标(X, Y)
gView.radius = pointDistance(gView.x, gView.y, X, Y);
// 更改数据模型
model.setRadius(gView.radius);
gView.repaint();
}
public void mouseReleased(MouseEvent e) {
// 鼠标离开时不再显示点坐标
gView.bShowDim = false;
gView.repaint();
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
int X = gView.getWidth() / 2;
int Y = gView.getHeight() / 2;
gView.bShowDim = true;
gView.x = e.getX();
gView.y = e.getY();
gView.radius = pointDistance(gView.x, gView.y, X, Y);
model.setRadius(gView.radius);
gView.repaint();
}
/**
* 求两点距离
* @param x1 double 点1的横坐标
* @param y1 double 点1的纵坐标
* @param x2 double 点2的横坐标
* @param y2 double 点2的纵坐标
* @return double
*/
protected double pointDistance(double x1, double y1, double x2, double y2) {
return Math.pow(((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)), 1/2.0);
}
}


GraphicsView.java

package newspherepro;
import java.util.Observer;
import java.util.Observable;
import java.awt.Graphics;
import java.awt.Canvas;
/**
*
* <p>Title: The View part of Application </p>
* <p>Description: A class can implement the Observer interface when it wants to
*  be informed of changes in observable objects. </p>
* <p>Copyright: Copyright (c) 2005</p>
* @author Smart Lee
* @version 1.1
*/
public class GraphicsView extends Canvas implements Observer {
// 定义鼠标坐标
int x, y;
// 定义球半径
double radius;
// 控制点坐标是否显示
boolean bShowDim;
//实现接口的方法
public void update(Observable o, Object arg) {
Sphere balloon = (Sphere) o;
radius = balloon.getRadius();
}
// 绘球体
public void paint(Graphics g) {
int d = (int) radius * 2;
int X = this.getWidth();
int Y = this.getHeight(); // 注意不能在全局变量里设值!
g.drawOval( (X - d) / 2, (Y - d) / 2, d, d);
g.drawOval( (X - d) / 2, Y / 2 - d / 8, d, d / 4);
g.drawOval(X / 2 - d / 8, (Y - d) / 2, d / 4, d);
// 显示鼠标坐标
if(bShowDim) {
g.drawString("(" + x + ", " + y + ")", x, y);
}
}
}


SphereFrame.java

package newspherepro;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* <p>Title: SphereFrame</p>
* <p>Description: configure the basic info of JFrame</p>
* <p>Copyright: Copyright (c) 2005</p>
* @author Smart Lee
* @version 1.1
*/
public class SphereFrame extends JFrame {
boolean packFrame = false;
JPanel contentPane;
GridLayout borderLayout1 = new GridLayout(1, 2);
//Construct the frame
public SphereFrame() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
//Component initialization
private void jbInit() throws Exception  {
//Validate frames that have preset sizes
//Pack frames that have useful preferred size info, e.g. from their layout
if (packFrame) {
this.pack();
}
else {
this.validate();
}
//Center the window
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = this.getSize();
if (frameSize.height > screenSize.height) {
frameSize.height = screenSize.height;
}
if (frameSize.width > screenSize.width) {
frameSize.width = screenSize.width;
}
this.setSize(600,300);
// 使窗口居中
this.setLocationRelativeTo(null);
contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(borderLayout1);
this.getContentPane().setBackground(SystemColor.controlLtHighlight);
this.setTitle("Spheres: volume and surface area");
}
//Overridden so we can exit when window is closed
protected void processWindowEvent(WindowEvent e) {
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
System.exit(0);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: