001 /*
002 * Copyright (c) 2000-2006 JGoodies Karsten Lentzsch. All Rights Reserved.
003 *
004 * Redistribution and use in source and binary forms, with or without
005 * modification, are permitted provided that the following conditions are met:
006 *
007 * o Redistributions of source code must retain the above copyright notice,
008 * this list of conditions and the following disclaimer.
009 *
010 * o Redistributions in binary form must reproduce the above copyright notice,
011 * this list of conditions and the following disclaimer in the documentation
012 * and/or other materials provided with the distribution.
013 *
014 * o Neither the name of JGoodies Karsten Lentzsch nor the names of
015 * its contributors may be used to endorse or promote products derived
016 * from this software without specific prior written permission.
017 *
018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030
031 package com.jgoodies.uif_lite.component;
032
033 import java.awt.Component;
034
035 import javax.swing.BorderFactory;
036 import javax.swing.JButton;
037 import javax.swing.JSplitPane;
038 import javax.swing.UIManager;
039 import javax.swing.plaf.SplitPaneUI;
040 import javax.swing.plaf.basic.BasicSplitPaneUI;
041
042 /**
043 * A <code>JSplitPane</code> subclass that can try to remove the divider border.
044 * Useful if the splitted components render their own borders.
045 * Note that this feature is not supported by all look&feels.
046 * Some look&feel implementation will always show a divider border,
047 * and conversely, others will never show a divider border.
048 *
049 * @author Karsten Lentzsch
050 * @version $Revision: 1.1 $
051 *
052 * @see javax.swing.plaf.basic.BasicSplitPaneUI
053 */
054
055 public final class UIFSplitPane extends JSplitPane {
056
057 /**
058 * Holds the name of the bound property that tries to show or hide
059 * the split pane's divider border.
060 *
061 * @see #isDividerBorderVisible()
062 * @see #setDividerBorderVisible(boolean)
063 */
064 public static final String PROPERTYNAME_DIVIDER_BORDER_VISIBLE =
065 "dividerBorderVisible";
066
067 /**
068 * Determines whether the divider border shall be removed when
069 * the UI is updated.
070 *
071 * @see #isDividerBorderVisible()
072 * @see #setDividerBorderVisible(boolean)
073 */
074 private boolean dividerBorderVisible;
075
076
077 // Instance Creation *****************************************************
078
079 /**
080 * Constructs a <code>UIFSplitPane</code> configured to arrange the child
081 * components side-by-side horizontally with no continuous
082 * layout, using two buttons for the components.
083 */
084 public UIFSplitPane() {
085 this(JSplitPane.HORIZONTAL_SPLIT, false,
086 new JButton(UIManager.getString("SplitPane.leftButtonText")),
087 new JButton(UIManager.getString("SplitPane.rightButtonText")));
088 }
089
090
091 /**
092 * Constructs a <code>UIFSplitPane</code> configured with the
093 * specified orientation and no continuous layout.
094 *
095 * @param newOrientation <code>JSplitPane.HORIZONTAL_SPLIT</code> or
096 * <code>JSplitPane.VERTICAL_SPLIT</code>
097 * @throws IllegalArgumentException if <code>orientation</code>
098 * is not one of HORIZONTAL_SPLIT or VERTICAL_SPLIT.
099 */
100 public UIFSplitPane(int newOrientation) {
101 this(newOrientation, false);
102 }
103
104
105 /**
106 * Constructs a <code>UIFSplitPane</code> with the specified
107 * orientation and redrawing style.
108 *
109 * @param newOrientation <code>JSplitPane.HORIZONTAL_SPLIT</code> or
110 * <code>JSplitPane.VERTICAL_SPLIT</code>
111 * @param newContinuousLayout a boolean, true for the components to
112 * redraw continuously as the divider changes position, false
113 * to wait until the divider position stops changing to redraw
114 * @throws IllegalArgumentException if <code>orientation</code>
115 * is not one of HORIZONTAL_SPLIT or VERTICAL_SPLIT
116 */
117 public UIFSplitPane(int newOrientation,
118 boolean newContinuousLayout) {
119 this(newOrientation, newContinuousLayout, null, null);
120 }
121
122
123 /**
124 * Constructs a <code>UIFSplitPane</code> with the specified orientation
125 * and the given componenents.
126 *
127 * @param orientation <code>JSplitPane.HORIZONTAL_SPLIT</code> or
128 * <code>JSplitPane.VERTICAL_SPLIT</code>
129 * @param leftComponent the <code>Component</code> that will
130 * appear on the left of a horizontally-split pane,
131 * or at the top of a vertically-split pane
132 * @param rightComponent the <code>Component</code> that will
133 * appear on the right of a horizontally-split pane,
134 * or at the bottom of a vertically-split pane
135 * @throws IllegalArgumentException if <code>orientation</code>
136 * is not one of: HORIZONTAL_SPLIT or VERTICAL_SPLIT
137 */
138 public UIFSplitPane(int orientation,
139 Component leftComponent,
140 Component rightComponent) {
141 this(orientation, false, leftComponent, rightComponent);
142 }
143
144
145 /**
146 * Constructs a <code>UIFSplitPane</code> with the specified orientation,
147 * redrawing style, and given components.
148 *
149 * @param orientation <code>JSplitPane.HORIZONTAL_SPLIT</code> or
150 * <code>JSplitPane.VERTICAL_SPLIT</code>
151 * @param continuousLayout a boolean, true for the components to
152 * redraw continuously as the divider changes position, false
153 * to wait until the divider position stops changing to redraw
154 * @param leftComponent the <code>Component</code> that will
155 * appear on the left
156 * of a horizontally-split pane, or at the top of a
157 * vertically-split pane
158 * @param rightComponent the <code>Component</code> that will
159 * appear on the right
160 * of a horizontally-split pane, or at the bottom of a
161 * vertically-split pane
162 * @throws IllegalArgumentException if <code>orientation</code>
163 * is not one of HORIZONTAL_SPLIT or VERTICAL_SPLIT
164 */
165 public UIFSplitPane(int orientation,
166 boolean continuousLayout,
167 Component leftComponent,
168 Component rightComponent){
169 super(orientation, continuousLayout, leftComponent, rightComponent);
170 dividerBorderVisible = false;
171 }
172
173
174 /**
175 * Constructs a <code>UIFSplitPane</code>,
176 * i.e. a <code>JSplitPane</code> that has no borders.
177 * Also disabled the one touch exandable property.
178 *
179 * @param orientation <code>JSplitPane.HORIZONTAL_SPLIT</code> or
180 * <code>JSplitPane.VERTICAL_SPLIT</code>
181 * @param leftComponent the <code>Component</code> that will
182 * appear on the left of a horizontally-split pane,
183 * or at the top of a vertically-split pane
184 * @param rightComponent the <code>Component</code> that will
185 * appear on the right of a horizontally-split pane,
186 * or at the bottom of a vertically-split pane
187 * @throws IllegalArgumentException if <code>orientation</code>
188 * is not one of: HORIZONTAL_SPLIT or VERTICAL_SPLIT
189 */
190 public static UIFSplitPane createStrippedSplitPane(
191 int orientation,
192 Component leftComponent,
193 Component rightComponent) {
194 UIFSplitPane split = new UIFSplitPane(orientation, leftComponent, rightComponent);
195 split.setBorder(BorderFactory.createEmptyBorder());
196 split.setOneTouchExpandable(false);
197 return split;
198 }
199
200
201 // Accessing Properties **************************************************
202
203 /**
204 * Checks and answers whether the divider border shall be visible
205 * or invisible.
206 * Note that this feature is not supported by all look&feels.
207 * Some look&feel implementation will always show a divider border,
208 * and conversely, others will never show a divider border.
209 *
210 * @return the desired (but potentially inaccurate) divider border visiblity
211 */
212 public boolean isDividerBorderVisible() {
213 return dividerBorderVisible;
214 }
215
216
217 /**
218 * Makes the divider border visible or invisible.
219 * Note that this feature is not supported by all look&feels.
220 * Some look&feel implementation will always show a divider border,
221 * and conversely, others will never show a divider border.
222 *
223 * @param newVisibility true for visible, false for invisible
224 */
225 public void setDividerBorderVisible(boolean newVisibility) {
226 boolean oldVisibility = isDividerBorderVisible();
227 if (oldVisibility == newVisibility)
228 return;
229 dividerBorderVisible = newVisibility;
230 firePropertyChange(PROPERTYNAME_DIVIDER_BORDER_VISIBLE,
231 oldVisibility,
232 newVisibility);
233 }
234
235
236 // Changing the Divider Border Visibility *********************************
237
238 /**
239 * Updates the UI and sets an empty divider border. The divider border
240 * may be restored by a L&F at UI installation time. And so, we
241 * try to reset it each time the UI is changed.
242 */
243 public void updateUI() {
244 super.updateUI();
245 if (!isDividerBorderVisible())
246 setEmptyDividerBorder();
247 }
248
249
250 /**
251 * Sets an empty divider border if and only if the UI is
252 * an instance of <code>BasicSplitPaneUI</code>.
253 */
254 private void setEmptyDividerBorder() {
255 SplitPaneUI splitPaneUI = getUI();
256 if (splitPaneUI instanceof BasicSplitPaneUI) {
257 BasicSplitPaneUI basicUI = (BasicSplitPaneUI) splitPaneUI;
258 basicUI.getDivider().setBorder(BorderFactory.createEmptyBorder());
259 }
260 }
261
262
263 }
|