浏览代码

Refactor FileMenu into its own class.

Sam Jaffe 5 年之前
父节点
当前提交
b2f8e51f23

+ 49 - 0
src/main/lombok/org/leumasjaffe/recipe/view/FileMenu.java

@@ -0,0 +1,49 @@
+package org.leumasjaffe.recipe.view;
+
+import java.awt.Toolkit;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowEvent;
+
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.KeyStroke;
+
+import org.leumasjaffe.recipe.controller.FileController;
+
+@SuppressWarnings("serial")
+public class FileMenu extends JMenu {
+	static final int MASK = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
+
+	public FileMenu(JFrame parent, FileController fileController) {
+		super("File");
+		
+		JMenuItem mntmNew = new JMenuItem("New");
+		mntmNew.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, MASK));
+		mntmNew.addActionListener(e -> fileController.create());
+		add(mntmNew);
+		
+		JMenuItem mntmOpen = new JMenuItem("Open");
+		mntmOpen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, MASK));
+		mntmOpen.addActionListener(e -> fileController.open());
+		add(mntmOpen);
+		
+		JMenuItem mntmSave = new JMenuItem("Save");
+		mntmSave.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, MASK));
+		mntmSave.addActionListener(e -> fileController.save());
+		add(mntmSave);
+		
+		JMenuItem mntmSaveAs = new JMenuItem("Save As");
+		mntmSaveAs.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, MASK | InputEvent.SHIFT_MASK));
+		mntmSaveAs.addActionListener(e -> fileController.saveAs());
+		add(mntmSaveAs);
+		
+		JMenuItem mntmQuit = new JMenuItem("Quit");
+		mntmQuit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, MASK));
+		mntmQuit.addActionListener(e -> {
+			parent.dispatchEvent(new WindowEvent(parent, WindowEvent.WINDOW_CLOSING));
+		});
+		add(mntmQuit);
+	}
+}

+ 8 - 37
src/main/lombok/org/leumasjaffe/recipe/view/RecipeFrame.java

@@ -12,12 +12,7 @@ import lombok.experimental.FieldDefaults;
 
 import javax.swing.JMenuBar;
 import javax.swing.JMenu;
-import javax.swing.JMenuItem;
-import javax.swing.KeyStroke;
-import java.awt.event.KeyEvent;
-import java.awt.event.WindowEvent;
 import java.awt.Toolkit;
-import java.awt.event.InputEvent;
 
 @SuppressWarnings("serial")
 @FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
@@ -28,40 +23,14 @@ public class RecipeFrame extends JFrame implements FileController.ViewModel {
 	public RecipeFrame() {
 		FileController fileController = new FileController(this);
 
-		final int MASK = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
 		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 		
 		JMenuBar menuBar = new JMenuBar();
 		setJMenuBar(menuBar);
 		
-		JMenu mnFile = new JMenu("File");
+		JMenu mnFile = new FileMenu(this, fileController);
 		menuBar.add(mnFile);
-		
-		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");
-		mntmQuit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, MASK));
-		mntmQuit.addActionListener( e -> { this.dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING)); } );
-		mnFile.add(mntmQuit);
-		
+				
 		tabbedPane = new JTabbedPane();
 		setContentPane(tabbedPane);
 
@@ -79,9 +48,11 @@ public class RecipeFrame extends JFrame implements FileController.ViewModel {
 	@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));
-		}
+		recipe.getProducts().forEach(this::addProduct);
+	}
+	
+	private void addProduct(final Product comp) {
+		summaryPanel.addProduct(comp);
+		tabbedPane.addTab(comp.getName(), new ProductPanel(comp));
 	}
 }

+ 75 - 0
src/test/java/org/leumasjaffe/recipe/view/FileMenuTest.java

@@ -0,0 +1,75 @@
+package org.leumasjaffe.recipe.view;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.*;
+
+import java.awt.event.KeyEvent;
+
+import javax.swing.JFrame;
+import javax.swing.JMenuBar;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.platform.runner.JUnitPlatform;
+import org.junit.runner.RunWith;
+import org.leumasjaffe.recipe.controller.FileController;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+@RunWith(JUnitPlatform.class)
+class FileMenuTest extends SwingTestCase {
+	
+	@Mock FileController controller;
+	JFrame spyFrame;
+	JMenuBar menuBar = new JMenuBar();
+	FileMenu menu;
+	
+	private KeyEvent getMenuEvent(int code, char key) {
+		return new KeyEvent(getTestFrame(), KeyEvent.KEY_PRESSED, 0, FileMenu.MASK, code, key);
+	}
+	
+	@BeforeEach
+	void setUp() {
+		getTestFrame().add(menuBar);
+		menu = new FileMenu(getTestFrame(), controller);
+		menuBar.add(menu);
+		// Key events don't go through without this
+		getTestFrame().setVisible(true);
+	}
+
+	@Test
+	void testShortcutNInvokesCreate() {
+		getTestFrame().dispatchEvent(getMenuEvent(KeyEvent.VK_N, 'n'));
+		verify(controller).create();
+	}
+
+	@Test
+	void testShortcutOInvokesOpen() {
+		getTestFrame().dispatchEvent(getMenuEvent(KeyEvent.VK_O, 'o'));
+		verify(controller).open();
+	}
+
+	@Test
+	void testShortcutSInvokesSave() {
+		getTestFrame().dispatchEvent(getMenuEvent(KeyEvent.VK_S, 's'));
+		verify(controller).save();
+	}
+
+	@Test
+	void testShortcutSInvokesSaveAs() {
+		getTestFrame().dispatchEvent(new KeyEvent(getTestFrame(), KeyEvent.KEY_PRESSED, 0, 
+				KeyEvent.SHIFT_MASK | FileMenu.MASK, KeyEvent.VK_S, 'S'));
+		verify(controller).saveAs();
+	}
+
+	@Test
+	void testShortcutQInvokesQuit() {
+		assertTrue(getTestFrame().isVisible());
+		getTestFrame().dispatchEvent(getMenuEvent(KeyEvent.VK_Q, 'q'));
+		assertFalse(getTestFrame().isVisible());
+	}
+
+}