概述
(1) View:主类 继承 JFrame
(2) Model:主类私有成员为,在主类的构造函数中初始化
(3)Controller:定义为主类的内部私有类,这样便于访问主类的成员函数和成员变量model
(4)不同组件之间的互动,通过model桥接,即信息状态改变都反映在model中,一旦希望View重画,调用主类repaint()进行通知,主类的相关组件自动从model中获取改变。
(5) 其他技术细节:
A) main中只负责new主类对象,调用主类的initialize()进行添加组件,注册监听器,组件都定义为intialize()的函数中的局部变量, GUI APP由单独的事件委派线程负责管理。
体现为如下main代码
public staticvoid main(String[] args) {
EventQueue.invokeLater(new Runnable(){
publicvoid run() {
HelloAppapp=newHelloApp();
app.initialize();
}
});
}
B) void initialize(){
//default:BorderLayout
//Create components,(1)-(3)可以用子类代替,外观设置改在构造函数中
JComponentpanel=newGamePanel();//(1)
panel.setBackground(Color.BLACK);//(2)
panel.setPreferredSize(new Dimension(320,240));//(3) /*
JButtonbutton=new JButton("hello");
JTextFieldtext=new JTextField();*/
//add components
add(panel,BorderLayout.NORTH);
/* add(button,BorderLayout.SOUTH);
add(text,BorderLayout.CENTER);*/
//Create components actions
panel.addMouseListener(new MouseHandler());
//set Frame appearance
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setTitle("Hello,world");
pack();
setVisible(true);
}
C) 复杂的组件,需要设置外观,可以使用继承机制建立类,以利于initialize代码简洁。
如这里的Jpanel对象,需要覆盖paintComponent方法,必须新建子类。
private classGamePanel extends JPanel{
privateinti=0;
protectedvoid paintComponent(Graphicsg) {
super.paintComponent(g);
g.setColor(Color.WHITE);
g.drawString(model.getInfo(), 10, 10);
System.out.println("paint:"+(++i));
}
}
D) 事件处理器定义为内部类,以方便访问主类私有信息,注意组件并不是作为主类的私有局部变量,事件处理器不能访问initialize内部的局部变量,二者传递信息的途径是model,通知途径是事件委派线程,简单的事件逻辑可以基于匿名内部类或者Lambda表达式完成(JDK1.8以上)
private class MouseHandlerextends MouseAdapter{
publicvoid mouseClicked(MouseEventevent) {
int x=event.getX();
int y=event.getY();
model.setInfo("("+x+", "+y+")");
repaint();//通知委派线程重绘
}
}
package game;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Date;
import java.util.Timer;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class HelloApp extends javax.swing.JFrame implements Runnable{
private Model model;
public HelloApp(){
model = new Model();
}
void initialize(){
//default: BorderLayout
//Create components,(1)-(3)可以用子类代替,外观设置改在构造函数中
JComponent panel=new GamePanel();//(1)
panel.setBackground(Color.BLACK);//(2)
panel.setPreferredSize(new Dimension(320,240));//(3)
/*
JButton button=new JButton("hello");
JTextField text=new JTextField();*/
//add components
add(panel,BorderLayout.NORTH);
/* add(button,BorderLayout.SOUTH);
add(text,BorderLayout.CENTER);*/
//Create components actions
panel.addMouseListener(new MouseHandler());
panel.setFocusable(true);//very important
panel.addKeyListener(new KeyAction());
//set Frame appearance
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setTitle("Hello,world");
pack();
setVisible(true);
new Thread(this).start();
}
private class KeyAction extends KeyAdapter{
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
int keyCode = e.getKeyCode();
System.out.println(keyCode);
}
}
private class MouseHandler extends MouseAdapter{
@Override
public void mouseClicked(MouseEvent event) {
int x=event.getX();
int y=event.getY();
model.setInfo("("+x+", "+y+")");
repaint();//通知重绘
}
}
private class GamePanel extends JPanel{
private int i=0;
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.WHITE);
//g.fillRect(30, 30, 50, 50);
int x=(int)(Math.random()*320);
int y=(int)(Math.random()*240);
g.drawString(model.getInfo(), x, y);
//System.out.println("paint:"+(++i));
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable(){
public void run() {
HelloApp app=new HelloApp();
app.initialize();
}
});
}
@Override
public void run() {
while(true){
repaint();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class Model{
private String info;
Model(){
info="Hello, world";
}
public void setInfo(String info){
this.info=info;
}
public String getInfo(){
return info;
}
}
<4>遇到的问题
最后
以上就是活力小伙为你收集整理的基于MVC架构的GUI设计的全部内容,希望文章能够帮你解决基于MVC架构的GUI设计所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复