Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,15 @@
* a snapshot of an object's state must be saved so that it can be restored to that state later, and
* a direct interface to obtaining the state would expose implementation details and break the object's encapsulation

##Model-View-Presenter
**Intent:** Apply a "Separation of Concerns" principle in a way that allows developers to build and test user interfaces.

![alt text](https://github.com/pitsios-s/java-design-patterns/blob/master/model-view-presenter/etc/model-view-presenter.jpg "Model-View-Presenter")

**Applicability:** Use the Model-View-Presenter in any of the following situations
* when you want to improve the "Separation of Concerns" principle in presentation logic
* when a user interface development and testing is necessary.

##Observer
**Intent:** Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

Expand Down
2 changes: 2 additions & 0 deletions model-view-presenter/etc/data/test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Test line 1
Test line 2
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions model-view-presenter/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iluwatar</groupId>
<artifactId>java-design-patterns</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.iluwatar</groupId>
<artifactId>model-view-presenter</artifactId>
<version>1.0-SNAPSHOT</version>
<name>model-view-presenter</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.java.dev.swing-layout</groupId>
<artifactId>swing-layout</artifactId>
<version>1.0.2</version>
</dependency>
</dependencies>
</project>
80 changes: 80 additions & 0 deletions model-view-presenter/src/main/java/com/iluwatar/FileLoader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.iluwatar;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

/**
* Every instance of this class represents the Model component
* in the Model-View-Presenter architectural pattern.
*
* It is responsible for reading and loading the contents of a given file.
*/
public class FileLoader {

/**
* Indicates if the file is loaded or not.
*/
private boolean loaded = false;

/**
* The name of the file that we want to load.
*/
private String fileName;

/**
* Loads the data of the file specified.
*/
public String loadData() {
try {
BufferedReader br = new BufferedReader(new FileReader(new File(this.fileName)));
String text = "";
String line = "";

while( (line = br.readLine()) != null ) {
text += line + "\n";
}

this.loaded = true;
br.close();

return text;
}

catch(Exception e) {
e.printStackTrace();
}

return null;
}

/**
* Sets the path of the file to be loaded, to the given value.
*
* @param fileName The path of the file to be loaded.
*/
public void setFileName(String fileName) {
this.fileName = fileName;
}

/**
* @return fileName The path of the file to be loaded.
*/
public String getFileName() {
return this.fileName;
}

/**
* @return True, if the file given exists, false otherwise.
*/
public boolean fileExists() {
return new File(this.fileName).exists();
}

/**
* @return True, if the file is loaded, false otherwise.
*/
public boolean isLoaded() {
return this.loaded;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
package com.iluwatar;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/**
* This class is the GUI implementation of the View component
* In the Model-View-Presenter pattern.
*/
public class FileSelectorJFrame extends JFrame implements FileSelectorView, ActionListener {

/**
* Default serial version ID.
*/
private static final long serialVersionUID = 1L;

/**
* The "OK" button for loading the file.
*/
private JButton OK;

/**
* The cancel button.
*/
private JButton cancel;

/**
* The information label.
*/
private JLabel info;

/**
* The contents label.
*/
private JLabel contents;

/**
* The text field for giving the name of the file
* that we want to open.
*/
private JTextField input;

/**
* A text area that will keep the contents of the file opened.
*/
private JTextArea area;

/**
* The panel that will hold our widgets.
*/
private JPanel panel;

/**
* The Presenter component that the frame will interact with
*/
private FileSelectorPresenter presenter;

/**
* The name of the file that we want to read it's contents.
*/
private String fileName;

/**
* Constructor.
*/
public FileSelectorJFrame() {
super("File Loader");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(null);
this.setBounds(100, 100, 500, 200);

/*
* Add the panel.
*/
this.panel = new JPanel();
panel.setLayout(null);
this.add(panel);
panel.setBounds(0, 0, 500, 200);
panel.setBackground(Color.LIGHT_GRAY);

/*
* Add the info label.
*/
this.info = new JLabel("File Name :");
this.panel.add(info);
info.setBounds(30, 10, 100, 30);

/*
* Add the contents label.
*/
this.contents = new JLabel("File contents :");
this.panel.add(contents);
this.contents.setBounds(30, 100, 120, 30);

/*
* Add the text field.
*/
this.input = new JTextField(100);
this.panel.add(input);
this.input.setBounds(150, 15, 200, 20);

/*
* Add the text area.
*/
this.area = new JTextArea(100, 100);
JScrollPane pane = new JScrollPane(area);
pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
this.panel.add(pane);
this.area.setEditable(false);
pane.setBounds(150, 100, 250, 80);

/*
* Add the OK button.
*/
this.OK = new JButton("OK");
this.panel.add(OK);
this.OK.setBounds(250, 50, 100, 25);
this.OK.addActionListener(this);

/*
* Add the cancel button.
*/
this.cancel = new JButton("Cancel");
this.panel.add(this.cancel);
this.cancel.setBounds(380, 50, 100, 25);
this.cancel.addActionListener(this);

this.presenter = null;
this.fileName = null;
}

@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == this.OK) {
this.fileName = this.input.getText();
presenter.fileNameChanged();
presenter.confirmed();
}

else if(e.getSource() == this.cancel) {
presenter.cancelled();
}
}

@Override
public void open() {
this.setVisible(true);
}

@Override
public void close() {
this.dispose();
}

@Override
public boolean isOpened() {
return this.isVisible();
}

@Override
public void setPresenter(FileSelectorPresenter presenter) {
this.presenter = presenter;
}

@Override
public FileSelectorPresenter getPresenter() {
return this.presenter;
}

@Override
public void setFileName(String name) {
this.fileName = name;
}

@Override
public String getFileName() {
return this.fileName;
}

@Override
public void showMessage(String message) {
JOptionPane.showMessageDialog(null, message);
}

@Override
public void displayData(String data) {
this.area.setText(data);
}
}
Loading