All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jidesoft.swing.JideSplitPaneDivider Maven / Gradle / Ivy

/*
 * @(#)JideSplitPaneDivider.java
 *
 * Copyright 2002 JIDE Software Inc. All rights reserved.
 */

package com.jidesoft.swing;


import com.jidesoft.plaf.UIDefaultsLookup;
import com.jidesoft.plaf.basic.Painter;
import com.jidesoft.utils.PortingUtils;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.MouseInputAdapter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;


/**
 * Divider used by JideSplitPane.
 */
public class JideSplitPaneDivider extends JPanel
        implements PropertyChangeListener {
    /**
     * Handles mouse dragging message to do the actual dragging.
     */
    protected DragController _dragger;

    /**
     * Size of the divider.
     */
    protected int _dividerSize = UIDefaultsLookup.getInt("JideSplitPane.dividerSize"); // default - SET TO 0???

    /**
     * JideSplitPane the receiver is contained in.
     */
    protected JideSplitPane _jideSplitPane;

    /**
     * Handles mouse events from both this class, and the split pane. Mouse events are handled for the JideSplitPane
     * since you want to be able to drag when clicking on the border of the divider, which is not drawn by the divider.
     */
    protected MouseHandler _mouseHandler;

    /**
     * Orientation of the JideSplitPane.
     */
    protected int _orientation;

    /**
     * Cursor used for HORIZONTAL_SPLIT split panes.
     */
    static final Cursor HORIZONTAL_CURSOR =
            JideCursors.getPredefinedCursor(JideCursors.HSPLIT_CURSOR);

    /**
     * Cursor used for VERTICAL_SPLIT split panes.
     */
    static final Cursor VERTICAL_CURSOR =
            JideCursors.getPredefinedCursor(JideCursors.VSPLIT_CURSOR);

    /**
     * Default cursor.
     */
    static final Cursor DEFAULT_CURSOR = Cursor.getDefaultCursor();

    private Painter _gripperPainter;

    /**
     * Creates an instance of BasicJideSplitPaneDivider. Registers this instance for mouse events and mouse dragged
     * events.
     *
     * @param splitPane the JideSplitPane.
     */
    public JideSplitPaneDivider(JideSplitPane splitPane) {
        setJideSplitPane(splitPane);
        _orientation = _jideSplitPane.getOrientation();

        // get divider size from JideSplitPane
        setDividerSize(splitPane.getDividerSize());
        setDefaultResizeCursor();

        setBackground(UIDefaultsLookup.getColor("JideSplitPaneDivider.background"));
        setBorder(UIDefaultsLookup.getBorder("JideSplitPaneDivider.border"));
        if (_jideSplitPane.isOneTouchExpandable()) {
            oneTouchExpandableChanged();
        }
        _gripperPainter = (Painter) UIDefaultsLookup.get("JideSplitPaneDivider.gripperPainter");
        setOpaque(false);
        setLayout(null);
    }

    public void setDefaultResizeCursor() {
        setCursor((_orientation == JideSplitPane.HORIZONTAL_SPLIT) ?
                HORIZONTAL_CURSOR : VERTICAL_CURSOR);
    }

    /**
     * Gets the JideSplitPane.
     *
     * @return the JideSplitPane
     */
    public JideSplitPane getJideSplitPane() {
        return _jideSplitPane;
    }

    /**
     * Sets the JideSplitPane that is using this divider.
     *
     * @param splitPane the JideSplitPane.
     */
    public void setJideSplitPane(JideSplitPane splitPane) {
        uninstallListeners();
        _jideSplitPane = splitPane;
        installListeners();
    }

    private void installListeners() {
        if (_jideSplitPane != null) {
            if (_mouseHandler == null) {
                _mouseHandler = createMouseHandler();
            }
            _jideSplitPane.addMouseListener(_mouseHandler);
            _jideSplitPane.addMouseMotionListener(_mouseHandler);
            addMouseListener(_mouseHandler);
            addMouseMotionListener(_mouseHandler);
            _jideSplitPane.addPropertyChangeListener(this);
        }
    }

    private void uninstallListeners() {
        if (_jideSplitPane != null) {
            _jideSplitPane.removePropertyChangeListener(this);
            if (_mouseHandler != null) {
                _jideSplitPane.removeMouseListener(_mouseHandler);
                _jideSplitPane.removeMouseMotionListener(_mouseHandler);
                removeMouseListener(_mouseHandler);
                removeMouseMotionListener(_mouseHandler);
                _mouseHandler = null;
            }
        }
    }

    protected MouseHandler createMouseHandler() {
        return new MouseHandler();
    }

    /**
     * Sets the size of the divider to newSize. That is the width if the split pane is
     * HORIZONTAL_SPLIT, or the height of VERTICAL_SPLIT.
     *
     * @param newSize the new divider size.
     */
    public void setDividerSize(int newSize) {
        _dividerSize = newSize;
    }


    /**
     * Returns the size of the divider, that is the width if the split pane is HORIZONTAL_SPLIT, or the height of
     * VERTICAL_SPLIT.
     *
     * @return the divider size.
     */
    public int getDividerSize() {
        return _dividerSize;
    }

    /**
     * Returns dividerSize x dividerSize
     */
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(getDividerSize(), getDividerSize());
    }

    /**
     * Returns dividerSize x dividerSize
     */
    @Override
    public Dimension getMinimumSize() {
        return getPreferredSize();
    }


    /**
     * Property change event, presumably from the JideSplitPane, will message updateOrientation if necessary.
     */
    public void propertyChange(PropertyChangeEvent e) {
        if (e.getSource() == _jideSplitPane) {
            if (JideSplitPane.ORIENTATION_PROPERTY.equals(e.getPropertyName())) {
                _orientation = _jideSplitPane.getOrientation();
                setCursor((_orientation == JideSplitPane.HORIZONTAL_SPLIT) ?
                        HORIZONTAL_CURSOR : VERTICAL_CURSOR);
                invalidate();
                validate();
            }
            else if (JideSplitPane.ONE_TOUCH_EXPANDABLE_PROPERTY.equals(e.getPropertyName())) {
                setDividerSize(_jideSplitPane.getDividerSize());
                oneTouchExpandableChanged();
            }
            else if (JideSplitPane.DIVIDER_SIZE_PROPERTY.equals(e.getPropertyName())) {
                setDividerSize(_jideSplitPane.getDividerSize());
            }
            else if (JideSplitPane.GRIPPER_PROPERTY.equals(e.getPropertyName())) {
                repaint();
            }
        }
    }


    /**
     * Resets the UI property to a value from the current look and feel. JComponent subclasses must
     * override this method like this:
     * 
     *   public void updateUI() {
     *      setUI((SliderUI)UIManager.getUI(this);
     *   }
     *  
* * @see #setUI * @see UIManager#getLookAndFeel * @see UIManager#getUI */ @Override public void updateUI() { super.updateUI(); setBackground(UIDefaultsLookup.getColor("JideSplitPaneDivider.background")); setBorder(UIDefaultsLookup.getBorder("JideSplitPaneDivider.border")); _gripperPainter = (Painter) UIDefaultsLookup.get("JideSplitPaneDivider.gripperPainter"); } /** * Paints the divider. */ @Override public void paintComponent(Graphics g) { super.paintComponent(g); // Paint the border. Border border = getBorder(); Dimension size = getSize(); if (isOpaque()) { g.setColor(getBackground()); g.fillRect(0, 0, size.width, size.height); } if (border != null) { border.paintBorder(this, g, 0, 0, size.width, size.height); } if (_jideSplitPane.isShowGripper()) { Rectangle rect = new Rectangle(size); if (_gripperPainter != null) { if (rect.width > rect.height) { // rect.x = rect.x + rect.width / 2 - 10; // rect.width = 22; _gripperPainter.paint(this, g, rect, SwingConstants.VERTICAL, 0); } else { // rect.y = rect.y + rect.height / 2 - 10; // rect.height = 22; _gripperPainter.paint(this, g, rect, SwingConstants.HORIZONTAL, 0); } } else { rect.x++; rect.y++; JideSwingUtilities.drawGrip(g, rect, 9, UIDefaultsLookup.getInt("JideSplitPane.dividerSize") / 3); } } } /** * Message to prepare for dragging. This messages the BasicJideSplitPaneUI with startDragging. */ protected void prepareForDragging() { _jideSplitPane.startDragging(this); } protected void dragDividerTo(int location) { _jideSplitPane.dragDividerTo(this, location); /* * Update the variables used by the one-touch expand/collapse buttons. */ _currentState = DEFAULT_STATE; int indexOfDivider = _jideSplitPane.indexOfDivider(JideSplitPaneDivider.this); _lastPosition = _jideSplitPane.getDividerLocation(indexOfDivider); } protected void finishDraggingTo(int location) { _jideSplitPane.finishDraggingTo(this, location); } protected int getPreviousDividerLocation(boolean ignoreVisibility, boolean reversed) { return _jideSplitPane.getPreviousDividerLocation(this, ignoreVisibility, reversed); } protected int getNextDividerLocation(boolean ignoreVisibility, boolean reversed) { return _jideSplitPane.getNextDividerLocation(this, ignoreVisibility, reversed); } /** * Gets the first component. This divider is installed between two components. The first component is usually the * one on the left or on the top. * * @param ignoreVisibility true to not check if the component is visible. * @return the first component */ public Component getFirstComponent(boolean ignoreVisibility) { int index = _jideSplitPane.indexOf(this); if (index - 1 >= 0) { for (int i = (index - 1); i >= 0; i--) { if (ignoreVisibility || _jideSplitPane.getComponent(i).isVisible()) { return _jideSplitPane.getComponent(i); } } // return an invisible component in lieu of null return _jideSplitPane.getComponent(index - 1); } else { throw new IndexOutOfBoundsException("There is no component before divider " + index); } } /** * Gets the second component. This divider is installed between two components. The second component is usually the * one on the right or on the bottom. * * @param ignoreVisibility true to not check if the component is visible. * @return the first component */ public Component getSecondComponent(boolean ignoreVisibility) { int index = _jideSplitPane.indexOf(this); if (index + 1 < _jideSplitPane.getComponentCount()) { for (int i = (index + 1); i >= 0; i++) { if (ignoreVisibility || _jideSplitPane.getComponent(i).isVisible()) { return _jideSplitPane.getComponent(i); } } // return an invisible component in lieu of null return _jideSplitPane.getComponent(index + 1); } else { throw new IndexOutOfBoundsException("There is no component before divider " + index); } } /** * MouseHandler is responsible for converting mouse events (released, dragged...) into the appropriate * DragController methods. *

*/ protected class MouseHandler extends MouseInputAdapter { /** * Starts the dragging session by creating the appropriate instance of DragController. */ @Override public void mousePressed(MouseEvent e) { if ((e.getSource() == JideSplitPaneDivider.this/*|| e.getSource() == _jideSplitPane*/) && _dragger == null && _jideSplitPane.isEnabled() && _jideSplitPane.isDragResizable()) { if (getFirstComponent(true) != null && getSecondComponent(true) != null) { if (_orientation == JideSplitPane.HORIZONTAL_SPLIT) { _dragger = new DragController(e); } else { _dragger = new VerticalDragController(e); } if (!_dragger.isValid()) { _dragger = null; } else { prepareForDragging(); _dragger.continueDrag(e); } } e.consume(); } } /** * If dragger is not null it is messaged with completeDrag. */ @Override public void mouseReleased(MouseEvent e) { if (_dragger != null) { if (e.getSource() == _jideSplitPane) { _dragger.completeDrag(e.getX(), e.getY()); } else if (e.getSource() == JideSplitPaneDivider.this) { Point ourLoc = getLocation(); _dragger.completeDrag(e.getX() + ourLoc.x, e.getY() + ourLoc.y); } _dragger = null; e.consume(); } } // // MouseMotionListener // /** * If dragger is not null it is messaged with continueDrag. */ @Override public void mouseDragged(MouseEvent e) { if (_dragger != null) { if (e.getSource() == _jideSplitPane) { _dragger.continueDrag(e.getX(), e.getY()); } else if (e.getSource() == JideSplitPaneDivider.this) { Point ourLoc = getLocation(); _dragger.continueDrag(e.getX() + ourLoc.x, e.getY() + ourLoc.y); } e.consume(); } } } /** * Handles the events during a dragging session for a HORIZONTAL_SPLIT oriented split pane. This continually * messages dragDividerTo and then when done messages finishDraggingTo. When an instance * is created it should be messaged with isValid to insure that dragging can happen (dragging won't be * allowed if the two views can not be resized). */ protected class DragController { /** * Initial location of the divider. */ int initialLocation; /** * Maximum and minimum positions to drag to. */ int maxLocation, minLocation; /** * Initial location the mouse down happened at. */ int offset; protected DragController(MouseEvent e) { ComponentOrientation o = getComponentOrientation(); boolean ltr = o.isLeftToRight(); boolean reversed = !ltr && _jideSplitPane.getOrientation() == JideSplitPane.HORIZONTAL_SPLIT; Component leftC = reversed ? getSecondComponent(false) : getFirstComponent(false); Component rightC = reversed ? getFirstComponent(false) : getSecondComponent(false); initialLocation = getLocation().x; if (e.getSource() == JideSplitPaneDivider.this) { offset = e.getX(); } else { // splitPane offset = e.getX() - initialLocation; } if (leftC == null || rightC == null || offset < -1 || offset >= _jideSplitPane.getSize().width) { // Don't allow dragging. maxLocation = -1; } else { int index = _jideSplitPane.indexOf(JideSplitPaneDivider.this); int modelLeftWidth = 0; int modelRightWidth = 0; for (int i = 0; i < index; i++) { Component component = _jideSplitPane.getComponent(i); if (component instanceof JideSplitPaneDivider) { modelLeftWidth += component.getSize().getWidth(); } else if (component.isVisible()) { if (((JideBoxLayout) _jideSplitPane.getLayout()).getConstraintMap().get(component) == JideBoxLayout.FIX) { modelLeftWidth += component.getWidth(); } else { modelLeftWidth += component.getMinimumSize().getWidth(); } } } for (int i = index + 1; i < _jideSplitPane.getComponentCount(); i++) { Component component = _jideSplitPane.getComponent(i); if (component instanceof JideSplitPaneDivider) { modelRightWidth += component.getSize().getWidth(); } else if (component.isVisible()) { if (((JideBoxLayout) _jideSplitPane.getLayout()).getConstraintMap().get(component) == JideBoxLayout.FIX) { modelRightWidth += component.getWidth(); } else { modelRightWidth += component.getMinimumSize().getWidth(); } } } minLocation = reversed ? modelRightWidth : modelLeftWidth; maxLocation = _jideSplitPane.getWidth() - ((reversed ? modelLeftWidth : modelRightWidth) + (int) getSize().getWidth()); if (maxLocation < minLocation) minLocation = maxLocation = 0; } } /** * Returns true if the dragging session is valid. * * @return true or false. */ protected boolean isValid() { return (maxLocation > 0); } /** * Returns the new position to put the divider at based on the passed in MouseEvent. * * @param e the mouse event. * @return the position of the mouse event after considering the max and min size it is allowed. */ protected int positionForMouseEvent(MouseEvent e) { int newX = (e.getSource() == JideSplitPaneDivider.this) ? (e.getX() + getLocation().x) : e.getX(); newX = Math.min(maxLocation, Math.max(minLocation, newX - offset)); if (_jideSplitPane.getDividerStepSize() != 0) { int distanceFromCurrent = newX - getX(); newX -= (distanceFromCurrent % _jideSplitPane.getDividerStepSize()); } return newX; } /** * Returns the x argument, since this is used for horizontal splits. * * @param x x position * @param y y position * @return the actual position after considering the max and min size it is allowed. */ protected int getNeededLocation(int x, int y) { int newX; newX = Math.min(maxLocation, Math.max(minLocation, x - offset)); if (_jideSplitPane.getDividerStepSize() != 0) { int distanceFromCurrent = newX - getX(); newX -= (distanceFromCurrent % _jideSplitPane.getDividerStepSize()); } return newX; } protected void continueDrag(int newX, int newY) { dragDividerTo(getNeededLocation(newX, newY)); } /** * Messages dragDividerTo with the new location for the mouse event. * * @param e the mouse event. */ protected void continueDrag(MouseEvent e) { dragDividerTo(positionForMouseEvent(e)); } protected void completeDrag(int x, int y) { finishDraggingTo(getNeededLocation(x, y)); } /** * Messages finishDraggingTo with the new location for the mouse event. * * @param e the mouse event. */ protected void completeDrag(MouseEvent e) { finishDraggingTo(positionForMouseEvent(e)); } } // End of BasicJideSplitPaneDivider.DragController /** * Handles the events during a dragging session for a VERTICAL_SPLIT oriented split pane. This continually messages * dragDividerTo and then when done messages finishDraggingTo. When an instance is created * it should be messaged with isValid to insure that dragging can happen (dragging won't be allowed if * the two views can not be resized). */ protected class VerticalDragController extends DragController { /* Vertical DragControllers are now in terms of y, not x. */ protected VerticalDragController(MouseEvent e) { super(e); Component leftC = getFirstComponent(false); Component rightC = getSecondComponent(false); initialLocation = getLocation().y; if (e.getSource() == JideSplitPaneDivider.this) { offset = e.getY(); } else { // splitPane offset = e.getY() - initialLocation; } if (leftC == null || rightC == null || offset < -1 || offset >= _jideSplitPane.getSize().height) { // Don't allow dragging. maxLocation = -1; } else { int index = _jideSplitPane.indexOf(JideSplitPaneDivider.this); int modelUpHeight = 0; int modelDownHeight = 0; for (int i = 0; i < index; i++) { Component component = _jideSplitPane.getComponent(i); if (component instanceof JideSplitPaneDivider) { modelUpHeight += component.getSize().getHeight(); } else if (component.isVisible()) { if (((JideBoxLayout) _jideSplitPane.getLayout()).getConstraintMap().get(component) == JideBoxLayout.FIX) { modelUpHeight += component.getHeight(); } else { modelUpHeight += component.getMinimumSize().getHeight(); } } } for (int i = index + 1; i < _jideSplitPane.getComponentCount(); i++) { Component component = _jideSplitPane.getComponent(i); if (component instanceof JideSplitPaneDivider) { modelDownHeight += component.getSize().getHeight(); } else if (component.isVisible()) { if (((JideBoxLayout) _jideSplitPane.getLayout()).getConstraintMap().get(component) == JideBoxLayout.FIX) { modelDownHeight += component.getHeight(); } else { modelDownHeight += component.getMinimumSize().getHeight(); } } } minLocation = modelUpHeight; maxLocation = _jideSplitPane.getHeight() - modelDownHeight - (int) getSize().getHeight(); if (maxLocation < minLocation) minLocation = maxLocation = 0; } } /** * Returns the y argument, since this is used for vertical splits. */ @Override protected int getNeededLocation(int x, int y) { int newY; newY = Math.min(maxLocation, Math.max(minLocation, y - offset)); if (_jideSplitPane.getDividerStepSize() != 0) { int distanceFromCurrent = newY - getY(); newY -= (distanceFromCurrent % _jideSplitPane.getDividerStepSize()); } return newY; } /** * Returns the new position to put the divider at based on the passed in MouseEvent. */ @Override protected int positionForMouseEvent(MouseEvent e) { int newY = (e.getSource() == JideSplitPaneDivider.this) ? (e.getY() + getLocation().y) : e.getY(); newY = Math.min(maxLocation, Math.max(minLocation, newY - offset)); if (_jideSplitPane.getDividerStepSize() != 0) { int distanceFromCurrent = newY - getY(); newY -= (distanceFromCurrent % _jideSplitPane.getDividerStepSize()); } return newY; } } // End of BasicSplitPaneDividier.VerticalDragController /* * Added on 05/14/2008 in response to http://www.jidesoft.com/forum/viewtopic.php?p=26074#26074, * http://www.jidesoft.com/forum/viewtopic.php?p=5148#5148 and * http://www.jidesoft.com/forum/viewtopic.php?p=23403#23403. * * The addition below provides the option of adding a one-touch button which is capable of expanding/collapsing the * split pane (in one click of the mouse). * * @see #setOneTouchExpandable(boolean) */ /** * Indicates that the pane of the left of this component has been collapse by the one-touch button. */ public static final int COLLAPSED_STATE = 0; /** * Indicates that this divider has not been expanded or collapsed. */ public static final int DEFAULT_STATE = 1; /** * Indicates that the pane of the right of this component has been collapse by the one-touch button. Hence, the pane * on the left has been "expanded". */ public static final int EXPANDED_STATE = 2; /** * Indicates the current state of this divider. Either expanded, collapsed or in its default state. */ private int _currentState = DEFAULT_STATE; /** * Button for quickly toggling the left component. */ protected JButton _leftButton = null; /** * Button for quickly toggling the right component. */ protected JButton _rightButton = null; /** * Used to paint the triangle on the one-touch buttons. */ private int _triangleSize = 5; /** * Used as the one-touch button's width. */ private int _buttonWidth = 5; /** * Used as the one-touch button's height. */ private int _buttonHeight = 10; /** * The last non-expanded/collapsed position of the divider. We want to keep track of the dividers last position, so * if a user collapses the pane on the right of this divider for example, pressing the expand button will revert the * divider back to its original location - the last non-expanded/collapsed position. * * @see JideSplitPaneDivider.OneTouchActionHandler#actionPerformed */ private int _lastPosition; /** * Invoked when the oneTouchExpandable value of the JideSplitPane changes.

Responsible for creating the * one-touch buttons and revalidating the UI. *

* #see JideSplitePane#setOneTouchExpandable(boolean) */ protected void oneTouchExpandableChanged() { if (_jideSplitPane.isOneTouchExpandable() && _leftButton == null) { _leftButton = createLeftOneTouchButton(); if (_leftButton != null) { _leftButton.addActionListener(new OneTouchActionHandler(true)); if (_orientation == JideSplitPane.HORIZONTAL_SPLIT) { _leftButton.setBounds(1, 10, _buttonWidth, _buttonHeight); } else if (_orientation == JideSplitPane.VERTICAL_SPLIT) { //noinspection SuspiciousNameCombination _leftButton.setBounds(10, 1, _buttonHeight, _buttonWidth); } add(_leftButton); } } if (_jideSplitPane.isOneTouchExpandable() && _rightButton == null) { _rightButton = createRightOneTouchButton(); if (_rightButton != null) { _rightButton.addActionListener(new OneTouchActionHandler(false)); if (_orientation == JideSplitPane.HORIZONTAL_SPLIT) { _rightButton.setBounds(1, 25, _buttonWidth, _buttonHeight); } else if (_orientation == JideSplitPane.VERTICAL_SPLIT) { //noinspection SuspiciousNameCombination _rightButton.setBounds(25, 1, _buttonHeight, _buttonWidth); } add(_rightButton); } } if (!(_jideSplitPane.isOneTouchExpandable()) && _leftButton != null) { remove(_leftButton); _leftButton = null; } if (!(_jideSplitPane.isOneTouchExpandable()) && _rightButton != null) { remove(_rightButton); _rightButton = null; } /* * The one-touch buttons should completely collapse the pane in question; as such, all panes should have a * their minimum sizes overridden whilst one-touch expandable is on. * * We fill the minimunSizes array with the current minimum size of each pane for restoration later. */ int paneCount = _jideSplitPane.getPaneCount(); if (_jideSplitPane.isOneTouchExpandable()) { for (int i = 0; i < paneCount; i++) { Component component = _jideSplitPane.getPaneAt(i); PortingUtils.setMinimumSize(component, new Dimension(0, 0)); } } else { for (int i = 0; i < paneCount; i++) { Component component = _jideSplitPane.getPaneAt(i); PortingUtils.setMinimumSize(component, null); } } } /** * Builds the Button that can be used to collapse the component to the left/above this divider. * * @return a JButton instance used to collapse the component to the left/above this divider. */ protected JButton createLeftOneTouchButton() { JButton b = new JButton() { @Override public void setBorder(Border b) { } @Override public void paint(Graphics g) { if (_jideSplitPane != null) { g.setColor(JideSplitPaneDivider.this.getBackground()); if (isOpaque()) { g.fillRect(0, 0, this.getWidth(), this.getHeight()); } if (_jideSplitPane.getLeftOneTouchButtonImageIcon() != null) { _jideSplitPane.getLeftOneTouchButtonImageIcon().paintIcon(this, g, 0, 0); } else if (_orientation == JideSplitPane.HORIZONTAL_SPLIT) { /* * If the split pane is horizontally split, paint the 'left' button. */ g.setColor(getDarkShadowColor()); int size = _triangleSize; for (int i = 0; i < size; i++) { g.drawLine(i, size - i, i, size + i); } } else if (_orientation == JideSplitPane.VERTICAL_SPLIT) { /* * If the split pane is vertically split, paint an 'up' button. */ g.setColor(getDarkShadowColor()); int size = _triangleSize; for (int i = 0; i < size; i++) { g.drawLine(size - i, i, size + i, i); } } } } @SuppressWarnings({"deprecation"}) @Override public boolean isFocusTraversable() { return false; } }; b.setMinimumSize(new Dimension(_buttonWidth, _buttonHeight)); b.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); b.setFocusPainted(false); b.setBorderPainted(false); b.setRequestFocusEnabled(false); return b; } /** * Gets the current collapse/expand state. *

* The default value is DEFAULT_STATE when {@link com.jidesoft.swing.JideSplitPane#isOneTouchExpandable()} returns false. * It could be EXPANDED_STATE or COLLAPSED_STATE when one touch expandable is activated. * * @return the current state * @since 3.3.8 */ public int getCurrentState() { return _currentState; } /** * Builds the rightButton that can be used to expand/collapse a split panes divider to the right. * * @return a JButton instance used to expand/collapse a split panes divider to the right. */ protected JButton createRightOneTouchButton() { JButton b = new JButton() { @Override public void setBorder(Border b) { } @Override public void paint(Graphics g) { if (_jideSplitPane != null) { g.setColor(JideSplitPaneDivider.this.getBackground()); if (isOpaque()) { g.fillRect(0, 0, this.getWidth(), this.getHeight()); } if (_jideSplitPane.getRightOneTouchButtonImageIcon() != null) { _jideSplitPane.getRightOneTouchButtonImageIcon().paintIcon(this, g, 0, 0); } else if (_orientation == JideSplitPane.HORIZONTAL_SPLIT) { /* * If the split pane is horizontally split, paint the 'right' button. */ g.setColor(getDarkShadowColor()); int size = _triangleSize; int j = 0; for (int i = size - 1; i >= 0; i--) { g.drawLine(j, size - i, j, size + i); j++; } } else if (_orientation == JideSplitPane.VERTICAL_SPLIT) { /* * If the split pane is vertically split, paint an 'down' button. */ g.setColor(getDarkShadowColor()); int size = _triangleSize; int j = 0; for (int i = size - 1; i >= 0; i--) { g.drawLine(size - i, j, size + i, j); j++; } } } } @SuppressWarnings({"deprecation"}) @Override public boolean isFocusTraversable() { return false; } }; b.setMinimumSize(new Dimension(_buttonWidth, _buttonHeight)); b.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); b.setFocusPainted(false); b.setBorderPainted(false); b.setRequestFocusEnabled(false); return b; } /** * Returns a dark shadow color. This color is used to paint the left and right buttons graphics. It is based on the * current Look and Feel. (And thus fits all look and Feels.) * * @return UIManager.getColor("controlDkShadow") */ protected Color getDarkShadowColor() { return UIManager.getColor("controlDkShadow"); } /** * The actionListener that will listen for button presses on either the leftButton or the rightButton. This class is * responsible for one-touch expanding/collapsing of the divider. */ protected class OneTouchActionHandler implements ActionListener { /** * If collapse is true, move the divider to the left/top; otherwise, move the divider to the * right/bottom. */ private boolean _collapse; /** * Constructs the handler responsible for expanding/collapsing the panes on either side of this divider. * * @param collapse true or false. */ public OneTouchActionHandler(boolean collapse) { _collapse = collapse; } /** * Called to collapse or expand this divider. */ public void actionPerformed(ActionEvent e) { /* * If _collapse is true, move the divider to the left/top; otherwise, move the divider to the right/bottom. */ /* * If the left button is pressed. (If _collapse is true.) */ if (_collapse) { if (_currentState == COLLAPSED_STATE) { int indexOfDivider = _jideSplitPane.indexOfDivider(JideSplitPaneDivider.this); int dividerPosition = _jideSplitPane.getDividerLocation(indexOfDivider); int previousDividerPosition = getPreviousDividerLocation(true, false); if (dividerPosition != previousDividerPosition) { _currentState = DEFAULT_STATE; } } if (_currentState == EXPANDED_STATE) { _jideSplitPane.setDividerLocation(JideSplitPaneDivider.this, _lastPosition); _currentState = DEFAULT_STATE; } else if (_currentState == DEFAULT_STATE) { int indexOfDivider = _jideSplitPane.indexOfDivider(JideSplitPaneDivider.this); _lastPosition = _jideSplitPane.getDividerLocation(indexOfDivider); int loc = getPreviousDividerLocation(true, false); _jideSplitPane.setDividerLocation(JideSplitPaneDivider.this, loc); _currentState = COLLAPSED_STATE; } } /* * If the right button is pressed. (If _collapse is false.) */ else { if (_currentState == EXPANDED_STATE) { int indexOfDivider = _jideSplitPane.indexOfDivider(JideSplitPaneDivider.this); int dividerPosition = _jideSplitPane.getDividerLocation(indexOfDivider); int nextDividerPosition = getNextDividerLocation(true, false); if (dividerPosition != nextDividerPosition) { _currentState = DEFAULT_STATE; } } if (_currentState == COLLAPSED_STATE) { _jideSplitPane.setDividerLocation(JideSplitPaneDivider.this, _lastPosition); _currentState = DEFAULT_STATE; } else if (_currentState == DEFAULT_STATE) { int indexOfDivider = _jideSplitPane.indexOfDivider(JideSplitPaneDivider.this); _lastPosition = _jideSplitPane.getDividerLocation(indexOfDivider); int loc = getNextDividerLocation(true, false); _jideSplitPane.setDividerLocation(JideSplitPaneDivider.this, loc); _currentState = EXPANDED_STATE; } } } } /** * Collapses the divider to the left side (or to the top if vertically). */ public void collapse() { if (_leftButton != null) { _leftButton.doClick(); } else { new OneTouchActionHandler(true).actionPerformed(null); } } /** * Expands the divider to the right side (or to the bottom if vertically). */ public void expand() { if (_rightButton != null) { _rightButton.doClick(); } else { new OneTouchActionHandler(false).actionPerformed(null); } } /* * End of one-touch expand/collapse addition. * * Added on 05/14/2008. */ }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy