Je m'exerce à écrire des applications MVC. J'ai un jeu Mastermind, que je voudrais réécrire en tant qu'application MVC. J'ai divisé mon code en parties, mais au lieu de travailler le jeu, je reçois un cadre vide et une erreur dans "public void paint (Graphics g)". L'erreur provient de l'appel de cette méthode dans ma vue avec un argument nul. Mais comment surmonter cela? MVC était assez simple avec swing mais awt et ses méthodes de peinture sont beaucoup plus compliquées.Conversion d'une application en architecture MVC
Code de l'application de travail:
http://paste.pocoo.org/show/224982/
App divisée MVC:
principal:
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) {}
}
Vue:
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) {
}
}
Modèle:
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;
}
}
Des indices sur la façon de surmonter ce serait formidable. Ai-je divisé mon code incorrectement?
Alors où dois-je placer les méthodes paint()? en vue ? Et si j'ai de la peinture() pour Model et Pin? – terence6
"paint" est intrinsèquement View. Si vous avez des objets Model et Pin qui nécessitent une peinture, passez-les dans View et demandez-leur de faire le travail. – duffymo