Tartalomjegyzék

< Java

Java MVC

Az MVC

A Model View Controller szavakból alkotott betűszó. A szoftverfejlesztésben használatos szerkezeti minta. Azt jelenti, szétválasztjuk a megjelenésérét felelős kódrészeket, az adatokért és a vezérlésért felelős kódrészektől.

Egyszerű MVC

A következő példában egyetlen állományban valósítjuk meg az MVC-t. A View név helyett a MainWindow nevet használom osztálynévnek. De lehetne akár View osztály is.

Program01.java
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.FlowLayout;
 
class MainWindow extends JFrame {
	private JButton calcButton = new JButton("Számít");
	public JTextField baseField = new JTextField(10);
	public JTextField heightField = new JTextField(10);
	public JTextField resultField = new JTextField(10);
	private JLabel baseLabel = new JLabel("alap:");
	private JLabel heightLabel = new JLabel("magasság:");
	MainWindow() {
		resultField.setVisible(false);
		add(baseLabel);
		add(baseField);
		add(heightLabel);
		add(heightField);
		add(resultField);
		add(calcButton);
 
		setLayout(new FlowLayout());
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		pack();
		centerWindow(this);
		setVisible(true);
	}
	public void addCalcButtonActionListener(ActionListener listener) {
		calcButton.addActionListener(listener);
	}	
	public static void centerWindow(java.awt.Window frame) {
		java.awt.Dimension dimension =
		    java.awt.Toolkit.getDefaultToolkit().getScreenSize();
		int x = (int)((dimension.getWidth() - frame.getWidth()) / 2);
		int y = (int)((dimension.getHeight() - frame.getHeight()) / 2);
		frame.setLocation(x, y);
	}	
}
 
class Controller {
	MainWindow mainWindow = new MainWindow();
	Model model = new Model();
	Controller() {
		mainWindow.addCalcButtonActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent event) {
				String baseStr = mainWindow.baseField.getText();
				String heightStr = mainWindow.heightField.getText();
				double base = Double.parseDouble(baseStr);
				double height = Double.parseDouble(heightStr);
				Double area = model.calcArea(base, height);
				mainWindow.resultField.setText(area.toString());
				mainWindow.resultField.setVisible(true);
				mainWindow.pack();
			}
		});
	}
}
 
class Model {
	public double calcArea(double base, double height) {
		if(base <= 0 || height <=0) {
			throw new IllegalArgumentException();
		}
		return (base * height) /2;
	}
}
 
class Program01 {
	public static void main(String[]args) {
		new Controller();
	}
}

Külön könyvtárakban, vázlat

Nagyobb projektekben a modell, nézet és kontroller számára is külön könyvtárat késztünk.

A következő könyvtárszerkezetet alakítjuk ki:

projektKonyvtar/
      |--views/
      |   `--MainFrame.java
      |--models/
      |   `--Model.java
      |--controllers/
      |   `--Controller.java
      |--Makefile
      `--Haromszog.java
MainFrame.java
package view;
 
import javax.swing.JFrame;
 
public class MainFrame extends JFrame {
	public MainFrame() {
 
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(400, 300);
		setVisible(true);
	}
}
Model.java
package model;
 
public class Model {
 
}
Controller.java
package controller;
 
import view.MainFrame;
import model.Model;
 
public class Controller {
	MainFrame mainFrame = new MainFrame();
	Model model = new Model();
	public Controller() {
 
	}
}
Haromszog.java
import controller.Controller;
 
class Haromszog {
	public static void main(String[] args) {
		new Controller();
	}
}
Makefile
SOURCE=view/MainFrame.java \
	model/Model.java \
	controller/Controller.java \
	Haromszog.java
 
all:
	javac -cp . $(SOURCE)
 
run:
	xterm -e "java -cp . Haromszog; read"

Külön könyvtárakban, megvalósítva

A következőben a háromszög területszámító program komplett megvalósítását látjuk, egységteszttel együtt. Tesztelni csak a model részt teszteljük, ahol maga a számítás történik.

projektKonyvtar/
      |--views/
      |   `--MainFrame.java
      |--models/
      |   `--Model.java
      |--controllers/
      |      `--Controller.java
      |--Makefile
      |--Haromszog.java
      `--test/
          `--ModelTest.java
MainFrame.java
package view;
 
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.BoxLayout;
import javax.swing.JPanel;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
 
public class MainFrame extends JFrame {
	JPanel topPanel = new JPanel();
	JLabel titleLabel = new JLabel("Háromszög területszámító");
 
	JPanel bottomPanel = new JPanel();
	JLabel baseLabel = new JLabel("alap:");
	public JTextField baseField = new JTextField(5);
	JLabel heightLabel = new JLabel("magasság:");
	public JTextField heightField = new JTextField(5);
	public JLabel resultLabel = new JLabel("eredmény:");
	public JTextField resultField = new JTextField(5);
	JButton calcButton = new JButton("Számít");
 
	public MainFrame() {
		topPanel.setLayout(new FlowLayout());
		topPanel.add(titleLabel);
 
		bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.X_AXIS));
		bottomPanel.add(baseLabel);
		bottomPanel.add(baseField);
		bottomPanel.add(heightLabel);
		bottomPanel.add(heightField);
		bottomPanel.add(resultLabel);
		bottomPanel.add(resultField);
		bottomPanel.add(calcButton);
 
		resultLabel.setVisible(false);
		resultField.setVisible(false);
 
		setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
		add(topPanel);
		add(bottomPanel);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		pack();
		setVisible(true);
	}
	public void addCalcButtonActionListener(ActionListener listener) {
		calcButton.addActionListener(listener);
	}
}
ModelTest.java
package test;
 
import org.junit.Test;
import static org.junit.Assert.*;
import model.Model;
 
public class ModelTest {
	Model model = new Model();
    @Test
    public void testCalcArea() {
        assertEquals(525, model.calcArea(30, 35), 0);        
        assertEquals(900, model.calcArea(40, 45), 0);
    }
 
    @Test(expected = IllegalArgumentException.class)
    public void tesztExceptionSzamitTerulet() {
        model.calcArea(0, 35);
    }    
}
Model.java
package model;
 
public class Model {
    public static double calcArea(double base, double height) {
        if (base <= 0 || height <= 0) {
            throw new IllegalArgumentException("Nem megfelelő paraméterek");                
        }
        return (base * height) / 2;
    }	
}
Controller.java
package controller;
 
import view.MainFrame;
import model.Model;
 
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
 
public class Controller {
	MainFrame mainFrame = new MainFrame();
	Model model = new Model();
	public Controller() {
		mainFrame.addCalcButtonActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent event) {
				String baseStr = mainFrame.baseField.getText();
				double base = Double.parseDouble(baseStr);
				String heightStr = mainFrame.heightField.getText();
				double height = Double.parseDouble(heightStr);
				Double result = model.calcArea(base, height);
				mainFrame.resultField.setText(result.toString());
				mainFrame.resultField.setVisible(true);
				mainFrame.resultLabel.setVisible(true);
				mainFrame.pack();
			}
		});
	}
}
Haromszog.java
import controller.Controller;
 
class Haromszog {
	public static void main(String[] args) {
		new Controller();
	}
}
Makefile
SOURCE=view/MainFrame.java \
	model/Model.java \
	controller/Controller.java \
	Haromszog.java
 
all:
	javac -cp . $(SOURCE)
 
 
run:
	xterm -e "java -cp . Haromszog; read"
 
 
LINJUNIT=/usr/share/java/junit4.jar
 
testl:
	javac -cp .:$(LINJUNIT) test/ModelTest.java
	java -cp .:$(LINJUNIT) org.junit.runner.JUnitCore test.ModelTest
 
 
WINJUNIT=c:\bin\SWScite\javalibs\junit-4.11.jar
WINHAMCREST=c:\bin\SWScite\javalibs\hamcrest-core-1.3.jar
 
testw:
	javac -cp .;$(WINJUNIT);$(WINHAMCREST) test/ModelTest.java
	java -cp .;$(WINJUNIT);$(HAMCREST) org.junit.runner.JUnitCore test.ModelTest

MVC NetBeansben

Mainwindow.java
package view;
 
import controller.Controller;
 
public class Mainwindow extends javax.swing.JFrame {
    Controller controller = new Controller(this);
    public Mainwindow() {
        initComponents();
    }
 
	//...
 
    private void aboutButtonActionPerformed(java.awt.event.ActionEvent evt) {
        controller.aboutButtonActionListener(evt);
    }
 
 
    public static void main(String args[]) {
		//...
    }
 
	//..
    private javax.swing.JButton aboutButton;
}
Controller.java
package controller;
 
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import model.Model;
 
public class Controller {
    Model model = new Model();
    Mainwindow jframe;
    public Controller(Mainwindow jframe) {
        this.jframe = jframe;
    }
    public void aboutButtonActionListener(ActionEvent ev ) {
        JOptionPane.showMessageDialog(jframe, "Működik");
    }
}
Model.java
package model;
 
public class Model {
 
}

Swing GUI program MVC-ben

app01/
  |-lib/
  `-src/
     |-controllers/
     |   `-MainController.java
     |-models/
     |   `-MainModel.java
     |-views/
     |   `-MainFrame.java
     `-App.java
  
src/App.java
import controllers.MainController;
 
public class App {
    public static void main(String[] args) throws Exception {
        new MainController();
    }
}
src/views/MainFrame.java
package views;
 
import javax.swing.JFrame;
 
public class MainFrame extends JFrame {
 
    public MainFrame() {
 
        this.setTitle("App");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(400, 300);
        this.setVisible(true);
    }
 
}
src/models/MainModel.java
package models;
 
public class MainModel {
 
}
src/controllers/MainController.java
package controllers;
 
import models.MainModel;
import views.MainFrame;
 
public class MainController {
    MainFrame mainFrame;
    MainModel mainModel;
 
    public MainController() {
        this.mainFrame = new MainFrame();
        this.mainModel = new MainModel();
    }    
 
}

Linkek