Package com.agifans.picedit.gui.frame

Source Code of com.agifans.picedit.gui.frame.PictureFrame$NavigationButton

package com.agifans.picedit.gui.frame;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.KeyboardFocusManager;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;

import com.agifans.picedit.PicEdit;
import com.agifans.picedit.gui.PictureCodeList;
import com.agifans.picedit.gui.handler.KeyboardHandler;
import com.agifans.picedit.gui.handler.MouseHandler;
import com.agifans.picedit.picture.EditStatus;
import com.agifans.picedit.picture.Picture;
import com.agifans.picedit.types.ToolType;
import com.agifans.picedit.view.EgoTestHandler;

/**
* An internal picture frame to display in the desktop pane. There is one
* such frame for each picture that is loaded. It is in these frames that
* the pictures are displayed.
*
* @author Lance Ewing
*/
@SuppressWarnings("serial")
public class PictureFrame extends JInternalFrame implements InternalFrameListener {

    /**
     * The PicEdit application.
     */
    private PicEdit application;
   
    /**
     * The scroll pane that holds the picture panel.
     */
    private JScrollPane pictureScrollPane;
   
    /**
     * The panel containing the picture being edited.
     */
    private PicturePanel picturePanel;
   
    /**
     * Holds the current edit status of the picture in this frame.
     */
    private EditStatus editStatus;
   
    /**
     * The picture that is displayed in this frame.
     */
    private Picture picture;
   
    /**
     * The handler for managing the Ego Test mode.
     */
    private EgoTestHandler egoTestHandler;
   
    /**
     * Holds the maximum frame size for each zoom factor.
     */
    private Map<Integer, Dimension> maximumSizeMap;
   
    /**
     * The slider that sets the picture position.
     */
    private JSlider positionSlider;
   
    /**
     * The back navigation button. Goes back one picture action.
     */
    private NavigationButton backButton;
   
    /**
     * The forward navigation button. Goes forward one picture action.
     */
    private NavigationButton forwardButton;
   
    /**
     * The mouse handler for this picture frame.
     */
    private MouseHandler mouseHandler;
   
    /**
     * The initial default name for the picture prior to the first save.
     */
    private String defaultPictureName;
   
    /**
     * The JList of picture codes for this PictureFrames Picture.
     */
    private PictureCodeList pictureCodeList;
   
    /**
     * Constructor for PictureFrame.
     *
     * @param application The PicEdit application.
     * @param initialZoomFactor The initial zoome factor for this picture frame.
     * @param defaultPictureName The initial default name for the picture prior to the first save.
     */
    @SuppressWarnings("unchecked")
    public PictureFrame(final PicEdit application, int initialZoomFactor, String defaultPictureName) {
        this.application = application;
        this.defaultPictureName = defaultPictureName;
        this.editStatus = new EditStatus();
        this.editStatus.setZoomFactor(initialZoomFactor);
        this.picture = new Picture(editStatus);
        this.pictureCodeList = new PictureCodeList(picture);
        this.picture.addPictureChangeListener(pictureCodeList);
        this.egoTestHandler = new EgoTestHandler(editStatus, picture);
        this.picturePanel = new PicturePanel(editStatus, picture, egoTestHandler);
        mouseHandler = new MouseHandler(this, application);
        picturePanel.addMouseListener(mouseHandler);
        picturePanel.addMouseMotionListener(mouseHandler);
        picturePanel.addMouseWheelListener(mouseHandler);
       
        // This is import since without it a click on the picture frame stops the TAB accelerator key from working.
        this.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, Collections.EMPTY_SET);
        this.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, Collections.EMPTY_SET);
       
        this.calculateResizeDimensions();
        this.setLayout(new BorderLayout());
       
        KeyboardHandler keyboardHandler = new KeyboardHandler(application, egoTestHandler);
        this.getContentPane().addKeyListener(keyboardHandler);
       
        // Add the panel that holds the picture that is being edited.
        pictureScrollPane = new JScrollPane(picturePanel);
        pictureScrollPane.setMinimumSize(new Dimension(10, 10));
        pictureScrollPane.setOpaque(true);
        pictureScrollPane.setBackground(Color.lightGray);
        this.add(pictureScrollPane, BorderLayout.CENTER);
       
        JPanel bottomPanel = new JPanel();
        bottomPanel.setLayout(new BorderLayout());
        backButton = new NavigationButton("Back24.gif", NavigationButtonType.BACK);
        bottomPanel.add(backButton, BorderLayout.WEST);
        forwardButton = new NavigationButton("Forward24.gif", NavigationButtonType.FORWARD);
        bottomPanel.add(forwardButton, BorderLayout.EAST);
       
        positionSlider = new JSlider();
        positionSlider.setModel(new PositionSliderModel(picture));
        positionSlider.setFocusable(false);
        positionSlider.addChangeListener(pictureCodeList);
        bottomPanel.add(positionSlider, BorderLayout.CENTER);
        this.add(bottomPanel, BorderLayout.SOUTH);
       
        this.setIconifiable(true);
        this.setResizable(true);
        this.setClosable(true);
        this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        this.setSize(this.maximumSizeMap.get(editStatus.getZoomFactor()));
        this.setMaximumSize(this.maximumSizeMap.get(editStatus.getZoomFactor()));
        this.addInternalFrameListener(this);
        this.setVisible(true);
    }
   
    /**
     * Buttons used for picture navigation.
     */
    class NavigationButton extends JButton implements ActionListener {
        NavigationButton(String iconImageName, NavigationButtonType type) {
            Image iconImage = null;
            try {
                iconImage = ImageIO.read(ClassLoader.getSystemResource("com/agifans/picedit/images/" + iconImageName));
            } catch (IOException e) {
            }
            setIcon(new ImageIcon(iconImage));
            setPreferredSize(new Dimension(24, 24));
            setMaximumSize(new Dimension(24, 24));
            setFocusable(false);
            setFocusPainted(false);
            setBorderPainted(false);
            setMargin(new Insets(0, 0, 0, 0));
            setActionCommand(type.name());
            addActionListener(this);
        }

        /**
         * Processes the navigation button clicks.
         *
         * @param event The ActionEvent for the button click.
         */
        public void actionPerformed(ActionEvent event) {
            NavigationButtonType type = NavigationButtonType.valueOf(event.getActionCommand());
            switch (type) {
                case FORWARD:
                    application.getPicture().moveForwardOnePictureAction();
                    break;
                case BACK:
                    application.getPicture().moveBackOnePictureAction();
                    break;
            }
        }
    }
   
    public MouseHandler getMouseHandler() {
      return mouseHandler;
    }
   
    public EditStatus getEditStatus() {
        return editStatus;
    }
   
    public Picture getPicture() {
        return picture;
    }
   
    public PicturePanel getPicturePanel() {
        return picturePanel;
    }
   
    public JSlider getPositionSlider() {
        return positionSlider;
    }
   
    /**
     * Gets the picture code JList component that holds the list of human readable picture codes.
     *
     * @return The picture code JList component that holds the list of human readable picture codes.
     */
    public PictureCodeList getPictureCodeList() {
        return pictureCodeList;
    }
   
    public void calculateResizeDimensions() {
        this.maximumSizeMap = new HashMap<Integer, Dimension>();
        for (int i=1; i<=5; i++) {
            JInternalFrame frame = new JInternalFrame();
            JPanel panel = new JPanel();
            Dimension appDimension = new Dimension(320 * i, editStatus.getPictureType().getHeight() * i);
            panel.setPreferredSize(appDimension);
            JScrollPane scrollPane = new JScrollPane(panel);
            scrollPane.setMinimumSize(new Dimension(10, 10));
            frame.setLayout(new BorderLayout());
            JPanel bottomPanel = new JPanel();
            bottomPanel.setLayout(new BorderLayout());
            JSlider slider = new JSlider();
            JButton backButton = new JButton();
            backButton.setPreferredSize(new Dimension(24, 24));
            JButton forwardButton = new JButton();
            forwardButton.setPreferredSize(new Dimension(24, 24));
            bottomPanel.add(backButton, BorderLayout.WEST);
            bottomPanel.add(slider, BorderLayout.CENTER);
            bottomPanel.add(forwardButton, BorderLayout.EAST);
            frame.add(scrollPane, BorderLayout.CENTER);
            frame.add(bottomPanel, BorderLayout.SOUTH);
            frame.pack();
            frame.invalidate();
            this.maximumSizeMap.put(i, frame.getSize());
        }
    }
   
    public void resizeForZoomFactor(int zoomFactor) {
        this.editStatus.setZoomFactor(zoomFactor);
       
        // Update the size of the picture according to new zoom factor.
        picturePanel.setPreferredSize(new Dimension(320 * editStatus.getZoomFactor(), editStatus.getPictureType().getHeight() * editStatus.getZoomFactor()));
       
        // Apply the new maximum size to the frame.
        Dimension maximumSize = maximumSizeMap.get(editStatus.getZoomFactor());
        this.setMaximumSize(maximumSize);
       
        // Use max size for the new size of the frame. Works best this way when zooming out and in.
        Dimension desktopSize = this.application.getDesktopPane().getSize();
        Point frameLocation = this.getLocation();
        this.setSize(new Dimension(
                Math.min(maximumSize.width, desktopSize.width - frameLocation.x),
                Math.min(maximumSize.height, desktopSize.height - frameLocation.y)));
       
        // This will tell the scroll pane to adjust itself.
        picturePanel.revalidate();
    }
   
    /**
     * Paints the PictureFrame.
     */
    public void paint(Graphics g) {
        super.paint(g);
       
        // Update slider enabled status based on whether line is being drawn or not. Slider
        // cannot be used if line drawing is active.
        positionSlider.setEnabled(!editStatus.isLineBeingDrawn());
        forwardButton.setEnabled(!editStatus.isLineBeingDrawn());
        backButton.setEnabled(!editStatus.isLineBeingDrawn());
       
        // Make sure the slider is up to date with the picture position.
        positionSlider.getModel().setValue(picture.getPicturePosition());
       
        // Update the title to show the current picture name.
        StringBuilder title = new StringBuilder();
        if (editStatus.hasUnsavedChanges()) {
          title.append("*");
        }
        if (editStatus.getPictureFile() == null) {
            title.append(defaultPictureName);
        } else {
            title.append(editStatus.getPictureFile().getName());
        }
        this.setTitle(title.toString());
    }

    public void internalFrameActivated(InternalFrameEvent event) {
        Dimension desktopSize = application.getDesktopPane().getSize();
        int newWidth = Math.min(desktopSize.width, this.getWidth());
        int newHeight = Math.min(desktopSize.height, this.getHeight());
        this.setSize(new Dimension(newWidth, newHeight));
       
        // Updates the View menu items to reflect the new frames picture edit status.
        application.getMenu().updateViewMenuItems();
       
        // Switch in the JList that holds the picture codes for the current PictureFrame.
        application.switchPictureCodeList();
    }

    public void internalFrameClosed(InternalFrameEvent event) {
    }

    public void internalFrameClosing(InternalFrameEvent event) {
        if (editStatus.hasUnsavedChanges() && (picture.getPictureCodes().size() > 1)) {
            Object[] saveOptions = { "Save", "Don't Save", "Cancel" };
            StringBuilder message = new StringBuilder();
            message.append("<html><b>Do you want to save the changes you made<br/>to the picture \"");
            if (editStatus.getPictureFile() == null) {
                message.append(defaultPictureName);
            } else {
                message.append(editStatus.getPictureFile().getName());
            }
            message.append("\"?</b><br/><br/><p>Your changes will be lost if you don�t save them.</p><br/></html>");
            int answer = JOptionPane.showOptionDialog(application, message.toString(), "Save Changes", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, saveOptions, saveOptions[0]);
            switch (answer) {
                case JOptionPane.YES_OPTION:
                    // Save before closing.
                    picture.savePicture(editStatus.getPictureFile());
                    application.updateRecentPictures(editStatus.getPictureFile());
                    dispose();
                    break;
                case JOptionPane.NO_OPTION:
                    dispose();
                    break;
                case JOptionPane.CANCEL_OPTION:
                    // Do nothing. Ignore close.
                    return;
            }
        } else {
            // No unsaved changes, so let the picture frame close.
            dispose();
        }
       
        // After closing, select the next frame (if there is one)
        application.selectNextPictureFrame();
    }

    /**
     * Invokes when the picture frame is deactivated. If after being deactivated there is
     * no active frame then it asks to be selected again.
     */
    public void internalFrameDeactivated(InternalFrameEvent event) {
        this.editStatus.setTool(ToolType.NONE);
    }

    public void internalFrameDeiconified(InternalFrameEvent event) {
    }

    public void internalFrameIconified(InternalFrameEvent event) {
    }

    public void internalFrameOpened(InternalFrameEvent event) {
    }
}
TOP

Related Classes of com.agifans.picedit.gui.frame.PictureFrame$NavigationButton

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.