/* * Copyright (C) 2015 Patryk Strach * * This file is part of Virtual Slide Viewer. * * Virtual Slide Viewer is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software Foundation, * either version 3 of the License, or (at your option) any later version. * * Virtual Slide Viewer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with Virtual Slide Viewer. * If not, see <http://www.gnu.org/licenses/>. */ package virtualslideviewer.ui; import java.awt.*; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.WindowEvent; import java.util.ArrayList; import java.util.List; import javax.swing.*; import javax.swing.border.BevelBorder; import javax.swing.border.EmptyBorder; import virtualslideviewer.config.ApplicationConfiguration; import virtualslideviewer.ui.utils.Region; import virtualslideviewer.ui.utils.SwingRegion; public class MainWindow extends JFrame implements MainView { private static final long serialVersionUID = 1L; private JMenuItem mUndoMenu; private JMenuItem mRedoMenu; private SwingRegion mMainRegion; private JPanel mStatusBarPanel; private JLabel mStatusLabel; private final List<Listener> mListeners = new ArrayList<>(); public MainWindow(JMenu fileMenu) { if(fileMenu == null) throw new IllegalArgumentException("fileMenu cannot be null."); super.setTitle("Virtual Slide Viewer"); super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); initializeMenu(fileMenu); initializeMainRegion(); createStatusBar(); layoutComponents(); } private void initializeMenu(JMenu fileMenu) { JMenuBar menuBar = new JMenuBar(); menuBar.add(fileMenu); initializeEditMenu(menuBar); initializeHelpMenu(menuBar); super.setJMenuBar(menuBar); } private void initializeEditMenu(JMenuBar menuBar) { JMenu editMenu = new JMenu("Edit"); mUndoMenu = new JMenuItem("Undo"); mRedoMenu = new JMenuItem("Redo"); mUndoMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_MASK)); mRedoMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, InputEvent.CTRL_MASK)); mUndoMenu.addActionListener((x) -> mListeners.forEach(l -> l.onUndo())); mRedoMenu.addActionListener((x) -> mListeners.forEach(l -> l.onRedo())); editMenu.add(mUndoMenu); editMenu.add(mRedoMenu); editMenu.addSeparator(); JMenuItem preferencesMenu = new JMenuItem("Preferences"); preferencesMenu.addActionListener(x -> mListeners.forEach(l -> l.onOpenPreferences())); editMenu.add(preferencesMenu); menuBar.add(editMenu); } private void initializeHelpMenu(JMenuBar menuBar) { JMenu helpMenu = new JMenu("Help"); JMenuItem aboutMenu = new JMenuItem("About"); aboutMenu.addActionListener((x) -> mListeners.forEach(l -> l.onAboutClick())); helpMenu.add(aboutMenu); menuBar.add(helpMenu); } private void initializeMainRegion() { mMainRegion = new SwingRegion(); mMainRegion.changeView(new NoSlideLoadedMainPanelPlaceholder()); } private void createStatusBar() { mStatusBarPanel = new JPanel(); mStatusBarPanel.setBorder(new BevelBorder(BevelBorder.LOWERED)); mStatusBarPanel.setLayout(new BoxLayout(mStatusBarPanel, BoxLayout.X_AXIS)); mStatusBarPanel.setVisible(false); mStatusLabel = new JLabel(); mStatusLabel.setFont(new Font("Dialog", Font.PLAIN, 11)); mStatusLabel.setHorizontalAlignment(SwingConstants.LEFT); mStatusBarPanel.add(mStatusLabel); } private void layoutComponents() { JPanel contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(3, 3, 3, 3)); contentPane.setLayout(new BorderLayout(0, 0)); setContentPane(contentPane); contentPane.add(mMainRegion); contentPane.add(mStatusBarPanel, BorderLayout.SOUTH); } @Override public void setStatusMessage(String message) { if(message == null) throw new IllegalArgumentException("message cannot be null."); mStatusBarPanel.setVisible(true); mStatusLabel.setText(message); } @Override public void addListener(Listener listener) { if(listener == null) throw new IllegalArgumentException("listener cannot be null."); mListeners.add(listener); } @Override public void setUndoEnabled(boolean enable) { mUndoMenu.setEnabled(enable); } @Override public void setRedoEnabled(boolean enable) { mRedoMenu.setEnabled(enable); } @Override public void displayErrorMessage(String message) { JOptionPane.showMessageDialog(this, message, "Error", JOptionPane.ERROR_MESSAGE); } @Override public void restoreLayoutFromConfiguration(ApplicationConfiguration configuration) { if(configuration == null) throw new IllegalArgumentException("configuration cannot be null."); super.setBounds(configuration.getWindowBounds()); } @Override public void saveLayoutToConfiguration(ApplicationConfiguration configuration) { if(configuration == null) throw new IllegalArgumentException("configuration cannot be null."); configuration.setWindowBounds(super.getBounds()); } public Region getMainRegion() { return mMainRegion; } @Override @SuppressWarnings("deprecation") public void show() { EventQueue.invokeLater(() -> { // Cannot invoke setVisible(true) due to a conflict between JFrame.show() and MainView.show(). // Invoking setVisible(true) will internally invoke MainWindow.show() instead of JFrame.show(), which is not what we want. // An explicit interface implementation construct from a C# would help here, but Java does not support it. super.show(); }); } @Override protected void processWindowEvent(WindowEvent e) { if(e.getID() == WindowEvent.WINDOW_CLOSING) { mListeners.forEach(l -> l.onViewClosing()); } super.processWindowEvent(e); } }