Package org.openquark.gems.client

Source Code of org.openquark.gems.client.IntellicutPanel

/*
* Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*     * Redistributions of source code must retain the above copyright notice,
*       this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of Business Objects nor the names of its contributors
*       may be used to endorse or promote products derived from this software
*       without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/


/*
* IntellicutPanelBase.java
* Creation date: (16/04/01 2:03:41 PM)
* By: Michael Cheng
*/
package org.openquark.gems.client;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.text.MessageFormat;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;

import org.openquark.gems.client.IntellicutListModel.FilterLevel;
import org.openquark.gems.client.IntellicutManager.IntellicutMode;
import org.openquark.gems.client.utilities.MouseClickDragAdapter;
import org.openquark.gems.client.utilities.SmoothHighlightBorder;


/**
* A Panel listing the gems that are able to be connected to the intellicut part.
* Confirmation (double-click/enter key press) will drop the selected gem down onto
* the table top, and connected to the intellicut part.
* Cancel (Esc) will close this panel.
* Creation date: (16/04/01 2:03:41 PM)
* @author Michael Cheng
*/
public class IntellicutPanel extends JPanel {

    private static final long serialVersionUID = -8327460694085077388L;

    /** A completely transparent background color. */
    private static final Color TRANSPARENT_COLOR = new Color(0, 0, 0, 0);
   
    /** A slightly tinted background color used for the panel background. */
    private static final Color BACKGROUND_TINT_COLOR = new Color(200, 200, 200, 150);

    /** The icon used by the show all gems button. */
    private static final ImageIcon showAllGemsIcon = new ImageIcon(GemCutter.class.getResource("/Resources/showAllGems.gif"));

    /** The icon used by the show likely gems button */
    private static final ImageIcon showLikelyGemsIcon = new ImageIcon(GemCutter.class.getResource("/Resources/showingGoodGems.gif"));
   
    /** The icon used by the show best gems button */
    private static final ImageIcon showBestGemsIcon = new ImageIcon(GemCutter.class.getResource("/Resources/Gem_Red.gif"));
   
    /** The icon to display next to the title label. */
    private static final ImageIcon intellicutIcon = new ImageIcon(GemCutter.class.getResource("/Resources/intellicut.gif"));

    /** The mouse listener for moving the panel around. */
    private final MovePanelMouseListener movePanelMouseListener = new MovePanelMouseListener();
   
    /** The adapter class that owns this intellicut panel. */
    private final IntellicutPanelOwner adapter;
   
    /** The scrollpane that contains the intellicut list. */
    private JScrollPane listScrollPane = null;
   
    /** The intellicut list instance. */
    private final IntellicutList intellicutList;
   
    /** The button used to pick the "all" level of gem filtering */
    private JToggleButton showAllGemsButton = null;
   
    /** The button used to pick the "likely" level of gem filtering */
    private JToggleButton showLikelyGemsButton = null;
   
    /** The button used to pick the "best" level of gem filtering */
    private JToggleButton showBestGemsButton = null;
   
    /** The toolbar that contains the showGemsButton. */
    private JToolBar showGemsButtonToolBar = null;

    /** The button group that manages exclusion among the filter buttons */
    private ButtonGroup filterButtonGroup;
   
    /** The label that shows the status message text. */
    private JLabel statusLabel = null;

    /** The label that displayed the intellicut title. */
    private JLabel titleLabel = null;
   
    /** The top panel that contains the buttons and status label. */
    private JPanel topPanel = null;

    /** The input the user has typed. This is used to refresh the intellicut list. */
    private String userInput = null;

    /** The color that the type color manager recommends for the part we are trying to connect. */
    private Color typeColor = null;

    /** The original background color that was saved when we entered drag mode. */
    private Color savedBackgroundColor = null;
   
    /** Whether the panel is currently being dragged around by the user. */
    private boolean isDragging = false;
   
    /** Whether the current filtering setting should be saved on close */
    private boolean saveFilterPreference = true;
   
    /** Whether the filter buttons are clickable */
    private boolean filtersEnabled = true;
   
    /**
     * The listener that updates the IntellicutList as the user types.
     * It does so by keeping track of the String the user has typed in so far and
     * and it shrinks the visible list of matching gems accordingly.
     * Also closes the list if the user hits ESC or ENTER.
     */
    private class IntellicutKeyListener extends KeyAdapter {

        @Override
        public void keyPressed(KeyEvent e) {
           
            int keyCode = e.getKeyCode();
            int selectedIndex = intellicutList.getSelectedIndex();
            IntellicutListModel listModel = (IntellicutListModel) intellicutList.getModel();
           
            // Toggles between showing all or best gems
            if (keyCode == KeyEvent.VK_T && e.isAltDown()) {
               
                if (getShowAllGemsButton().isSelected()) {
                    getShowLikelyGemsButton().doClick();
                } else if (getShowLikelyGemsButton().isSelected()) {
                    getShowBestGemsButton().doClick();
                } else {
                    getShowAllGemsButton().doClick();
                }
               
                selectedIndex = intellicutList.getSelectedIndex();
               
            // Moves the selection upwards and downwards
            } else if (keyCode == KeyEvent.VK_UP) {
                selectedIndex--;

            } else if (keyCode == KeyEvent.VK_DOWN) {
                selectedIndex++;

            } else if (keyCode == KeyEvent.VK_PAGE_UP) {
                selectedIndex -= Math.min(getNumVisibleRows() - 1, selectedIndex);

            } else if (keyCode == KeyEvent.VK_PAGE_DOWN) {
                int nextRow = intellicutList.getModel().getSize() - selectedIndex - 1;
                selectedIndex += Math.min(getNumVisibleRows() - 1, nextRow);
              
            } else if (keyCode == KeyEvent.VK_HOME) {
                selectedIndex = 0;
               
            } else if (keyCode == KeyEvent.VK_END) {
                selectedIndex = intellicutList.getModel().getSize() - 1;              

            // Commits or cancels the intellicut selection
            } else if (keyCode == KeyEvent.VK_ENTER) {
                adapter.connectSelectedGem();
               
            } else if (keyCode == KeyEvent.VK_ESCAPE) {
                adapter.stopIntellicutPanel();
               
            // Deletes the last character
            } else if (keyCode == KeyEvent.VK_BACK_SPACE) {
               
                // First delete previous character
                if (userInput.length() > 0) {
                    userInput = userInput.substring(0, userInput.length() - 1);
                    intellicutList.refreshList(userInput);
                    selectedIndex = intellicutList.getSelectedIndex();
                }
               
                // Now check if we need to re-enable the filter buttons
                if (userInput.length() == 0) {
                    setFiltersEnabled(true);
                }
               
            } else if (keyCode == KeyEvent.VK_CONTROL   || keyCode == KeyEvent.VK_ALT ||
                       keyCode == KeyEvent.VK_SHIFT     || keyCode == KeyEvent.VK_META ||
                       keyCode == KeyEvent.VK_CAPS_LOCK || e.isActionKey() || e.getKeyChar() == ' ') {
               
                // Do nothing.

            } else {

                // Adds the newly typed character to the string if necessary
               
                String newUserInput = userInput + e.getKeyChar();
                setFiltersEnabled(false);
               
                if (listModel.hasAnyGemsFor(newUserInput)) {
                    userInput = newUserInput;
                    intellicutList.refreshList(userInput);
                    selectedIndex = intellicutList.getSelectedIndex();
                } else {
                    Toolkit.getDefaultToolkit().beep();
                    if (userInput.length() == 0) {
                        setFiltersEnabled(true);
                    }
                }
               
            }
           
            // Select the correct item and make it visible
            if (selectedIndex >= 0 && selectedIndex < intellicutList.getModel().getSize()) {
                intellicutList.setSelectedIndex(selectedIndex);
                intellicutList.ensureIndexIsVisible(selectedIndex);
                updateStatusLabel();
               
                // Hide the currently displayed tooltip if we move the list selection.
                // Easiest way to do this is to temporarily disable the tooltip manager.
                ToolTipManager.sharedInstance().setEnabled(false);
                ToolTipManager.sharedInstance().setEnabled(true);
            }
           
            e.consume();
        }
    }

    /**
     * Mouse listener that listens for double left clicks to close the list and right
     * clicks to display the list popup menu.
     */
    private class DoubleClickMouseListener extends MouseClickDragAdapter {

        @Override
        public boolean mouseReallyClicked(MouseEvent e){
   
            // double left-click?
            boolean doubleClicked = super.mouseReallyClicked(e);
           
            // If it is the popup trigger, show the popup.
            if (e.isPopupTrigger()) {
                JList matchingGemsList = getIntellicutList();
                int index = matchingGemsList.locationToIndex(e.getPoint());
                if (index >= 0) {
                    matchingGemsList.setSelectedIndex(index);
                    JPopupMenu popupMenu = adapter.getIntellicutPopupMenu();
                    if (popupMenu != null) {
                        popupMenu.show(e.getComponent(), e.getX(), e.getY());
                    }
                }
            }
   
            if (doubleClicked && SwingUtilities.isLeftMouseButton(e)) {
                adapter.connectSelectedGem();      
            }
           
            return doubleClicked;
        }
    }
   
    /**
     * This listener class is responsible for moving the intellicut panel if the user clicks
     * on it and moves the mouse.
     * @author Frank Worsley
     */
    private class MovePanelMouseListener extends MouseAdapter implements MouseMotionListener {
       
        /** The point at which the mouse was first pressed and in whose relation we are dragging. */
        private Point dragPoint = null;
       
        public void mouseDragged(MouseEvent e) {
           
            if (dragPoint == null) {
                // This shouldn't happen.
                return;
            }

            int newX = IntellicutPanel.this.getX() + e.getX() - dragPoint.x;
            int newY = IntellicutPanel.this.getY() + e.getY() - dragPoint.y;

            setDragMode(true);           
            setLocation(newX, newY);
        }

        @Override
        public void mousePressed(MouseEvent e) {
            dragPoint = e.getPoint();
        }
       
        @Override
        public void mouseReleased(MouseEvent e) {
            if (isDragging) {
                setDragMode(false);
                intellicutList.requestFocusInWindow();
            }
        }

        public void mouseMoved(MouseEvent e) {
        }
    }

    /**
     * IntellicutPanel constructor.
     */
    public IntellicutPanel(IntellicutPanelOwner adapter,
                           IntellicutListModelAdapter modelAdapter,
                           Color typeColor, IntellicutMode mode) {

        this.adapter = adapter;
        this.typeColor = typeColor;
        this.userInput = "";
       
        IntellicutListModel listModel = new IntellicutListModel(modelAdapter);

        intellicutList = new IntellicutList(mode);
        intellicutList.setModel(listModel);
        intellicutList.setCursor(Cursor.getDefaultCursor());

        setLayout(new BorderLayout());
        setBorder(BorderFactory.createEtchedBorder());
        setMoveable(true);
       
        if (typeColor != null) {
            setBackground(typeColor);
        }

        listScrollPane = new JScrollPane();
        listScrollPane.setViewportView(getIntellicutList());
        listScrollPane.getHorizontalScrollBar().setCursor(Cursor.getDefaultCursor());
        listScrollPane.getVerticalScrollBar().setCursor(Cursor.getDefaultCursor());

        add(listScrollPane, BorderLayout.CENTER);

        // Remove the default list key listeners. These are added by Swing to enable list
        // navigation, but they screw up our own intellicut searching and navigation.
        KeyListener[] keyListeners = getIntellicutList().getKeyListeners();
        for (final KeyListener listenerToRemove : keyListeners) {
            intellicutList.removeKeyListener(listenerToRemove);
        }
       
        // Make sure double clicks are handled by the list.
        intellicutList.addMouseListener(new DoubleClickMouseListener());
               
        // The key listener that updates the list as the user types.
        KeyListener keyListener = new IntellicutKeyListener();
        addKeyListener(keyListener);
        intellicutList.addKeyListener(keyListener);
    }
   
    /**
     * Whether or not the user should be able to move the panel around by dragging the title bar area.
     * @param moveable true if panel should be movable, false otherwise
     */
    public void setMoveable(boolean moveable) {

        if (moveable) {
            addMouseListener(movePanelMouseListener);
            addMouseMotionListener(movePanelMouseListener);
        } else {
            removeMouseListener(movePanelMouseListener);
            removeMouseMotionListener(movePanelMouseListener);
        }
    }
       
    /**
     * Removes the panel from its parent's display.
     */
    public void close() {  
       
        if (saveFilterPreference) {
            GemCutter.getPreferences().put(IntellicutManager.INTELLICUT_GEM_FILTER_LEVEL_PREF_KEY,
                                              getIntellicutListModel().getFilterLevel().toString());
        }
       
        // Remove ourselves from our parent and repaint it.
        Container parent = getParent();
        if (parent != null) {
           
            parent.remove(this);
           
            if (parent instanceof JPopupMenu) {
                JPopupMenu popupMenu = (JPopupMenu) parent;
                popupMenu.setVisible(false);
            }
           
            if (parent instanceof JComponent) {
                ((JComponent) parent).repaint(getBounds());
            } else {
                parent.validate();
            }  
        }
    }
   
    /**
     * @return the IntellicutList for this panel.
     */
    public IntellicutList getIntellicutList() {
        return intellicutList;
    }
   
    /**
     * This method modifies the preferred size of the list's scroll pane to show the desired
     * number of rows. This method only works if the list model has at least one item in it. If
     * called with when the list model is empty, then nothing is done.
     * @param numRows the number of rows that should be visible
     */
    public void setPreferredVisibleRows(int numRows) {
    
        if (getIntellicutListModel().isEmpty()) {
            return;
        }
       
        Dimension prefSize = listScrollPane.getPreferredSize();
        int cellHeight = getIntellicutList().getCellBounds(0, 0).height;
        int borders = listScrollPane.getInsets().top + listScrollPane.getInsets().bottom;
        listScrollPane.setPreferredSize(new Dimension(prefSize.width, numRows * cellHeight + borders));
    }
   
    /**
     * @return the number of rows currently visible in the Intellicut list.
     */
    private int getNumVisibleRows() {
       
        if (getIntellicutListModel().isEmpty()) {
            return 0;
        }
       
        int rowHeight = intellicutList.getCellBounds(0, 0).height;
        int listHeight = listScrollPane.getSize().height;
       
        return listHeight / rowHeight;
    }
   
    /**
     * @return the list model used by the intellicut list.
     */
    public IntellicutListModel getIntellicutListModel() {
        return (IntellicutListModel) getIntellicutList().getModel();
    }
   
    /**
     * Sets the title of the intellicut panel.
     * @param newTitle the new title for the list
     */
    public void setTitle(String newTitle) {
        getTitleLabel().setText(newTitle);
    }
   
    /**
     * Initially loads the list model. This should be called after users of the panel
     * have added any additional gems they want to be loaded.  This is a separate call
     * to make loading gems and displaying the list more efficient.
     */
    public void loadListModel() {
       
        IntellicutListModel listModel = getIntellicutListModel();
       
        listModel.load();

        FilterLevel filterLevel = FilterLevel.fromString(GemCutter.getPreferences().get(IntellicutManager.INTELLICUT_GEM_FILTER_LEVEL_PREF_KEY, IntellicutManager.INTELLICUT_GEM_FILTER_LEVEL_DEFAULT.toString()));
        boolean hasBestGems = listModel.hasFilteredGemsFor("", filterLevel);
        if (!hasBestGems) {
            filterLevel = FilterLevel.SHOW_ALL;
        }
       
        // Processing to eliminate redundant buttons (ie, those that add no filtering)
        int numEntries = listModel.numFilteredGems(FilterLevel.SHOW_ALL);
        int numLikelyEntries = listModel.numFilteredGems(FilterLevel.SHOW_LIKELY);
        int numBestEntries = listModel.numFilteredGems(FilterLevel.SHOW_BEST);

        if ((numEntries - numLikelyEntries) < 20 || (numLikelyEntries - numBestEntries) < 20) {
            getShowGemsButtonToolBar().remove(getShowLikelyGemsButton());
            if (filterLevel == FilterLevel.SHOW_LIKELY) {
                filterLevel = FilterLevel.SHOW_BEST;
                saveFilterPreference = false; // Don't save automatically adjusted filter settings
            }
        }
       
        if ((numEntries - numBestEntries) < 20 || numBestEntries == 0) {
            getShowGemsButtonToolBar().remove(getShowBestGemsButton());
            if (filterLevel == FilterLevel.SHOW_BEST) {
                filterLevel = FilterLevel.SHOW_ALL;
                saveFilterPreference = false; // Don't save automatically adjusted filter settings
            }
        }
       
        listModel.setFilterLevel(filterLevel);
        listModel.refreshList("");

        // If there are no matching gems, display an error message and return.
        if (listModel.isEmpty()) {
            JLabel message = new JLabel(adapter.getMessages().getString("ICL_NoGemsFound"));
            message.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
            message.setIcon(intellicutIcon);
           
            remove(listScrollPane);
            add(message, BorderLayout.CENTER);
           
            return;
        }

        // Add the top panel only now so that the status message and button state
        // are synced up with the show all gems state of the model.
        add(getTopPanel(), BorderLayout.NORTH);
       
        if (listModel.getFilterLevel() == FilterLevel.SHOW_ALL) {
            getShowAllGemsButton().getModel().setSelected(true);
        } else if(listModel.getFilterLevel() == FilterLevel.SHOW_LIKELY) {
            getShowLikelyGemsButton().getModel().setSelected(true);
        } else if(listModel.getFilterLevel() == FilterLevel.SHOW_BEST) {
            getShowBestGemsButton().getModel().setSelected(true);
        }
       
        getIntellicutList().setSelectedIndex(0);

        setPreferredVisibleRows(20);
    }
   
    /**
     * Enables transparency for the intellicut panel and components within it.
     * If you enable transparency the panel and list will be coloured in a light tint,
     * allowing you to see the components below it. Once transparency is enabled you
     * can't disabled it anymore. You have to recreate the panel if you don't want
     * transparency anymore.
     */
    public void makeTransparent() {

        // Components can not be opaque or transparency will not work. We have to
        // manually draw in the background since Java screws it up for some reason.

        setOpaque(false);
        setBackground(BACKGROUND_TINT_COLOR);

        setBorder(new SmoothHighlightBorder(typeColor != null ? typeColor : getBackground(), false));
       
        getIntellicutList().setBackground(TRANSPARENT_COLOR);
        getIntellicutList().setOpaque(false);
        getIntellicutList().setTransparent(true);
       
        listScrollPane.setBackground(TRANSPARENT_COLOR);
        listScrollPane.setOpaque(false);
       
        listScrollPane.getViewport().setBackground(TRANSPARENT_COLOR);
        listScrollPane.getViewport().setOpaque(false);
       
        getTopPanel().setBackground(TRANSPARENT_COLOR);
        getTopPanel().setOpaque(false);
       
        getStatusLabel().setBackground(TRANSPARENT_COLOR);
        getStatusLabel().setOpaque(false);
       
        getShowAllGemsButton().setBackground(TRANSPARENT_COLOR);
        getShowAllGemsButton().setOpaque(false);

        getShowLikelyGemsButton().setBackground(TRANSPARENT_COLOR);
        getShowLikelyGemsButton().setOpaque(false);

        getShowBestGemsButton().setBackground(TRANSPARENT_COLOR);
        getShowBestGemsButton().setOpaque(false);

        getShowGemsButtonToolBar().setBackground(TRANSPARENT_COLOR);
        getShowGemsButtonToolBar().setOpaque(false);

        // Here we have to again remove the list's default key listeners that are added
        // by Swing. These listeners are re-added when the list updates its UI when the
        // transparency is enabled. The listeners need to be removed since they screw up
        // our own key navigation and intellicut searching.
        KeyListener[] keyListeners = getIntellicutList().getKeyListeners();
        for (final KeyListener listenerToRemove : keyListeners) {
            getIntellicutList().removeKeyListener(listenerToRemove);
        }
       
        // Add back our own listener
        getIntellicutList().addKeyListener(new IntellicutKeyListener());       
    }
   
    /**
     * Makes the entire panel except for its border invisible. This is used to draw the outline
     * of the panel while it is being moved around the screen.
     * @param dragMode true to make everything invisible but the border, false otherwise
     */
    private void setDragMode(boolean dragMode) {
       
        if (dragMode == isDragging) {
            return;
        }
       
        isDragging = dragMode;
       
        if (dragMode) {
            savedBackgroundColor = getBackground();
            setBackground(TRANSPARENT_COLOR);
            setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
            listScrollPane.setVisible(false);
            getTopPanel().setVisible(false);
           
        } else {
           
            setBackground(savedBackgroundColor);

            if (intellicutList.isTransparent()) {
                setBorder(new SmoothHighlightBorder(typeColor != null ? typeColor : getBackground(), false));
            } else {
                setBorder(BorderFactory.createEtchedBorder());
            }

            getTopPanel().setVisible(true);
            listScrollPane.setVisible(true);
        }
    }
   
    /**
     * We draw in our background manually. This is necessary since Java screws up the background
     * drawing if the panel is transparent.
     */
    @Override
    public void paintComponent(Graphics g) {
        Insets insets = getInsets();
        g.setColor(getBackground());
        g.fillRect(insets.left, insets.top, getWidth() - insets.left - insets.right, getHeight() - insets.top - insets.bottom);
    }
   
    /**
     * Returns the panel at the top of the intellicut list that contains the switch buttons
     * and title labels.
     * @return JPanel
     */
    private JPanel getTopPanel() {
       
        if (topPanel == null) {

            topPanel = new JPanel();
            topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.X_AXIS));
   
            topPanel.add(getTitleLabel());
            topPanel.add(Box.createHorizontalGlue());
            topPanel.add(getStatusLabel());
            topPanel.add(Box.createHorizontalStrut(5));
            topPanel.add(getShowGemsButtonToolBar());
           
            // we don't want a visible border for the top panel, just use this to create margins
            topPanel.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5));

            // set the size to be large enough to display long status messages
            Dimension prefSize = getTopPanel().getPreferredSize();
            topPanel.setPreferredSize(new Dimension(prefSize.width + 25, prefSize.height));
           
            topPanel.setCursor(Cursor.getDefaultCursor());
        }
       
        return topPanel;       
    }
   
    /**
     * Returns the title label for the title of the intellicut list.
     * @return JLabel
     */
    private JLabel getTitleLabel() {
       
        if (titleLabel == null) {
            titleLabel = new JLabel(adapter.getMessages().getString("ICL_IntellicutTitle"));
           
            titleLabel.setIcon(intellicutIcon);
           
            Font labelFont = getFont().deriveFont(Font.BOLD, getFont().getSize() + 4);
            titleLabel.setFont(labelFont);
           
            titleLabel.setCursor(Cursor.getDefaultCursor());
        }

        return titleLabel;
    }
   
    /**
     * Returns the status label for the status of the intellicut list.
     * @return JLabel
     */
    private JLabel getStatusLabel() {
       
        if (statusLabel == null) {
            statusLabel = new JLabel();
            statusLabel.setCursor(Cursor.getDefaultCursor());
            updateStatusLabel();
        }
       
        return statusLabel;
    }
    private static class TransparentToggleButton extends JToggleButton {
        private static final long serialVersionUID = -7591214478387598044L;

        /**
         * This overrides paintComponent to make transparency work correctly.
         * We have to draw in our own background, otherwise Java will screw it up.
         * @param g the Graphics object to draw with
         */
        @Override
        public void paintComponent(Graphics g) {
           
            g.setColor(getBackground());
            g.fillRect(0, 0, getWidth(), getHeight());

            super.paintComponent(g);
        }
    }

    /** @return JToggleButton the button for the show all gems level of filtering */
    private JToggleButton getShowAllGemsButton() {
        if (showAllGemsButton == null) {
            showAllGemsButton = new TransparentToggleButton();

            showAllGemsButton.setAction(getGemFilterButtonAction(showAllGemsButton, showAllGemsIcon, "ICL_ShowAllGemsToolTip", FilterLevel.SHOW_ALL));           
            showAllGemsButton.setText(null);
            showAllGemsButton.setMargin(new Insets(0, 0, 0, 0));
            showAllGemsButton.setCursor(Cursor.getDefaultCursor());
        }
       
        return showAllGemsButton;
    }

    /** @return JToggleButton the button for the show likely gems level of filtering */
    private JToggleButton getShowLikelyGemsButton() {
        if (showLikelyGemsButton == null) {
            showLikelyGemsButton = new TransparentToggleButton();

            showLikelyGemsButton.setAction(getGemFilterButtonAction(showLikelyGemsButton, showLikelyGemsIcon, "ICL_ShowLikelyGemsToolTip", FilterLevel.SHOW_LIKELY));           
            showLikelyGemsButton.setText(null);
            showLikelyGemsButton.setMargin(new Insets(0, 0, 0, 0));
            showLikelyGemsButton.setCursor(Cursor.getDefaultCursor());
        }
       
        return showLikelyGemsButton;
    }

    /** @return JToggleButton the button for the show best gems level of filtering */
    private JToggleButton getShowBestGemsButton() {
        if (showBestGemsButton == null) {
            showBestGemsButton = new TransparentToggleButton();

            showBestGemsButton.setAction(getGemFilterButtonAction(showBestGemsButton, showBestGemsIcon, "ICL_ShowBestGemsToolTip", FilterLevel.SHOW_BEST));           
            showBestGemsButton.setText(null);
            showBestGemsButton.setMargin(new Insets(0, 0, 0, 0));
            showBestGemsButton.setCursor(Cursor.getDefaultCursor());
        }
       
        return showBestGemsButton;
    }

    /**
     * We cheat and place the show gems button inside a toolbar.
     * Toolbars can automatically give buttons the nice mouse-rollover effect,
     * without us having to install custom mouse listeners to do it.
     * @return the toolbar the show gems button is placed in.
     */
    private JToolBar getShowGemsButtonToolBar() {
       
        if (showGemsButtonToolBar == null) {
       
            showGemsButtonToolBar = new JToolBar() {
                   
                private static final long serialVersionUID = -4840586584969771381L;

                /**
                 * This overrides paintComponent to make transparency work correctly.
                 * We have to draw in our own background, otherwise Java will screw it up.
                 * @param g the Graphics object to draw with
                 */
                @Override
                public void paintComponent(Graphics g) {
                       
                    g.setColor(getBackground());
                    g.fillRect(0, 0, getWidth(), getHeight());
   
                    super.paintComponent(g);
                }
            };
               
            showGemsButtonToolBar.setOpaque(true);
            showGemsButtonToolBar.setRollover(true);
            showGemsButtonToolBar.setFloatable(false);
            showGemsButtonToolBar.setCursor(Cursor.getDefaultCursor());
            showGemsButtonToolBar.add(getShowBestGemsButton());
            showGemsButtonToolBar.add(getShowLikelyGemsButton());
            showGemsButtonToolBar.add(getShowAllGemsButton());
       
            getFilterButtonGroup();
        }
       
        return showGemsButtonToolBar;       
    }
   
    private ButtonGroup getFilterButtonGroup() {
        if (filterButtonGroup == null) {
           
            filterButtonGroup = new ButtonGroup();
           
            filterButtonGroup.add(getShowAllGemsButton());
            filterButtonGroup.add(getShowLikelyGemsButton());
            filterButtonGroup.add(getShowBestGemsButton());
        }
       
        return filterButtonGroup;
    }
   
    /**
     * Returns an action for the three filter-level buttons
     * @param button The button that this action is for
     * @param icon Icon to display on the button
     * @param toolTipId String id of the tooltip for this button
     * @param filterLevel Filter level that this button sets
     * @return Action
     */
    private Action getGemFilterButtonAction(JToggleButton button, ImageIcon icon, String toolTipId, final FilterLevel filterLevel) {
       
        Action filterButtonAction = new AbstractAction("filterButtonAction", icon) {
           
            private static final long serialVersionUID = -196510266687548115L;

            public void actionPerformed(ActionEvent evt) {
               
                getIntellicutList().setFilterLevel(filterLevel);
                getIntellicutList().requestFocus();
                updateStatusLabel();
                saveFilterPreference = true;
            }
        };
       
        filterButtonAction.putValue(Action.MNEMONIC_KEY, Integer.valueOf(KeyEvent.VK_T));
        filterButtonAction.putValue(Action.SHORT_DESCRIPTION, adapter.getMessages().getString(toolTipId));
   
        return filterButtonAction;
    }
   
    /**
     * Updates the status label of the list to show the correct information.
     */
    private void updateStatusLabel() {
       
        FilterLevel filterLevel = getIntellicutListModel().getFilterLevel();
        int numGems = getIntellicutListModel().getSize();
       
        String message = null;
        String messageId = (filtersEnabled == false)                    ? (numGems > 1 ? "ICL_ShowingMatchingGems" : "ICL_ShowingOneMatchingGem") :
                           (filterLevel == FilterLevel.SHOW_ALL)        ? (numGems > 1 ? "ICL_ShowingAllGems" : "ICL_ShowingAllOneGem") :
                           (filterLevel == FilterLevel.SHOW_LIKELY)     ? (numGems > 1 ? "ICL_ShowingLikelyGems" : "ICL_ShowingLikelyOneGem") :
                                        /* FilterLevel.SHOW_BEST */       (numGems > 1 ? "ICL_ShowingBestGems" : "ICL_ShowingBestOneGem");
       
        if (numGems > 1) {
            Object[] arguments = { Integer.valueOf(numGems) };
            message = MessageFormat.format(adapter.getMessages().getString(messageId), arguments);
        } else {
            message = adapter.getMessages().getString(messageId);
        }
       
        getStatusLabel().setText(message);
    }

    private void setFiltersEnabled(boolean enableFilters) {
       
        filtersEnabled = enableFilters;

        if (enableFilters) {
            getShowAllGemsButton().setVisible(true);
            getShowLikelyGemsButton().setVisible(true);
            getShowBestGemsButton().setVisible(true);
        } else {
            getShowAllGemsButton().setVisible(false);
            getShowLikelyGemsButton().setVisible(false);
            getShowBestGemsButton().setVisible(false);
        }

        updateStatusLabel();
    }
}
TOP

Related Classes of org.openquark.gems.client.IntellicutPanel

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.