简体   繁体   English

将应用程序转换为MVC架构

[英]Converting application to MVC architecture

I'm practicing writing MVC applications. 我正在练习编写MVC应用程序。 I have a Mastermind game, that I would like to rewrite as MVC app. 我有一个Mastermind游戏,我想重写为MVC应用程序。 I have divided my code to parts, but instead of working game I'm getting empty Frame and an error in "public void paint( Graphics g )". 我已将代码分为几部分,但不是正常运行的游戏,而是空的框架和“ public void paint(Graphics g)”错误。 Error comes from calling this method in my view with null argument. 错误来自在我的视图中使用null参数调用此方法。 But how to overcome this ? 但是如何克服呢? MVC was quite simple with swing but awt and it's paint methods are much more complicated. MVC使用swing很简单,但是awt及其绘制方法要复杂得多。

Code of working app : 工作应用程式码:
http://paste.pocoo.org/show/224982/ http://paste.pocoo.org/show/224982/

App divided to MVC : 应用分为MVC:
Main : 主要:

public class Main {

    public static void main(String[] args){

        Model model = new Model();
        View view = new View("Mastermind", 400, 590, model);
        Controller controller = new Controller(model, view);

        view.setVisible(true);
    }
}

Controller : 控制器:

import java.awt.*;
import java.awt.event.*;

public class Controller implements MouseListener, ActionListener {

    private Model model;
    private View view;

    public Controller(Model m, View v){

        model = m;
        view = v;

        view.addWindowListener( new WindowAdapter(){
            public void windowClosing(WindowEvent e){
            System.exit(0);
        } });

        view.addMouseListener(this);

    }

    public void actionPerformed( ActionEvent e ) {
        if(e.getSource() == view.checkAnswer){
            if(model.isRowFull){
                model.check();
            }
        }
    }

    public void mousePressed(MouseEvent e) {
        Point mouse = new Point();

        mouse = e.getPoint();
        if (model.isPlaying){
            if (mouse.x > 350) {
                int button = 1 + (int)((mouse.y - 32) / 50);
                if ((button >= 1) && (button <= 5)){
                    model.fillHole(button);
                }
            }
        }
    }

    public void mouseClicked(MouseEvent e) {}
    public void mouseReleased(MouseEvent e){}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e)  {}
}

View : 查看:

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class View extends Frame implements ActionListener {

    Model model;
    JButton checkAnswer;
    private JPanel button;
    static final int HIT_X[] = {270,290,310,290,310}, HIT_Y[] = {506,496,496,516,516};

    public View(String name, int w, int h, Model m){

        model = m;

        setTitle( name );
        setSize( w,h );
        setResizable( false );
        this.setLayout(new BorderLayout());

        button = new JPanel();
        button.setSize( new Dimension(400, 100));
        button.setVisible(true);
        checkAnswer = new JButton("Check");
        checkAnswer.addActionListener(this);
        checkAnswer.setSize( new Dimension(200, 30));
        button.add( checkAnswer );
        this.add( button, BorderLayout.SOUTH);
        button.setVisible(true);

        for ( int i=0; i < model.SCORE; i++ ){
            for ( int j = 0; j < model.LINE; j++ ){
                model.pins[i][j] = new Pin(20,0);
                model.pins[i][j].setPosition(j*50+30,510-i*50);
                model.pins[i+model.SCORE][j] = new Pin(8,0);
                model.pins[i+model.SCORE][j].setPosition(HIT_X[j],HIT_Y[j]-i*50);
            }
        }
        for ( int i=0; i < model.LINE; i++ ){
            model.pins[model.OPTIONS][i] = new Pin( 20, i+2 );
            model.pins[model.OPTIONS][i].setPosition( 370,i * 50 + 56);
        }
        model.combination();

        model.paint(null);
    }

    public void actionPerformed( ActionEvent e ) {
    }   
}

Model: 模型:

import java.awt.*;

public class Model extends Frame{
    static final int
    LINE = 5,
    SCORE = 10, OPTIONS = 20;
    Pin pins[][] = new Pin[21][LINE];
    int combination[] = new int[LINE];
    int curPin = 0;
    int turn = 1;
    int repaintPin;
    boolean isUpdate = true, isPlaying = true, isRowFull = false;

    public Model(){
    }

    void fillHole(int color) {
        pins[turn-1][curPin].setColor(color+1);
        repaintPins( turn );
        curPin = (curPin+1) % LINE;
        if (curPin == 0){
            isRowFull = true;
        }
    }

    public void paint( Graphics g ) {
        g.setColor( new Color(238, 238, 238));
        g.fillRect( 0,0,400,590);

        for ( int i=0; i < pins.length; i++ ) {
            pins[i][0].paint(g);
            pins[i][1].paint(g);
            pins[i][2].paint(g);
            pins[i][3].paint(g);
            pins[i][4].paint(g);
        }
    }

    public void update( Graphics g ) {
        if ( isUpdate ) {
            paint(g);
        }
        else {
            isUpdate = true;
            pins[repaintPin-1][0].paint(g);
            pins[repaintPin-1][1].paint(g);
            pins[repaintPin-1][2].paint(g);
            pins[repaintPin-1][3].paint(g);
            pins[repaintPin-1][4].paint(g);
        }
    }

    void repaintPins( int pin ) {
        repaintPin = pin;
        isUpdate = false;
        repaint();
    }

    void check() {
        int junkPegs[] = new int[LINE], junkCode[] = new int[LINE];
        int pegCount = 0, pico = 0;

        for ( int i = 0; i < LINE; i++ ) {
            junkPegs[i] = pins[turn-1][i].getColor();
            junkCode[i] = combination[i];
        }
        for ( int i = 0; i < LINE; i++ ){
            if (junkPegs[i]==junkCode[i]) {
                pins[turn+SCORE][pegCount].setColor(1);
                pegCount++;
                pico++;
                junkPegs[i] = 98;
                junkCode[i] = 99;
            }
        }
        for ( int i = 0; i < LINE; i++ ){
            for ( int j = 0; j < LINE; j++ )
                if (junkPegs[i]==junkCode[j]) {
                    pins[turn+SCORE][pegCount].setColor(2);
                    pegCount++;
                    junkPegs[i] = 98;
                    junkCode[j] = 99;
                    j = LINE;
            }
        }
        repaintPins( turn+SCORE );

        if ( pico == LINE ){
            isPlaying = false;
        }
        else if ( turn >= 10 ){
                isPlaying = false;
        }
        else{
            curPin = 0;
            isRowFull = false;
            turn++;
        }
    }

    void combination() {
        for ( int i = 0; i < LINE; i++ ){
          combination[i] = 1 + (int)(Math.random()*5);
            System.out.print(i+",");
        }
    }
}

class Pin{
    private int color, X, Y, radius;
    private static final Color COLORS[] = {
        Color.black,
        Color.white,
        Color.red,
        Color.yellow,
        Color.green,
        Color.blue,
        new Color(7, 254, 250)};

    public Pin(){
        X = 0; Y = 0; radius = 0; color = 0;
    }

    public Pin( int r,int c ){
        X = 0; Y = 0; radius = r; color = c;
    }

    public void paint( Graphics g ){
        int x = X-radius;
        int y = Y-radius;

        if (color > 0){
            g.setColor( COLORS[color]);
            g.fillOval( x,y,2*radius,2*radius );
        }
        else{
            g.setColor( new Color(238, 238, 238) );
            g.drawOval( x,y,2*radius-1,2*radius-1 );
        }
        g.setColor( Color.black );
        g.drawOval( x,y,2*radius,2*radius );
    }

    public void setPosition( int x,int y ){
        this.X = x ;
        this.Y = y ;
    }
    public void setColor( int c ){
        color = c;
    }
    public int getColor() {
        return color;
    }
}

Any clues on how to overcome this would be great. 关于如何克服这一点的任何线索都是很好的。 Have I divided my code improperly ? 我是否对代码进行了不正确的划分?

This doesn't look right to me. 这在我看来不对。

Model should not extend Frame. 模型不应扩展框架。 Frame is a View idea. 框架是一种View理念。 Model should not have graphics, or painting, or anything besides the problem at hand inside it. 模型中除了手头的问题外,不应具有图形或绘画。

I wouldn't have View implement any of the Listener interfaces. 我不会让View实现任何侦听器接口。 That's the Controller's job. 那是财务主任的工作。 It's the Listener that handles all events and updates the Model to respond to the changes it receives from the View event. 监听器处理所有事件并更新模型以响应从View事件接收到的更改。

View should be just Swing or AWT classes; 视图应该只是Swing或AWT类; no Listeners. 没有听众。 Paint methods belong in View. 绘画方法属于View。 Anything that's painted should be expressed in View. 绘制的任何内容都应在View中表达。

Neither Model nor View should have references to each other or Controller; Model或View都不应该相互引用或引用Controller。 the Controller owns references to both Model and View. Controller拥有对Model和View的引用。 It's the omniscient one that knows the whole problem. 这是全知的,知道整个问题。

Model only knows about the problem you're solving. 模型仅知道您要解决的问题。

View should be completely detachable. 视图应该是完全可分离的。 A good test is to be able to remove the Swing UI and write a purely text-driven View to replace it. 一个好的测试是能够删除Swing UI并编写一个纯文本驱动的View来替换它。 If you can do it without affecting the other two, you've layered things properly. 如果您可以做到而又不影响其他两个,则可以正确地进行分层。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Swing应用程序中的MVC架构 - MVC architecture in Swing application AJAX MVC应用程序的体系结构 - Architecture of AJAX MVC application 具有AJAX / JSON / REST的Spring MVC应用程序的体系结构 - Architecture of a Spring MVC application with AJAX / JSON / REST 重做cardlayout-应用到MVC架构中 - Redo cardlayout-application into MVC architecture 如何在这个 Java 应用程序中实现 MVC 架构 - How to implement the MVC architecture in this Java application 小部件、服务和应用程序(类似 MVC 的架构)的 model(单例)之间的通信 - Communication between a widget, a service, and the model (singleton) of an application (MVC like architecture) 在spring mvc hibernate应用程序中将错误从字符串转换为blob - error converting from string to blob in spring mvc hibernate application 在Spring MVC应用程序中将DAO对象转换为DTO对象 - Converting DAO objects to DTO objects in a Spring MVC Application 将独立的Spring应用程序转换或集成到Spring MVC应用程序 - Converting or Integrating a standalone spring application to a Spring MVC app 我正在使用MVC和三层架构设计Web应用程序。 我有三层架构的设计问题 - I am designing a web application using MVC and Three tier architecture. I have got design issue with three tier architecture
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM