/* * PrintPreviewPanel.java 27 aout 07 * * Sweet Home 3D, Copyright (c) 2007 Emmanuel PUYBARET / eTeks <info@eteks.com> * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package com.eteks.sweethome3d.swing; import java.awt.Color; import java.awt.Component; import java.awt.ComponentOrientation; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.event.ActionEvent; import java.util.Locale; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JToolBar; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.border.AbstractBorder; import com.eteks.sweethome3d.model.Home; import com.eteks.sweethome3d.model.UserPreferences; import com.eteks.sweethome3d.tools.OperatingSystem; import com.eteks.sweethome3d.viewcontroller.DialogView; import com.eteks.sweethome3d.viewcontroller.HomeController; import com.eteks.sweethome3d.viewcontroller.PrintPreviewController; import com.eteks.sweethome3d.viewcontroller.View; /** * Home print preview editing panel. * @author Emmanuel Puybaret */ public class PrintPreviewPanel extends JPanel implements DialogView { private enum ActionType {SHOW_PREVIOUS_PAGE, SHOW_NEXT_PAGE} private final UserPreferences preferences; private JToolBar toolBar; private HomePrintableComponent printableComponent; private JLabel pageLabel; /** * Creates a panel that displays print preview. * @param home home previewed by this panel * @param preferences the user preferences from which localized data is retrieved * @param homeController the controller of <code>home</code> * @param printPreviewController the controller of this panel */ public PrintPreviewPanel(Home home, UserPreferences preferences, HomeController homeController, PrintPreviewController printPreviewController) { super(new ProportionalLayout()); this.preferences = preferences; createActions(preferences); installKeyboardActions(); createComponents(home, homeController); layoutComponents(); updateComponents(); } /** * Creates actions. */ private void createActions(UserPreferences preferences) { // Show previous page action Action showPreviousPageAction = new ResourceAction( preferences, PrintPreviewPanel.class, ActionType.SHOW_PREVIOUS_PAGE.name()) { @Override public void actionPerformed(ActionEvent e) { printableComponent.setPage(printableComponent.getPage() - 1); updateComponents(); } }; // Show next page action Action showNextPageAction = new ResourceAction( preferences, PrintPreviewPanel.class, ActionType.SHOW_NEXT_PAGE.name()) { @Override public void actionPerformed(ActionEvent e) { printableComponent.setPage(printableComponent.getPage() + 1); updateComponents(); } }; ActionMap actionMap = getActionMap(); actionMap.put(ActionType.SHOW_PREVIOUS_PAGE, showPreviousPageAction); actionMap.put(ActionType.SHOW_NEXT_PAGE, showNextPageAction); } /** * Installs keys bound to actions. */ private void installKeyboardActions() { InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW); inputMap.put(KeyStroke.getKeyStroke("LEFT"), ActionType.SHOW_PREVIOUS_PAGE); inputMap.put(KeyStroke.getKeyStroke("UP"), ActionType.SHOW_PREVIOUS_PAGE); inputMap.put(KeyStroke.getKeyStroke("PAGE_UP"), ActionType.SHOW_PREVIOUS_PAGE); inputMap.put(KeyStroke.getKeyStroke("RIGHT"), ActionType.SHOW_NEXT_PAGE); inputMap.put(KeyStroke.getKeyStroke("DOWN"), ActionType.SHOW_NEXT_PAGE); inputMap.put(KeyStroke.getKeyStroke("PAGE_DOWN"), ActionType.SHOW_NEXT_PAGE); } /** * Creates and initializes components. */ private void createComponents(Home home, HomeController homeController) { this.printableComponent = new HomePrintableComponent(home, homeController, getFont()); this.printableComponent.setBorder(BorderFactory.createCompoundBorder( new AbstractBorder() { @Override public Insets getBorderInsets(Component c) { return new Insets(0, 0, 5, 5); } @Override public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { Graphics2D g2D = (Graphics2D)g; Color oldColor = g2D.getColor(); // Fill left and right border with a gradient for (int i = 0; i < 5; i++) { g2D.setColor(new Color(128, 128, 128, 200 - i * 45)); g2D.drawLine(x + width - 5 + i, y + i, x + width - 5 + i, y + height - 5 + i); g2D.drawLine(x + i, y + height - 5 + i, x + width - 5 + i - 1, y + height - 5 + i); } g2D.setColor(oldColor); } }, BorderFactory.createLineBorder(Color.BLACK))); this.pageLabel = new JLabel(); this.toolBar = new JToolBar() { public void applyComponentOrientation(ComponentOrientation orientation) { // Ignore orientation } }; this.toolBar.setFloatable(false); ActionMap actions = getActionMap(); if (OperatingSystem.isMacOSXLeopardOrSuperior() && OperatingSystem.isJavaVersionGreaterOrEqual("1.7")) { // Add buttons with higher insets to ensure the top and bottom of segmented buttons are correctly drawn class HigherInsetsButton extends JButton { public HigherInsetsButton(Action action) { super(action); } @Override public Insets getInsets() { Insets insets = super.getInsets(); insets.top += 3; insets.bottom += 3; return insets; } } toolBar.add(new HigherInsetsButton(actions.get(ActionType.SHOW_PREVIOUS_PAGE))); toolBar.add(new HigherInsetsButton(actions.get(ActionType.SHOW_NEXT_PAGE))); } else { this.toolBar.add(actions.get(ActionType.SHOW_PREVIOUS_PAGE)); this.toolBar.add(actions.get(ActionType.SHOW_NEXT_PAGE)); } updateToolBarButtonsStyle(this.toolBar); this.toolBar.add(Box.createHorizontalStrut(20)); this.toolBar.add(this.pageLabel); // Remove focusable property on buttons for (int i = 0, n = toolBar.getComponentCount(); i < n; i++) { toolBar.getComponentAtIndex(i).setFocusable(false); } } /** * Under Mac OS X 10.5 use segmented buttons with properties * depending on toolbar orientation. */ private void updateToolBarButtonsStyle(JToolBar toolBar) { // Use segmented buttons under Mac OS X 10.5 if (OperatingSystem.isMacOSXLeopardOrSuperior()) { // Retrieve component orientation because Mac OS X 10.5 miserably doesn't it take into account JComponent previousButton = (JComponent)toolBar.getComponentAtIndex(0); previousButton.putClientProperty("JButton.buttonType", "segmentedTextured"); previousButton.putClientProperty("JButton.segmentPosition", "first"); JComponent nextButton = (JComponent)toolBar.getComponentAtIndex(1); nextButton.putClientProperty("JButton.buttonType", "segmentedTextured"); nextButton.putClientProperty("JButton.segmentPosition", "last"); } } /** * Layouts panel components in panel with their labels. */ private void layoutComponents() { // Add toolbar at top in a flow layout panel to make it centered JPanel panel = new JPanel(); panel.add(this.toolBar); add(panel, ProportionalLayout.Constraints.TOP); // Add printable component at bottom of proportional layout panel add(this.printableComponent, ProportionalLayout.Constraints.BOTTOM); } /** * Updates components. */ private void updateComponents() { ActionMap actions = getActionMap(); actions.get(ActionType.SHOW_PREVIOUS_PAGE).setEnabled(this.printableComponent.getPage() > 0); actions.get(ActionType.SHOW_NEXT_PAGE).setEnabled( this.printableComponent.getPage() < this.printableComponent.getPageCount() - 1); this.pageLabel.setText(preferences.getLocalizedString( PrintPreviewPanel.class, "pageLabel.text", this.printableComponent.getPage() + 1, this.printableComponent.getPageCount())); } /** * Displays this panel in a modal resizable dialog box. */ public void displayView(View parentView) { String dialogTitle = preferences.getLocalizedString(PrintPreviewPanel.class, "printPreview.title"); JOptionPane optionPane = new JOptionPane(this, JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION); if (parentView != null) { optionPane.setComponentOrientation(((JComponent)parentView).getComponentOrientation()); } JDialog dialog = optionPane.createDialog(SwingUtilities.getRootPane((JComponent)parentView), dialogTitle); dialog.applyComponentOrientation(ComponentOrientation.getOrientation(Locale.getDefault())); dialog.setResizable(true); // Pack again because resize decorations may have changed dialog preferred size dialog.pack(); dialog.setMinimumSize(dialog.getPreferredSize()); dialog.setVisible(true); dialog.dispose(); } }