Package com.agifans.picedit.gui.toolbar

Source Code of com.agifans.picedit.gui.toolbar.ToolPanel$ColourButton$ColourButtonModel

package com.agifans.picedit.gui.toolbar;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.DefaultButtonModel;
import javax.swing.ImageIcon;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.RootPaneContainer;
import javax.swing.SwingUtilities;
import javax.swing.plaf.metal.MetalToolBarUI;

import com.agifans.picedit.PicEdit;
import com.agifans.picedit.picture.EditStatus;
import com.agifans.picedit.picture.Picture;
import com.agifans.picedit.types.ColourType;
import com.agifans.picedit.types.ToolType;
import com.agifans.picedit.utils.EgaPalette;
import com.agifans.picedit.utils.OSChecker;

/**
* The tool panel that is displayed at the bottom of the picture.
*
* @author Lance Ewing
*/
@SuppressWarnings("serial")
public class ToolPanel extends JToolBar {

    /**
     * Constructor for ToolPanel.
     *
     * @param application The PicEdit application.
     */
    public ToolPanel(final PicEdit application) {
        super(JToolBar.VERTICAL);
       
        ToolPanelActionListener actionListener = new ToolPanelActionListener(application);
        ToolButton selectionButton = new ToolButton("selection.png", application, actionListener, ToolType.SELECTION);
        selectionButton.setEnabled(false);
        ToolButton zoomButton = new ToolButton("zoom.png", application, actionListener, ToolType.ZOOM);
        zoomButton.setEnabled(false);
        ToolButton lineButton = new ToolButton("line.png", application, actionListener, ToolType.LINE);
        ToolButton shortLineButton = new ToolButton("shortline.png", application, actionListener, ToolType.SHORTLINE);
        ToolButton stepLineButton = new ToolButton("stepline.png", application, actionListener, ToolType.STEPLINE);
        ToolButton fillButton = new ToolButton("fill.png", application, actionListener, ToolType.FILL);
        ToolButton airbrushButton = new ToolButton("airbrush.png", application, actionListener, ToolType.AIRBRUSH);
        ToolButton brushButton = new ToolButton("brush.png", application, actionListener, ToolType.BRUSH);
        ToolButton rectangleButton = new ToolButton("rectangle.png", application, actionListener, ToolType.RECTANGLE);
        rectangleButton.setEnabled(false);
        ToolButton ellipseButton = new ToolButton("ellipse.png", application, actionListener, ToolType.ELLIPSE);
        ellipseButton.setEnabled(false);
        ToolButton eyeDropperButton = new ToolButton("eyedropper.png", application, actionListener, ToolType.EYEDROPPER);
        eyeDropperButton.setEnabled(false);
        ToolButton eraserButton = new ToolButton("eraser.png", application, actionListener, ToolType.ERASER);
        eraserButton.setEnabled(false);

        final JPanel buttonContainer = new JPanel();
        buttonContainer.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
        buttonContainer.setPreferredSize(new Dimension(64, 192));
        buttonContainer.setMaximumSize(new Dimension(64, 192));
        buttonContainer.add(selectionButton);
        buttonContainer.add(zoomButton);
        buttonContainer.add(lineButton);
        buttonContainer.add(shortLineButton);
        buttonContainer.add(stepLineButton);
        buttonContainer.add(fillButton);
        buttonContainer.add(airbrushButton);
        buttonContainer.add(brushButton);
        buttonContainer.add(rectangleButton);
        buttonContainer.add(ellipseButton);
        buttonContainer.add(eyeDropperButton);
        buttonContainer.add(eraserButton);
        this.add(buttonContainer);
       
        this.addSeparator();
       
        final JPanel colourPanel = new JPanel();
        colourPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
        colourPanel.setPreferredSize(new Dimension(64, 64));
        colourPanel.setMaximumSize(new Dimension(64, 64));
        ColourButtonPanel visualButton = new ColourButtonPanel(ColourType.VISUAL, application);
        colourPanel.add(visualButton);
        ColourButtonPanel priorityButton = new ColourButtonPanel(ColourType.PRIORITY, application);
        colourPanel.add(priorityButton);
        this.add(colourPanel);
       
        this.addSeparator();
       
        JPanel filler = new JPanel();
        this.add(filler);
       
        this.setFocusable(false);
        this.setUI(new PicEditToolBarUI());
        this.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(final java.beans.PropertyChangeEvent evt) {
                if ("ancestor".equals(evt.getPropertyName())) {
                    if (evt.getNewValue() != null) {
                        Window window = SwingUtilities.windowForComponent((JComponent)evt.getNewValue());
                        if (window instanceof PicEditToolBarUI.PicEditToolBarUIDialog) {
                            // Floating.
                            buttonContainer.setPreferredSize(new Dimension(128, 96));
                            buttonContainer.setMaximumSize(new Dimension(128, 96));
                            colourPanel.setPreferredSize(new Dimension(128, 32));
                            colourPanel.setMaximumSize(new Dimension(128, 32));
                            ToolPanel.this.setOrientation(JToolBar.VERTICAL);
                            application.setToolPanelLocation(ToolPanelLocation.FLOATING);
                        } else {
                            // Docking.
                            if (ToolPanel.this.getOrientation() == JToolBar.VERTICAL) {
                                buttonContainer.setPreferredSize(new Dimension(64, 192));
                                buttonContainer.setMaximumSize(new Dimension(64, 192));
                                colourPanel.setPreferredSize(new Dimension(64, 64));
                                colourPanel.setMaximumSize(new Dimension(64, 64));
                                SwingUtilities.invokeLater(new Runnable() {
                                    public void run() {
                                        String borderConstraints = (String)((BorderLayout)((JComponent)evt.getNewValue()).getLayout()).getConstraints(ToolPanel.this);
                                            if (BorderLayout.EAST.equals(borderConstraints)) {
                                                application.setToolPanelLocation(ToolPanelLocation.DOCKED_RIGHT);
                                            } else {
                                                application.setToolPanelLocation(ToolPanelLocation.DOCKED_LEFT);
                                            }
                                        }
                                    }
                                );
                            } else {
                                buttonContainer.setPreferredSize(new Dimension(384, 32));
                                buttonContainer.setMaximumSize(new Dimension(384, 32));
                                colourPanel.setPreferredSize(new Dimension(128, 32));
                                colourPanel.setMaximumSize(new Dimension(128, 32));
                                application.setToolPanelLocation(ToolPanelLocation.DOCKED_TOP);
                            }
                        }
                    }
                }
            }
        });
    }
   
    /**
     * A panel to hold the ColourButton. This panel will make sure there is a visually
     * sufficient gap between the left side and the checkbox.
     */
    class ColourButtonPanel extends JPanel {
       
        /**
         * Constructor for ColourButtonPanel.
         *
         * @param colourType The type of colour button.
         * @param application The PicEdit application.
         */
        ColourButtonPanel(ColourType colourType, PicEdit application) {
            this.setPreferredSize(new Dimension(64, 32));
            this.setMaximumSize(new Dimension(64, 32));
            this.setLayout(null);
            ColourButton colourButton = new ColourButton(colourType, application);
            if (OSChecker.isMac()) {
                colourButton.setBounds(3, 3, 58, 26);
            } else {
                colourButton.setBounds(7, 3, 54, 26);
            }
            this.add(colourButton);
        }
       
        /**
         * Paints the ColourButtonPanel component.
         *
         * @param graphics The Graphics to use to drawn the ColourButtonPanel component.
         */
        public void paintComponent(Graphics graphics) {
          super.paintComponent(graphics);
          graphics.setColor(Color.GRAY);
          graphics.drawRect(2, 2, 60, 27);
        }
    }
   
    /**
     * Colour button class used for the visual and priority colour changing buttons.
     */
    class ColourButton extends JCheckBox {
       
        /**
         * The PicEdit application.
         */
        private PicEdit application;
       
        /**
         * The type of colour button.
         */
        private ColourType colourType;
       
        /**
         * Constructor for ColourButton.
         *
         * @param colourType The type of colour button.
         * @param application The PicEdit application.
         */
        ColourButton(final ColourType colourType, final PicEdit application) {
            super();
           
            this.colourType = colourType;
            this.application = application;
           
            if (OSChecker.isMac()) {
                this.setPreferredSize(new Dimension(58, 26));
                this.setMaximumSize(new Dimension(58, 26));
            } else {
                this.setPreferredSize(new Dimension(54, 26));
                this.setMaximumSize(new Dimension(54, 26));
            }
            this.setFocusable(false);
            this.setFocusPainted(false);
            this.setMargin(new Insets(0, 0, 0, 0));
            this.setToolTipText(colourType.getDisplayName());
            this.setModel(new ColourButtonModel());
            this.addMouseListener(new ColourButtonMouseListener());
        }
       
        /**
         * Paints the ColourButton component.
         *
         * @param graphics The Graphics to use to drawn the ColourButton component.
         */
        public void paintComponent(Graphics graphics) {
            super.paintComponent(graphics);
            int colourCode = -1;
            switch (colourType) {
                case VISUAL:
                    if (application.getEditStatus().isVisualDrawEnabled()) {
                        colourCode = application.getEditStatus().getVisualColour();
                        colourCode = (colourCode == EditStatus.TRANSPARENT? 15 : colourCode);
                        graphics.setColor(EgaPalette.COLOR_OBJECTS[colourCode]);
                        if (OSChecker.isMac()) {
                            graphics.fillRect(26, 2, 31, 22);
                        } else {
                            graphics.fillRect(22, 2, 31, 22);
                        }
                    }
                    break;
                case PRIORITY:
                    if (application.getEditStatus().isPriorityDrawEnabled()) {
                        colourCode = application.getEditStatus().getPriorityColour();
                        colourCode = (colourCode == EditStatus.TRANSPARENT? 4 : colourCode);
                        graphics.setColor(EgaPalette.COLOR_OBJECTS[colourCode]);
                        if (OSChecker.isMac()) {
                            graphics.fillRect(26, 2, 31, 22);
                        } else {
                            graphics.fillRect(22, 2, 31, 22);
                        }
                    }
                    break;
            }
            graphics.setColor(Color.GRAY);
            graphics.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 18));
            if ((colourCode >= 0) && (colourCode <= 8)) {
                graphics.setColor(Color.WHITE);
            } else if ((colourCode >= 9) && (colourCode <= 15)) {
                graphics.setColor(Color.BLACK);
            }
            if (OSChecker.isMac()) {
              graphics.drawString("" + colourType.getDisplayName().charAt(0), 36, 20);
            } else {
              graphics.drawString("" + colourType.getDisplayName().charAt(0), 32, 20);
            }
        }
       
        /**
         * ButtonModel used to determine the ColourButton state.
         */
        class ColourButtonModel extends DefaultButtonModel {
           
            /**
             * Determines whether the ColourButton checkbox is checked on not based on the
             * visual or priority enabled flag in the EditStatus.
             *
             * @return true if the ColourButton is selected; otherwise false.
             */
            public boolean isSelected() {
                switch (colourType) {
                    case VISUAL:
                        return application.getEditStatus().isVisualDrawEnabled();
                    case PRIORITY:
                        return application.getEditStatus().isPriorityDrawEnabled();
                    default:
                        return false;
                }
            }
           
            /**
             * Indicates if the button can be selected or triggered by an input device, such
             * as a mouse pointer.
             *
             * @return <code>true</code> if the button is enabled
             */
            public boolean isEnabled() {
                boolean enabled = false;
               
                if (application != null) {
                    // Tools are only active when at least one picture frame is displayed,
                    // and the current position is not on a data code. We don't want the
                    // user to use the tools within the middle of an existing action.
                    enabled = application.hasVisiblePictureFrame() && !application.getPicture().getCurrentPictureCode().isDataCode();
                }
               
                return enabled;
            }
        }
       
        /**
         * MouseListener that processes clicks on a ColourButton.
         */
        class ColourButtonMouseListener extends MouseAdapter {
           
            /**
             * Processes mouse pressed events on the ColourButton.
             *
             * @param event The mouse pressed event to process.
             */
            public void mousePressed(MouseEvent event) {
                // We will only process mouse clicks if at least one picture frame is
                // being displayed and the current position is not on a data code. We
                // don't want the user to use the tools within the middle of an existing action.
                if (application.hasVisiblePictureFrame() && !application.getPicture().getCurrentPictureCode().isDataCode()) {
                    Point mousePoint = event.getPoint();
                    Rectangle colourBox = new Rectangle(30, 5, 30, 23);
                    boolean clickInColourBox = colourBox.contains(mousePoint);
                    EditStatus editStatus = application.getEditStatus();
                    Picture picture = application.getPicture();
                   
                    switch (colourType) {
                        case VISUAL:
                            if (editStatus.isVisualDrawEnabled() && !clickInColourBox) {
                                // If click is on the visual button but not in the colour box and visual
                                // drawing is currently on then turn off visual drawing.
                                picture.processVisualColourOff();
                            } else {
                                // Pop up colour chooser.
                                ColourChooserDialog dialog = new ColourChooserDialog(ColourButton.this);
                                dialog.setVisible(true);
                               
                                // Process the chosen visual colour.
                                if (dialog.getChosenColour() != -1) {
                                    picture.processVisualColourChange(dialog.getChosenColour());
                                }
                            }
                            break;
                        case PRIORITY:
                            if (editStatus.isPriorityDrawEnabled() && !clickInColourBox) {
                                // If click is on the priority button but not in the colour box and priority
                                // drawing is currently on then turn off priority drawing.
                                picture.processPriorityColourOff();
                            } else {
                                // Pop up colour chooser.
                                ColourChooserDialog dialog = new ColourChooserDialog(ColourButton.this);
                                dialog.setVisible(true);
                               
                                // Process the chosen priority colour.
                                if (dialog.getChosenColour() != -1) {
                                    picture.processPriorityColourChange(dialog.getChosenColour());
                                }
                            }
                            break;
                    }
                }
            }
        }
    }
   
    /**
     * Tool button class used for all buttons on the internal frames tool bar panel.
     */
    class ToolButton extends JToggleButton {
       
        /**
         * Constructor for PictureTool.
         *
         * @param iconImageName The name of the image file for the button icon.
         * @param application The PicEdit application.
         * @param actionListener The action listener that processes actions on this button.
         * @param tool The tool that this ToolButton is associated with.
         */
        ToolButton(String iconImageName, PicEdit application, ActionListener actionListener, ToolType tool) {
            super();
            setModel(new ToolButtonModel(tool, application));
            Image iconImage = null;
            Image pressedImage = null;
            Image hoveredImage = null;
            try {
                iconImage = ImageIO.read(ClassLoader.getSystemResource("com/agifans/picedit/images/" + iconImageName));
                pressedImage = ImageIO.read(ClassLoader.getSystemResource("com/agifans/picedit/images/pressed.png"));
                hoveredImage = ImageIO.read(ClassLoader.getSystemResource("com/agifans/picedit/images/hovered.png"));
            } catch (IOException e) {
            }
            setIcon(new ImageIcon(iconImage));
            setSelectedIcon(new ImageIcon(mergeImages(iconImage, pressedImage)));
            setRolloverIcon(new ImageIcon(mergeImages(iconImage, hoveredImage)));
            setRolloverSelectedIcon(getSelectedIcon());
            setPressedIcon(getSelectedIcon());
            setPreferredSize(new Dimension(32, 32));
            setMaximumSize(new Dimension(32, 32));
            setFocusable(false);
            setFocusPainted(false);
            setBorderPainted(false);
            setMargin(new Insets(0, 0, 0, 0));
            setToolTipText(tool.toString());
            setActionCommand(tool.name());
            addActionListener(actionListener);
        }
       
        /**
         * Merges the two images together by firstly drawing the backgroundImage
         * and then the foregroundImage on top of it.
         *
         * @param foregroundImage The image to draw on top of the background image.
         * @param backgroundImage The image to draw behind the foreground image.
         *
         * @return the merged Image.
         */
        Image mergeImages(Image foregroundImage, Image backgroundImage) {
            BufferedImage image = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB);
            Graphics graphics = image.getGraphics();
            graphics.drawImage(backgroundImage, 0, 0, 32, 32, this);
            graphics.drawImage(foregroundImage, 0, 0, 32, 32, this);
            return image;
        }
    }
   
    /**
     * Model for the ToolButton class. Uses the EditStatus's currently selected tool to determine
     * whether this toggle button is selected or not.
     */
    class ToolButtonModel extends JToggleButton.ToggleButtonModel {
       
        /**
         * The type of tool that the button selects.
         */
        private ToolType tool;
       
        /**
         * The PicEdit application.
         */
        private PicEdit application;
       
        /**
         * Constructor for ToolButtonModel.
         *
         * @param tool The type of tool that the button selects.
         * @param application The PicEdit application.
         */
        ToolButtonModel(ToolType tool, PicEdit application) {
            this.tool = tool;
            this.application = application;
        }
       
        /**
         * Invoked when one of the tool panel buttons is pressed or depressed.
         *
         * @param pressed true if the button was pressed; false if it was depressed.
         */
        public void setPressed(boolean pressed) {
          super.setPressed(pressed);
          if (pressed) {
            // Clear the previous tool as soon as a new one is pressed down.
            application.getEditStatus().setTool(ToolType.NONE);
            ToolPanel.this.repaint();
          }
        }
       
        /**
         * Returns true if the currently selected tool is this tool; otherwise false.
         *
         * @return true if the currently selected tool is this tool; otherwise false.
         */
        public boolean isSelected() {
          return application.getEditStatus().getTool().equals(tool);
        }
       
        /**
         * Indicates if the button can be selected or triggered by an input device, such
         * as a mouse pointer.
         *
         * @return <code>true</code> if the button is enabled
         */
        public boolean isEnabled() {
            boolean enabled = false;
           
            if (application != null) {
                if (tool.equals(ToolType.AIRBRUSH) ||
                    tool.equals(ToolType.BRUSH) ||
                    tool.equals(ToolType.FILL) ||
                    tool.equals(ToolType.LINE) ||
                    tool.equals(ToolType.SHORTLINE) ||
                    tool.equals(ToolType.STEPLINE)) {
                 
                    // Tools are only active when at least one picture frame is displayed,
                    // and the current position is not on a data code. We don't want the
                    // user to use the tools within the middle of an existing action.
                    enabled = application.hasVisiblePictureFrame() && !application.getPicture().getCurrentPictureCode().isDataCode();
                }
            }
         
            return enabled;
        }
    }
   
    /**
     * ToolBar UI that customises the behaviour of the floating toolbar dialog.
     */
    class PicEditToolBarUI extends MetalToolBarUI {
        protected RootPaneContainer createFloatingWindow(JToolBar toolbar) {
            return new PicEditToolBarUIDialog();
        }
       
        class PicEditToolBarUIDialog extends JDialog {
            PicEditToolBarUIDialog() {
                this.getRootPane().putClientProperty("Window.style", "small");
                this.setResizable(false);
                this.setAlwaysOnTop(true);
                WindowListener windowListener = createFrameListener();
                this.addWindowListener(windowListener);
            }
        }
    }
   
    /**
     * The listener that processes tool bar button actions.
     */
    class ToolPanelActionListener implements ActionListener {

        /**
         * The PICEDIT application component.
         */
        protected PicEdit application;
       
        /**
         * Constructor for ToolPanelActionListener.
         *
         * @param application The PicEdit application.
         */
        public ToolPanelActionListener(PicEdit application) {
            this.application = application;
        }

        /**
         * Processes a tool panel button press.
         *
         * @param event The ActionEvent triggered when the tool bar button was pressed.
         */
        public void actionPerformed(ActionEvent event) {
            ToolPanelLocation toolPanelLocation = application.getToolPanelLocation();
            ToolType tool = ToolType.valueOf(event.getActionCommand());
            switch (tool) {
                case BRUSH:
                    // Pop up brush chooser.
                    BrushChooserDialog brushDialog = new BrushChooserDialog((Component)event.getSource(), false, toolPanelLocation);
                    brushDialog.setVisible(true);
                    if (brushDialog.getChosenBrush() != null) {
                        application.getEditStatus().setBrushCode(brushDialog.getChosenBrush().getBrushCode());
                    }
                    break;
                case AIRBRUSH:
                    // Pop up brush chooser.
                    BrushChooserDialog airBrushDialog = new BrushChooserDialog((Component)event.getSource(), true, toolPanelLocation);
                    airBrushDialog.setVisible(true);
                    if (airBrushDialog.getChosenBrush() != null) {
                        application.getEditStatus().setBrushCode(airBrushDialog.getChosenBrush().getBrushCode());
                    }
                    break;
            }
           
            // Process the selected tool.
            application.getEditStatus().setTool(tool);
        }
    }
}
TOP

Related Classes of com.agifans.picedit.gui.toolbar.ToolPanel$ColourButton$ColourButtonModel

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.