Converting application to MVC architecture

Posted by terence6 on Stack Overflow See other posts from Stack Overflow or by terence6
Published on 2010-06-13T18:09:24Z Indexed on 2010/06/13 18:32 UTC
Read the original article Hit count: 198

Filed under:
|

I'm practicing writing MVC applications. I have a Mastermind game, that I would like to rewrite as MVC app. 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 )". Error comes from calling this method in my view with null argument. But how to overcome this ? MVC was quite simple with swing but awt and it's paint methods are much more complicated.

Code of working app :
http://paste.pocoo.org/show/224982/

App divided to 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 ?

© Stack Overflow or respective owner

Related posts about java

Related posts about mvc