以下为个人学习笔记和习题整理
课程:面向对象程序设计 ——Java 语言
- 浙江大学 - 翁恺 @ 中国大学 MOOC
https://www.icourse163.org/course/ZJU-1001542001

# 课堂笔记

# Swing

# 布局管理器

部件 button
容器 frame
部件可以被放在容器里,容器本身也是一种部件。

布局管理器 BorderLayout 来管理部件的大小、位置等。
BorderLayout 类把容器分为五个部分,分别是 NORTHSOUTHEASTWESTCENTER (默认),同一个位置,同一个时间,只能有一个部件。并根据内容来计算布局长宽。

# 事件机制 addActionListener

Swing 使用一个非常灵活的模型来处理 GUI 的输入:采用事件监听器的事件处理 (event handling) 模型。

Swing 框架本身以及大部分部件在发生一些情况时会触发相关的事件,而其他的对象也许会对这些事件感兴趣。
不同类型的动作会导致不同类型的事件。
当点击一个按钮或选中一个菜单项,部件就会触发动作事件;而当点击或移动鼠标时,会触发鼠标事件;当框架被关闭或最小化时,会触发窗口事件。另外还有许多种其他事件。

所有的对象都可以成为任何这些事件的监听器,而一旦成为监听器,就可以得到这些事件触发的通知。

实现了众多监听器接口之一的对象就成为一个事件监听器。
如果对象实现了恰当的接口,就可以注册到它想监听的组件上。

# 匿名类

new 对象的时候给出的类的定义形成了匿名类。
匿名类可以继承某类,也可以实现某接口。
Swing 的消息机制广泛使用匿名类。

# 内部类

内部类就是指一个类定义在另一个类的内部,从而成为外部类的一个成员。
因此一个类中可以有成员变量、方法,还可以有内部类。
实际上 Java 的内部类可以被称为成员类,内部类实际上是它所在类的成员。
所以内部类也就具有和成员变量、成员方法相同的性质。

比如,成员方法可以访问私有变量,那么成员类也可以访问私有变量了。
也就是说,成员类中的成员方法都可以访问成员类所在类的私有变量。

内部类最重要的特点就是:能够访问外部类的所有成员,包括任何私有的成员。

也可以定义在函数内部。
外部是函数时,只能访问那个函数里 final 的变量

# MVC 模式

数据、表现和控制三者分离,各负其责。
Model 模型
保存和维护数据,提供接口让外部修改数据
通知表现,需要刷新

View 表现
从模型获得数据,根据数据画出表现

Control 控制
从用户得到输入,根据输入调整数据

用户在界面上的操作,不直接显示

# 课内项目

# 注入反转

由按钮公布一个守听者接口和一对注册 / 注销函数。
你的代码实现那个接口,将守听者对象注册在按钮上。
一旦按钮被按下,就会反过来调用你的守听者对象的某个函数。

例子:狐狸与兔子添加步进按钮

package FoxAndRabbit;
import field.Field;
import field.View;
import field.Location;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JButton;
import animal.Fox;
import animal.Rabbit;
import animal.Animal;
import cell.Cell;
public class FoxAndRabbit{
	private Field thefield;
	private View theview;
	private JFrame frame;
	
	/**
	 * 内部类  StepListener
	 */
	private class StepListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			step();
			frame.repaint();			
		}
	}
	
	public FoxAndRabbit( int size ){
		thefield = new Field(size, size);
		for( int row = 0; row <thefield.getHeight(); row++ ){
			for( int col = 0; col < thefield.getWidth(); col++ ){
				double probability = Math.random();
				if( probability <0.05 ){
					thefield.place( row, col, new Fox());
				}else if( probability < 0.15 ){
					thefield.place( row, col, new Rabbit());
				}
			}
		}
		theview = new View(thefield);
		frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setResizable(false);
		frame.setTitle("FoxAndRabbit");
		frame.add(theview, BorderLayout.CENTER);
		
		// 添加一个按钮
		JButton btnStep = new JButton("单步");
		frame.add(btnStep, BorderLayout.NORTH);		
		
		// 按钮绑定事件,方法 1:匿名类
//		btnStep.addActionListener(new ActionListener() {
//			@Override
//			public void actionPerformed(ActionEvent e) {
//				System.out.println ("按下啦!");
//				step();
//				frame.repaint();
//			}			
//		});
		// 按钮绑定事件,方法 2:内部类
		btnStep.addActionListener(new StepListener());
		
		frame.pack();
		frame.setVisible(true);
	}
	
	public void step(){
		for( int row = 0; row < thefield.getHeight(); row++ ){
			for( int col = 0; col < thefield.getWidth(); col++ ){
				Cell cell = thefield.get(row, col);
				if( cell != null ){
					Animal animal = (Animal)cell;
					animal.grow();
					if( animal.isAlive()){
						//move
						Location loc = animal.move(thefield.getFreeNeighbour(row, col));
						if( loc != null ){
							thefield.move(row, col, loc);
						}
						//eat   animal.eat(thefield);
						if( animal instanceof Fox){
							Cell[] neighbour = thefield.getNeighbour(row, col);
							ArrayList<Animal> listRabbit = new ArrayList<Animal>();
							for( Cell an : neighbour ){
								if( an instanceof Rabbit ){
									listRabbit.add( (Rabbit)an );
								}
							}
							if( !listRabbit.isEmpty() ){
								Animal fed = animal.feed(listRabbit);
								if( fed != null ){
									thefield.remove((Cell)fed);
								}
							}
						}
						//breed
						Animal baby = animal.breed();
						if( baby != null ){
							thefield.placeRandomAdj(row, col, (Cell)baby);
						}
					}else{
						thefield.remove(row, col);
					}
				}
			}
		}	
	}
	
	public void start( int steps ){
		for( int i = 0; i < steps; i++){
			step();
			theview.repaint();
			try{
				Thread.sleep(200);
			}catch (InterruptedException e){
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		FoxAndRabbit fnr = new FoxAndRabbit(30);
		//fnr.start(10);
	}
}

# 课程表

JTable 类可以以表格的形式显示和编辑数据。
JTable 类的对象并不存储数据,它只是数据的表现。

KCB.java
package kcb;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
public class KCB {
	public static void main(String[] args) {
		JFrame frame = new JFrame();
		JTable table = new JTable(new KCBData());
		JScrollPane pane = new JScrollPane(table);
		frame.add(pane);
		frame.pack();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}
KCBData.java
package kcb;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
public class KCBData implements TableModel {
	private String[] title = { "周一", "周二", "周三", "周四", "周五", "周六", "周日" };
	private String[][] data = new String[8][7];
	public KCBData() {
		for (int i = 0; i < data.length; i++) {
			for (int j = 0; j < data[i].length; j++) {
				data[i][j] = "";
			}
		}
	}
	@Override
	public void addTableModelListener(TableModelListener arg0) {
		// TODO Auto-generated method stub
	}
	@Override
	public Class<?> getColumnClass(int arg0) {
		return String.class;
	}
	@Override
	public int getColumnCount() {
		return 7;
	}
	@Override
	public String getColumnName(int arg0) {
		return title[arg0];
	}
	@Override
	public int getRowCount() {
		return 8;
	}
	@Override
	public Object getValueAt(int arg0, int arg1) {
		// TODO Auto-generated method stub
		return data[arg0][arg1];
	}
	@Override
	public boolean isCellEditable(int arg0, int arg1) {
		// TODO Auto-generated method stub
		return true; // 可以被编辑
	}
	@Override
	public void removeTableModelListener(TableModelListener arg0) {
		// TODO Auto-generated method stub
	}
	@Override
	public void setValueAt(Object arg0, int arg1, int arg2) {
		// TODO Auto-generated method stub
		data[arg1][arg2] = (String) arg0;
	}
}

# 课堂讨论

  1. 在第 5 周的城堡程序那里,我们做的 Handler 是需要在构造的时候注入 Game 的。那么,在学习了内部类之后,能否用 Game 的内部类来实现这些 Handler 呢?应该怎么做?
package castle;
import java.util.HashMap;
import java.util.Scanner;
public class Game {
	public abstract class Handler {
		public  abstract void doCmd(String word);
		public boolean isBye(){
			return false;
		}
	}
	 
	public Game()
	{
//		handlers.put("go",new HandlerGo(this));
//		handlers.put("bye",new HandlerBye(this));
//		handlers.put("help",new HandlerHelp(this));
//		createRooms();
		handlers.put("go", new Handler() {
			@Override
			public void doCmd(String word) {
				goRoom(word);
			}
		});
		handlers.put("help", new Handler() {
			@Override
			public void doCmd(String word) {
				System.out.println("迷路了吗?你可以做的命令有go bye help");
				System.out.println("如:\tgo east");
			}
		});
		handlers.put("bye", new Handler() {
			@Override
			public void doCmd(String word) {
 				System.out.println("bye");
			}
 
			@Override
			public boolean isBye() {
				return true;
			}
		});
		createRooms();
	}
}
阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Ruri Shimotsuki 微信支付

微信支付

Ruri Shimotsuki 支付宝

支付宝

Ruri Shimotsuki 贝宝

贝宝