Pārlūkot izejas kodu

Properly delineate file loading and controller responsibilities.

Sam Jaffe 5 gadi atpakaļ
vecāks
revīzija
adfa3509d5

+ 80 - 0
src/main/lombok/org/leumasjaffe/recipe/controller/FileController.java

@@ -0,0 +1,80 @@
+package org.leumasjaffe.recipe.controller;
+
+import java.awt.Component;
+import java.io.File;
+import java.io.IOException;
+
+import javax.swing.JFileChooser;
+import javax.swing.JOptionPane;
+
+import org.leumasjaffe.container.functional.Result;
+import org.leumasjaffe.recipe.model.Recipe;
+import org.leumasjaffe.recipe.util.IOUtil;
+
+import lombok.AccessLevel;
+import lombok.RequiredArgsConstructor;
+import lombok.experimental.FieldDefaults;
+import lombok.experimental.NonFinal;
+
+@RequiredArgsConstructor
+@FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
+public class FileController<T extends Component & FileController.Model> {
+	public static interface Model {
+		void setModel(Recipe model);
+	}
+	
+	JFileChooser chooser = new JFileChooser();
+	T owner;
+	@NonFinal File filename = null;
+	@NonFinal Recipe model = null;
+	
+	public void create() {
+		setModel(new Recipe());
+	}
+	
+	public void save() {
+		if (filename == null) {
+			if (chooser.showSaveDialog(owner) == JFileChooser.APPROVE_OPTION) {
+				// TODO Store the file instead
+				filename = chooser.getSelectedFile();
+			}
+			return;
+		}
+		try {
+			IOUtil.save(filename, model);
+		} catch (IOException ioe) {
+			errorPopup(ioe);
+		}
+	}
+	
+	public void saveAs() {
+		this.filename = null;
+		save();
+	}
+	
+	public void open() {
+		if (chooser.showOpenDialog(owner) == JFileChooser.APPROVE_OPTION) {
+			// TODO Store the file instead
+			filename = chooser.getSelectedFile();
+		}
+		Result.maybe(IOUtil::load).apply(filename)
+			.consume(this::setModel, this::errorPopup);
+	}
+
+	@Deprecated
+	public void open(final String newFilename) {
+		this.filename = new File(newFilename);
+		Result.maybe(IOUtil::load).apply(filename)
+			.consume(this::setModel, this::errorPopup);
+	}
+
+	private void errorPopup(final Exception ex) {
+		JOptionPane.showMessageDialog(owner, ex.getLocalizedMessage(),
+				"File Error", JOptionPane.ERROR_MESSAGE);
+	}
+	
+	private void setModel(Recipe recipe) {
+		this.model = recipe;
+		owner.setModel(recipe);
+	}
+}

+ 0 - 53
src/main/lombok/org/leumasjaffe/recipe/controller/IOController.java

@@ -1,53 +0,0 @@
-package org.leumasjaffe.recipe.controller;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-
-import org.leumasjaffe.recipe.model.Recipe;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
-
-import lombok.AccessLevel;
-import lombok.NonNull;
-import lombok.experimental.FieldDefaults;
-
-@FieldDefaults(level=AccessLevel.PRIVATE)
-public class IOController {
-	@NonNull Recipe recipe = new Recipe();
-	
-	Recipe load(final Reader in) throws IOException {
-		ObjectMapper mapper = new ObjectMapper();
-		mapper.registerModule(new Jdk8Module());
-		return mapper.readValue(in, Recipe.class);
-	}
-	
-	void save(final Writer out) throws IOException {
-		ObjectMapper mapper = new ObjectMapper();
-		mapper.registerModule(new Jdk8Module());
-		mapper.writeValue(out, this.recipe);
-	}
-	
-	public Recipe create() {
-		return this.recipe = new Recipe();
-	}
-
-	public Recipe load(final @NonNull String filename) throws IOException {
-		try (FileReader file = new FileReader(filename);
-				BufferedReader buf = new BufferedReader(file)) {
-			return this.recipe = load(buf);
-		}
-	}
-	
-	public void save(final @NonNull String filename) throws IOException {
-		try (FileWriter file = new FileWriter(filename);
-				BufferedWriter buf = new BufferedWriter(file)) {
-			save(buf);
-		}
-	}
-}

+ 47 - 0
src/main/lombok/org/leumasjaffe/recipe/util/IOUtil.java

@@ -0,0 +1,47 @@
+package org.leumasjaffe.recipe.util;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+
+import org.leumasjaffe.recipe.model.Recipe;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+
+import lombok.NonNull;
+import lombok.experimental.UtilityClass;
+
+@UtilityClass
+public class IOUtil {	
+	Recipe load(final @NonNull Reader in) throws IOException {
+		ObjectMapper mapper = new ObjectMapper();
+		mapper.registerModule(new Jdk8Module());
+		return mapper.readValue(in, Recipe.class);
+	}
+	
+	void save(final @NonNull Writer out, final @NonNull Recipe recipe) throws IOException {
+		ObjectMapper mapper = new ObjectMapper();
+		mapper.registerModule(new Jdk8Module());
+		mapper.writeValue(out, recipe);
+	}
+
+	public Recipe load(final @NonNull File handle) throws IOException {
+		try (FileReader file = new FileReader(handle);
+				BufferedReader buf = new BufferedReader(file)) {
+			return load(buf);
+		}
+	}
+	
+	public void save(final @NonNull File handle, final @NonNull Recipe recipe) throws IOException {
+		try (FileWriter file = new FileWriter(handle);
+				BufferedWriter buf = new BufferedWriter(file)) {
+			save(buf, recipe);
+		}
+	}
+}

+ 12 - 17
src/main/lombok/org/leumasjaffe/recipe/view/RecipeFrame.java

@@ -3,8 +3,7 @@ package org.leumasjaffe.recipe.view;
 import javax.swing.JFrame;
 import javax.swing.JTabbedPane;
 
-import org.leumasjaffe.container.functional.Result;
-import org.leumasjaffe.recipe.controller.IOController;
+import org.leumasjaffe.recipe.controller.FileController;
 import org.leumasjaffe.recipe.model.Product;
 import org.leumasjaffe.recipe.model.Recipe;
 
@@ -23,13 +22,13 @@ import java.awt.event.InputEvent;
 
 @SuppressWarnings("serial")
 @FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
-public class RecipeFrame extends JFrame {
-	IOController io = new IOController();
+public class RecipeFrame extends JFrame implements FileController.Model {
 	SummaryPanel summaryPanel;
 	JTabbedPane tabbedPane;
 	
 	public RecipeFrame() {
-		
+		FileController<RecipeFrame> fileController = new FileController<>(this);
+
 		final int MASK = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
 		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 		
@@ -41,18 +40,22 @@ public class RecipeFrame extends JFrame {
 		
 		JMenuItem mntmNew = new JMenuItem("New");
 		mntmNew.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, MASK));
+		mntmNew.addActionListener(e -> fileController.create());
 		mnFile.add(mntmNew);
 		
 		JMenuItem mntmOpen = new JMenuItem("Open");
 		mntmOpen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, MASK));
+		mntmNew.addActionListener(e -> fileController.open());
 		mnFile.add(mntmOpen);
 		
 		JMenuItem mntmSave = new JMenuItem("Save");
 		mntmSave.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, MASK));
+		mntmNew.addActionListener(e -> fileController.save());
 		mnFile.add(mntmSave);
 		
 		JMenuItem mntmSaveAs = new JMenuItem("Save As");
 		mntmSaveAs.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, MASK | InputEvent.SHIFT_MASK));
+		mntmNew.addActionListener(e -> fileController.saveAs());
 		mnFile.add(mntmSaveAs);
 		
 		JMenuItem mntmQuit = new JMenuItem("Quit");
@@ -66,28 +69,20 @@ public class RecipeFrame extends JFrame {
 		summaryPanel = new SummaryPanel();
 		tabbedPane.addTab("Summary", summaryPanel);
 		
-		// TODO Switch these around...
-//		setModel(new Recipe());
-		open("src/test/resources/example.json");
+//		fileController.create();
+		fileController.open("src/test/resources/example.json");
 
 		pack();
 		repaint();
 		setVisible(true);
 	}
 	
-	private void open(final String filename) {
-		Result.maybe(io::load).apply(filename).consume(this::setModel, this::errorPopup);
-	}
-	
-	private void setModel(final Recipe recipe) {
+	@Override
+	public void setModel(final Recipe recipe) {
 		// TODO Clear underlying panels
 		for (Product comp : recipe.getProducts()) {
 			summaryPanel.addProduct(comp);
 			tabbedPane.addTab(comp.getName(), new ProductPanel(comp));
 		}
 	}
-	
-	private void errorPopup(final Exception ex) {
-		JOptionPane.showMessageDialog(this, ex.getLocalizedMessage(), "File Error", JOptionPane.ERROR_MESSAGE);
-	}
 }