/* * Copyright (c) 2003, 2004 JGoodies Karsten Lentzsch. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * o Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * o 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. * * o Neither the name of JGoodies Karsten Lentzsch 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. */ package com.jgoodies.uif_lite.component; import java.awt.Component; import javax.swing.JButton; import javax.swing.JSplitPane; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.plaf.SplitPaneUI; import javax.swing.plaf.basic.BasicSplitPaneUI; /** * A <code>JSplitPane</code> subclass that can try to remove the divider border. * Useful if the splitted components render their own borders. * Note that this feature is not supported by all look&feels. * Some look&feel implementation will always show a divider border, * and conversely, others will never show a divider border. * * @author Karsten Lentzsch * @version $Revision: 806 $ * * @see javax.swing.plaf.basic.BasicSplitPaneUI */ public final class UIFSplitPane extends JSplitPane { /** * Holds the name of the bound property that tries to show or hide * the split pane's divider border. * * @see #isDividerBorderVisible() * @see #setDividerBorderVisible(boolean) */ public static final String PROPERTYNAME_DIVIDER_BORDER_VISIBLE = "dividerBorderVisible"; /** * Holds an empty border that is reused for the split pane itself * and the divider. */ private static final Border EMPTY_BORDER = new EmptyBorder(0, 0, 0, 0); /** * Determines whether the divider border shall be removed when * the UI is updated. * * @see #isDividerBorderVisible() * @see #setDividerBorderVisible(boolean) */ private boolean dividerBorderVisible; // Instance Creation ***************************************************** /** * Constructs a <code>UIFSplitPane</code> configured to arrange the child * components side-by-side horizontally with no continuous * layout, using two buttons for the components. */ public UIFSplitPane() { this(JSplitPane.HORIZONTAL_SPLIT, false, new JButton(UIManager.getString("SplitPane.leftButtonText")), new JButton(UIManager.getString("SplitPane.rightButtonText"))); } /** * Constructs a <code>UIFSplitPane</code> configured with the * specified orientation and no continuous layout. * * @param newOrientation <code>JSplitPane.HORIZONTAL_SPLIT</code> or * <code>JSplitPane.VERTICAL_SPLIT</code> * @throws IllegalArgumentException if <code>orientation</code> * is not one of HORIZONTAL_SPLIT or VERTICAL_SPLIT. */ public UIFSplitPane(int newOrientation) { this(newOrientation, false); } /** * Constructs a <code>UIFSplitPane</code> with the specified * orientation and redrawing style. * * @param newOrientation <code>JSplitPane.HORIZONTAL_SPLIT</code> or * <code>JSplitPane.VERTICAL_SPLIT</code> * @param newContinuousLayout a boolean, true for the components to * redraw continuously as the divider changes position, false * to wait until the divider position stops changing to redraw * @throws IllegalArgumentException if <code>orientation</code> * is not one of HORIZONTAL_SPLIT or VERTICAL_SPLIT */ public UIFSplitPane(int newOrientation, boolean newContinuousLayout) { this(newOrientation, newContinuousLayout, null, null); } /** * Constructs a <code>UIFSplitPane</code> with the specified orientation * and the given componenents. * * @param orientation <code>JSplitPane.HORIZONTAL_SPLIT</code> or * <code>JSplitPane.VERTICAL_SPLIT</code> * @param leftComponent the <code>Component</code> that will * appear on the left of a horizontally-split pane, * or at the top of a vertically-split pane * @param rightComponent the <code>Component</code> that will * appear on the right of a horizontally-split pane, * or at the bottom of a vertically-split pane * @throws IllegalArgumentException if <code>orientation</code> * is not one of: HORIZONTAL_SPLIT or VERTICAL_SPLIT */ public UIFSplitPane(int orientation, Component leftComponent, Component rightComponent) { this(orientation, false, leftComponent, rightComponent); } /** * Constructs a <code>UIFSplitPane</code> with the specified orientation, * redrawing style, and given components. * * @param orientation <code>JSplitPane.HORIZONTAL_SPLIT</code> or * <code>JSplitPane.VERTICAL_SPLIT</code> * @param continuousLayout a boolean, true for the components to * redraw continuously as the divider changes position, false * to wait until the divider position stops changing to redraw * @param leftComponent the <code>Component</code> that will * appear on the left * of a horizontally-split pane, or at the top of a * vertically-split pane * @param rightComponent the <code>Component</code> that will * appear on the right * of a horizontally-split pane, or at the bottom of a * vertically-split pane * @throws IllegalArgumentException if <code>orientation</code> * is not one of HORIZONTAL_SPLIT or VERTICAL_SPLIT */ public UIFSplitPane(int orientation, boolean continuousLayout, Component leftComponent, Component rightComponent){ super(orientation, continuousLayout, leftComponent, rightComponent); dividerBorderVisible = false; } /** * Constructs a <code>UIFSplitPane</code>, * i.e. a <code>JSplitPane</code> that has no borders. * Also disabled the one touch exandable property. * * @param orientation <code>JSplitPane.HORIZONTAL_SPLIT</code> or * <code>JSplitPane.VERTICAL_SPLIT</code> * @param leftComponent the <code>Component</code> that will * appear on the left of a horizontally-split pane, * or at the top of a vertically-split pane * @param rightComponent the <code>Component</code> that will * appear on the right of a horizontally-split pane, * or at the bottom of a vertically-split pane * @throws IllegalArgumentException if <code>orientation</code> * is not one of: HORIZONTAL_SPLIT or VERTICAL_SPLIT */ public static UIFSplitPane createStrippedSplitPane( int orientation, Component leftComponent, Component rightComponent) { UIFSplitPane split = new UIFSplitPane(orientation, leftComponent, rightComponent); split.setBorder(EMPTY_BORDER); split.setOneTouchExpandable(false); return split; } // Accessing Properties ************************************************** /** * Checks and answers whether the divider border shall be visible * or invisible. * Note that this feature is not supported by all look&feels. * Some look&feel implementation will always show a divider border, * and conversely, others will never show a divider border. * * @return the desired (but potentially inaccurate) divider border visiblity */ public boolean isDividerBorderVisible() { return dividerBorderVisible; } /** * Makes the divider border visible or invisible. * Note that this feature is not supported by all look&feels. * Some look&feel implementation will always show a divider border, * and conversely, others will never show a divider border. * * @param newVisibility true for visible, false for invisible */ public void setDividerBorderVisible(boolean newVisibility) { boolean oldVisibility = isDividerBorderVisible(); if (oldVisibility == newVisibility) return; dividerBorderVisible = newVisibility; firePropertyChange(PROPERTYNAME_DIVIDER_BORDER_VISIBLE, oldVisibility, newVisibility); } // Changing the Divider Border Visibility ********************************* /** * Updates the UI and sets an empty divider border. The divider border * may be restored by a L&F at UI installation time. And so, we * try to reset it each time the UI is changed. */ public void updateUI() { super.updateUI(); if (!isDividerBorderVisible()) setEmptyDividerBorder(); } /** * Sets an empty divider border if and only if the UI is * an instance of <code>BasicSplitPaneUI</code>. */ private void setEmptyDividerBorder() { SplitPaneUI splitPaneUI = getUI(); if (splitPaneUI instanceof BasicSplitPaneUI) { BasicSplitPaneUI basicUI = (BasicSplitPaneUI) splitPaneUI; basicUI.getDivider().setBorder(EMPTY_BORDER); } } }