Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / javax / swing / plaf / basic / BasicSplitPaneUI.java
blob8a7c9d2a2906d84a4e95bbd7e204f47e7b28cd0d
1 /* BasicSplitPaneUI.java --
2 Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing.plaf.basic;
41 import java.awt.Canvas;
42 import java.awt.Color;
43 import java.awt.Component;
44 import java.awt.Container;
45 import java.awt.Dimension;
46 import java.awt.Graphics;
47 import java.awt.Insets;
48 import java.awt.LayoutManager2;
49 import java.awt.Point;
50 import java.awt.event.ActionEvent;
51 import java.awt.event.ActionListener;
52 import java.awt.event.FocusAdapter;
53 import java.awt.event.FocusEvent;
54 import java.awt.event.FocusListener;
55 import java.beans.PropertyChangeEvent;
56 import java.beans.PropertyChangeListener;
58 import javax.swing.JComponent;
59 import javax.swing.JSplitPane;
60 import javax.swing.KeyStroke;
61 import javax.swing.LookAndFeel;
62 import javax.swing.UIManager;
63 import javax.swing.plaf.ComponentUI;
64 import javax.swing.plaf.SplitPaneUI;
65 import javax.swing.plaf.UIResource;
67 /**
68 * This is the Basic Look and Feel implementation of the SplitPaneUI class.
70 public class BasicSplitPaneUI extends SplitPaneUI
72 /**
73 * This Layout Manager controls the position and size of the components when
74 * the JSplitPane's orientation is HORIZONTAL_SPLIT.
76 * @specnote Apparently this class was intended to be protected,
77 * but was made public by a compiler bug and is now
78 * public for compatibility.
80 public class BasicHorizontalLayoutManager implements LayoutManager2
82 // 3 components at a time.
83 // LEFT/TOP = 0
84 // RIGHT/BOTTOM = 1
85 // DIVIDER = 2
87 /**
88 * This array contains the components in the JSplitPane. The left/top
89 * component is at index 0, the right/bottom is at 1, and the divider is
90 * at 2.
92 protected Component[] components = new Component[3];
94 // These are the _current_ widths of the associated component.
96 /**
97 * This array contains the current width (for HORIZONTAL_SPLIT) or height
98 * (for VERTICAL_SPLIT) of the components. The indices are the same as
99 * for components.
101 protected int[] sizes = new int[3];
104 * This method adds the component given to the JSplitPane. The position of
105 * the component is given by the constraints object.
107 * @param comp The Component to add.
108 * @param constraints The constraints that bind the object.
110 public void addLayoutComponent(Component comp, Object constraints)
112 addLayoutComponent((String) constraints, comp);
116 * This method is called to add a Component to the JSplitPane. The
117 * placement string determines where the Component will be placed. The
118 * string should be one of LEFT, RIGHT, TOP, BOTTOM or null (signals that
119 * the component is the divider).
121 * @param place The placement of the Component.
122 * @param component The Component to add.
124 * @throws IllegalArgumentException DOCUMENT ME!
126 public void addLayoutComponent(String place, Component component)
128 int i = 0;
129 if (place == null)
130 i = 2;
131 else if (place.equals(JSplitPane.TOP) || place.equals(JSplitPane.LEFT))
132 i = 0;
133 else if (place.equals(JSplitPane.BOTTOM)
134 || place.equals(JSplitPane.RIGHT))
135 i = 1;
136 else
137 throw new IllegalArgumentException("Illegal placement in JSplitPane");
138 components[i] = component;
139 resetSizeAt(i);
140 splitPane.revalidate();
141 splitPane.repaint();
145 * This method returns the width of the JSplitPane minus the insets.
147 * @param containerSize The Dimensions of the JSplitPane.
148 * @param insets The Insets of the JSplitPane.
150 * @return The width of the JSplitPane minus the insets.
152 protected int getAvailableSize(Dimension containerSize, Insets insets)
154 return containerSize.width - insets.left - insets.right;
158 * This method returns the given insets left value. If the given inset is
159 * null, then 0 is returned.
161 * @param insets The Insets to use with the JSplitPane.
163 * @return The inset's left value.
165 protected int getInitialLocation(Insets insets)
167 if (insets != null)
168 return insets.left;
169 return 0;
173 * This specifies how a component is aligned with respect to other
174 * components in the x fdirection.
176 * @param target The container.
178 * @return The component's alignment.
180 public float getLayoutAlignmentX(Container target)
182 return target.getAlignmentX();
186 * This specifies how a component is aligned with respect to other
187 * components in the y direction.
189 * @param target The container.
191 * @return The component's alignment.
193 public float getLayoutAlignmentY(Container target)
195 return target.getAlignmentY();
199 * This method returns the preferred width of the component.
201 * @param c The component to measure.
203 * @return The preferred width of the component.
205 protected int getPreferredSizeOfComponent(Component c)
207 Dimension dims = c.getPreferredSize();
208 if (dims != null)
209 return dims.width;
210 return 0;
214 * This method returns the current width of the component.
216 * @param c The component to measure.
218 * @return The width of the component.
220 protected int getSizeOfComponent(Component c)
222 return c.getWidth();
226 * This method returns the sizes array.
228 * @return The sizes array.
230 protected int[] getSizes()
232 return sizes;
236 * This method invalidates the layout. It does nothing.
238 * @param c The container to invalidate.
240 public void invalidateLayout(Container c)
242 // DO NOTHING
246 * This method lays out the components in the container.
248 * @param container The container to lay out.
250 public void layoutContainer(Container container)
252 if (container instanceof JSplitPane)
254 JSplitPane split = (JSplitPane) container;
255 distributeExtraSpace();
256 Insets insets = split.getInsets();
257 Dimension dims = split.getSize();
258 int loc = getInitialLocation(insets);
259 int available = getAvailableSize(dims, insets);
260 sizes[0] = getDividerLocation(split) - loc;
261 sizes[1] = available - sizes[0] - sizes[2];
262 // The size of the divider won't change.
264 // Layout component#1.
265 setComponentToSize(components[0], sizes[0], loc, insets, dims);
266 // Layout divider.
267 loc += sizes[0];
268 setComponentToSize(components[2], sizes[2], loc, insets, dims);
269 // Layout component#2.
270 loc += sizes[2];
271 setComponentToSize(components[1], sizes[1], loc, insets, dims);
276 * This method returns the maximum size for the container given the
277 * components. It returns a new Dimension object that has width and
278 * height equal to Integer.MAX_VALUE.
280 * @param target The container to measure.
282 * @return The maximum size.
284 public Dimension maximumLayoutSize(Container target)
286 return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
290 * This method returns the container's minimum size. The minimum width is
291 * the sum of all the component's minimum widths. The minimum height is
292 * the maximum of all the components' minimum heights.
294 * @param target The container to measure.
296 * @return The minimum size.
298 public Dimension minimumLayoutSize(Container target)
300 if (target instanceof JSplitPane)
302 JSplitPane split = (JSplitPane) target;
303 Insets insets = target.getInsets();
305 int height = 0;
306 int width = 0;
307 for (int i = 0; i < components.length; i++)
309 if (components[i] == null)
310 continue;
311 Dimension dims = components[i].getMinimumSize();
312 if (dims != null)
314 width += dims.width;
315 height = Math.max(height, dims.height);
318 return new Dimension(width, height);
320 return null;
324 * This method returns the container's preferred size. The preferred width
325 * is the sum of all the component's preferred widths. The preferred
326 * height is the maximum of all the components' preferred heights.
328 * @param target The container to measure.
330 * @return The preferred size.
332 public Dimension preferredLayoutSize(Container target)
334 if (target instanceof JSplitPane)
336 JSplitPane split = (JSplitPane) target;
337 Insets insets = target.getInsets();
339 int height = 0;
340 int width = 0;
341 for (int i = 0; i < components.length; i++)
343 if (components[i] == null)
344 continue;
345 Dimension dims = components[i].getPreferredSize();
346 if (dims != null)
348 width += dims.width;
349 if (!(components[i] instanceof BasicSplitPaneDivider))
350 height = Math.max(height, dims.height);
353 return new Dimension(width, height);
355 return null;
359 * This method removes the component from the layout.
361 * @param component The component to remove from the layout.
363 public void removeLayoutComponent(Component component)
365 for (int i = 0; i < components.length; i++)
367 if (component == components[i])
369 components[i] = null;
370 sizes[i] = 0;
376 * This method resets the size of Component to the preferred size.
378 * @param index The index of the component to reset.
380 protected void resetSizeAt(int index)
382 if (components[index] != null)
383 sizes[index] = getPreferredSizeOfComponent(components[index]);
387 * This method resets the sizes of all the components.
389 public void resetToPreferredSizes()
391 for (int i = 0; i < components.length; i++)
392 resetSizeAt(i);
393 setDividerLocation(splitPane,
394 getInitialLocation(splitPane.getInsets()) + sizes[0]);
398 * This methods sets the bounds of the given component. The width is the
399 * size. The height is the container size minus the top and bottom
400 * inset. The x coordinate is the location given. The y coordinate is
401 * the top inset.
403 * @param c The component to set.
404 * @param size The width of the component.
405 * @param location The x coordinate.
406 * @param insets The insets to use.
407 * @param containerSize The height of the container.
409 protected void setComponentToSize(Component c, int size, int location,
410 Insets insets, Dimension containerSize)
412 int w = size;
413 int h = containerSize.height - insets.top - insets.bottom;
414 int x = location;
415 int y = insets.top;
416 c.setBounds(x, y, w, h);
420 * This method stores the given int array as the new sizes array.
422 * @param newSizes The array to use as sizes.
424 protected void setSizes(int[] newSizes)
426 sizes = newSizes;
430 * This method determines the size of each component. It should be called
431 * when a new Layout Manager is created for an existing JSplitPane.
433 protected void updateComponents()
435 Component left = splitPane.getLeftComponent();
436 Component right = splitPane.getRightComponent();
438 if (left != null)
440 components[0] = left;
441 resetSizeAt(0);
443 if (right != null)
445 components[1] = right;
446 resetSizeAt(1);
448 components[2] = divider;
449 resetSizeAt(2);
453 * This method resizes the left and right components to fit inside the
454 * JSplitPane when there is extra space.
456 void distributeExtraSpace()
458 // FIXME: This needs to be reimplemented correctly.
462 * This method returns the minimum width of the component at the given
463 * index.
465 * @param index The index to check.
467 * @return The minimum width.
469 int minimumSizeOfComponent(int index)
471 Dimension dims = components[index].getMinimumSize();
472 if (dims != null)
473 return dims.width;
474 else
475 return 0;
477 } //end BasicHorizontalLayoutManager
480 * This class is the Layout Manager for the JSplitPane when the orientation
481 * is VERTICAL_SPLIT.
483 * @specnote Apparently this class was intended to be protected,
484 * but was made public by a compiler bug and is now
485 * public for compatibility.
487 public class BasicVerticalLayoutManager
488 extends BasicHorizontalLayoutManager
491 * This method returns the height of the container minus the top and
492 * bottom inset.
494 * @param containerSize The size of the container.
495 * @param insets The insets of the container.
497 * @return The height minus top and bottom inset.
499 protected int getAvailableSize(Dimension containerSize, Insets insets)
501 return containerSize.height - insets.top - insets.bottom;
505 * This method returns the top inset.
507 * @param insets The Insets to use.
509 * @return The top inset.
511 protected int getInitialLocation(Insets insets)
513 return insets.top;
517 * This method returns the preferred height of the component.
519 * @param c The component to measure.
521 * @return The preferred height of the component.
523 protected int getPreferredSizeOfComponent(Component c)
525 Dimension dims = c.getPreferredSize();
526 if (dims != null)
527 return dims.height;
528 return 0;
532 * This method returns the current height of the component.
534 * @param c The component to measure.
536 * @return The current height of the component.
538 protected int getSizeOfComponent(Component c)
540 return c.getHeight();
544 * This method returns the minimum layout size. The minimum height is the
545 * sum of all the components' minimum heights. The minimum width is the
546 * maximum of all the components' minimum widths.
548 * @param container The container to measure.
550 * @return The minimum size.
552 public Dimension minimumLayoutSize(Container container)
554 if (container instanceof JSplitPane)
556 JSplitPane split = (JSplitPane) container;
557 Insets insets = container.getInsets();
559 int height = 0;
560 int width = 0;
561 for (int i = 0; i < components.length; i++)
563 if (components[i] == null)
564 continue;
565 Dimension dims = components[i].getMinimumSize();
566 if (dims != null)
568 height += dims.height;
569 width = Math.max(width, dims.width);
572 return new Dimension(width, height);
574 return null;
578 * This method returns the preferred layout size. The preferred height is
579 * the sum of all the components' preferred heights. The preferred width
580 * is the maximum of all the components' preferred widths.
582 * @param container The container to measure.
584 * @return The preferred size.
586 public Dimension preferredLayoutSize(Container container)
588 if (container instanceof JSplitPane)
590 JSplitPane split = (JSplitPane) container;
591 Insets insets = container.getInsets();
593 int height = 0;
594 int width = 0;
595 for (int i = 0; i < components.length; i++)
597 if (components[i] == null)
598 continue;
599 Dimension dims = components[i].getPreferredSize();
600 if (dims != null)
602 height += dims.height;
603 width = Math.max(width, dims.width);
606 return new Dimension(width, height);
608 return null;
612 * This method sets the bounds of the given component. The y coordinate is
613 * the location given. The x coordinate is the left inset. The height is
614 * the size given. The width is the container size minus the left and
615 * right inset.
617 * @param c The component to set bounds for.
618 * @param size The height.
619 * @param location The y coordinate.
620 * @param insets The insets to use.
621 * @param containerSize The container's size.
623 protected void setComponentToSize(Component c, int size, int location,
624 Insets insets, Dimension containerSize)
626 int y = location;
627 int x = insets.left;
628 int h = size;
629 int w = containerSize.width - insets.left - insets.right;
630 c.setBounds(x, y, w, h);
634 * This method returns the minimum height of the component at the given
635 * index.
637 * @param index The index of the component to check.
639 * @return The minimum height of the given component.
641 int minimumSizeOfComponent(int index)
643 Dimension dims = components[index].getMinimumSize();
644 if (dims != null)
645 return dims.height;
646 else
647 return 0;
652 * This class handles FocusEvents from the JComponent.
654 * @specnote Apparently this class was intended to be protected,
655 * but was made public by a compiler bug and is now
656 * public for compatibility.
658 public class FocusHandler extends FocusAdapter
661 * This method is called when the JSplitPane gains focus.
663 * @param ev The FocusEvent.
665 public void focusGained(FocusEvent ev)
667 // FIXME: implement.
671 * This method is called when the JSplitPane loses focus.
673 * @param ev The FocusEvent.
675 public void focusLost(FocusEvent ev)
677 // FIXME: implement.
682 * This is a deprecated class. It is supposed to be used for handling down
683 * and right key presses.
685 * @specnote Apparently this class was intended to be protected,
686 * but was made public by a compiler bug and is now
687 * public for compatibility.
689 public class KeyboardDownRightHandler implements ActionListener
692 * This method is called when the down or right keys are pressed.
694 * @param ev The ActionEvent
696 public void actionPerformed(ActionEvent ev)
698 // FIXME: implement.
703 * This is a deprecated class. It is supposed to be used for handling end
704 * key presses.
706 * @specnote Apparently this class was intended to be protected,
707 * but was made public by a compiler bug and is now
708 * public for compatibility.
710 public class KeyboardEndHandler implements ActionListener
713 * This method is called when the end key is pressed.
715 * @param ev The ActionEvent.
717 public void actionPerformed(ActionEvent ev)
719 // FIXME: implement.
724 * This is a deprecated class. It is supposed to be used for handling home
725 * key presses.
727 * @specnote Apparently this class was intended to be protected,
728 * but was made public by a compiler bug and is now
729 * public for compatibility.
731 public class KeyboardHomeHandler implements ActionListener
734 * This method is called when the home key is pressed.
736 * @param ev The ActionEvent.
738 public void actionPerformed(ActionEvent ev)
740 // FIXME: implement.
745 * This is a deprecated class. It is supposed to be used for handling resize
746 * toggles.
748 * @specnote Apparently this class was intended to be protected,
749 * but was made public by a compiler bug and is now
750 * public for compatibility.
752 public class KeyboardResizeToggleHandler implements ActionListener
755 * This method is called when a resize is toggled.
757 * @param ev The ActionEvent.
759 public void actionPerformed(ActionEvent ev)
761 // FIXME: implement.
766 * This is a deprecated class. It is supposed to be used for handler up and
767 * left key presses.
769 * @specnote Apparently this class was intended to be protected,
770 * but was made public by a compiler bug and is now
771 * public for compatibility.
773 public class KeyboardUpLeftHandler implements ActionListener
776 * This method is called when the left or up keys are pressed.
778 * @param ev The ActionEvent.
780 public void actionPerformed(ActionEvent ev)
782 // FIXME: implement.
787 * This helper class handles PropertyChangeEvents from the JSplitPane. When
788 * a property changes, this will update the UI accordingly.
790 * @specnote Apparently this class was intended to be protected,
791 * but was made public by a compiler bug and is now
792 * public for compatibility.
794 public class PropertyHandler implements PropertyChangeListener
797 * This method is called whenever one of the JSplitPane's properties
798 * change.
800 * @param e DOCUMENT ME!
802 public void propertyChange(PropertyChangeEvent e)
804 if (e.getPropertyName().equals(JSplitPane.DIVIDER_SIZE_PROPERTY))
806 int newSize = splitPane.getDividerSize();
807 int[] tmpSizes = layoutManager.getSizes();
808 dividerSize = tmpSizes[2];
809 int newSpace = newSize - tmpSizes[2];
810 tmpSizes[2] = newSize;
812 tmpSizes[0] += newSpace / 2;
813 tmpSizes[1] += newSpace / 2;
815 layoutManager.setSizes(tmpSizes);
817 else if (e.getPropertyName().equals(JSplitPane.ORIENTATION_PROPERTY))
819 int max = layoutManager.getAvailableSize(splitPane.getSize(),
820 splitPane.getInsets());
821 int dividerLoc = getDividerLocation(splitPane);
822 double prop = ((double) dividerLoc) / max;
824 resetLayoutManager();
825 if (prop <= 1 && prop >= 0)
826 splitPane.setDividerLocation(prop);
828 // Don't have to deal with continuous_layout - only
829 // necessary in dragging modes (and it's checked
830 // every time you drag there)
831 // Don't have to deal with resize_weight (as there
832 // will be no extra space associated with this
833 // event - the changes to the weighting will
834 // be taken into account the next time the
835 // sizes change.)
836 // Don't have to deal with divider_location
837 // The method in JSplitPane calls our setDividerLocation
838 // so we'll know about those anyway.
839 // Don't have to deal with last_divider_location
840 // Although I'm not sure why, it doesn't seem to
841 // have any effect on Sun's JSplitPane.
842 // one_touch_expandable changes are dealt with
843 // by our divider.
847 /** The location of the divider when dragging began. */
848 protected int beginDragDividerLocation;
850 /** The size of the divider while dragging. */
851 protected int dividerSize;
853 /** The location where the last drag location ended. */
854 transient int lastDragLocation = -1;
856 /** The distance the divider is moved when moved by keyboard actions. */
857 // Sun defines this as 3
858 protected static int KEYBOARD_DIVIDER_MOVE_OFFSET = 3;
860 /** The divider that divides this JSplitPane. */
861 protected BasicSplitPaneDivider divider;
863 /** The listener that listens for PropertyChangeEvents from the JSplitPane. */
864 protected PropertyChangeListener propertyChangeListener;
866 /** The JSplitPane's focus handler. */
867 protected FocusListener focusListener;
869 /** @deprecated The handler for down and right key presses. */
870 protected ActionListener keyboardDownRightListener;
872 /** @deprecated The handler for end key presses. */
873 protected ActionListener keyboardEndListener;
875 /** @deprecated The handler for home key presses. */
876 protected ActionListener keyboardHomeListener;
878 /** @deprecated The handler for toggling resizes. */
879 protected ActionListener keyboardResizeToggleListener;
881 /** @deprecated The handler for up and left key presses. */
882 protected ActionListener keyboardUpLeftListener;
884 /** The JSplitPane's current layout manager. */
885 protected BasicHorizontalLayoutManager layoutManager;
887 /** @deprecated The divider resize toggle key. */
888 protected KeyStroke dividerResizeToggleKey;
890 /** @deprecated The down key. */
891 protected KeyStroke downKey;
893 /** @deprecated The end key. */
894 protected KeyStroke endKey;
896 /** @deprecated The home key. */
897 protected KeyStroke homeKey;
899 /** @deprecated The left key. */
900 protected KeyStroke leftKey;
902 /** @deprecated The right key. */
903 protected KeyStroke rightKey;
905 /** @deprecated The up key. */
906 protected KeyStroke upKey;
908 /** Set to true when dragging heavy weight components. */
909 protected boolean draggingHW;
912 * The constraints object used when adding the non-continuous divider to the
913 * JSplitPane.
915 protected static final String NON_CONTINUOUS_DIVIDER
916 = "nonContinuousDivider";
918 /** The dark divider used when dragging in non-continuous layout mode. */
919 protected Component nonContinuousLayoutDivider;
921 /** The JSplitPane that this UI draws. */
922 protected JSplitPane splitPane;
924 private int dividerLocation;
927 * Creates a new BasicSplitPaneUI object.
929 public BasicSplitPaneUI()
931 // Nothing to do here.
935 * This method creates a new BasicSplitPaneUI for the given JComponent.
937 * @param x The JComponent to create a UI for.
939 * @return A new BasicSplitPaneUI.
941 public static ComponentUI createUI(JComponent x)
943 return new BasicSplitPaneUI();
947 * This method installs the BasicSplitPaneUI for the given JComponent.
949 * @param c The JComponent to install the UI for.
951 public void installUI(JComponent c)
953 if (c instanceof JSplitPane)
955 splitPane = (JSplitPane) c;
956 installDefaults();
957 installListeners();
958 installKeyboardActions();
963 * This method uninstalls the BasicSplitPaneUI for the given JComponent.
965 * @param c The JComponent to uninstall the UI for.
967 public void uninstallUI(JComponent c)
969 uninstallKeyboardActions();
970 uninstallListeners();
971 uninstallDefaults();
973 splitPane = null;
977 * This method installs the defaults given by the Look and Feel.
979 protected void installDefaults()
981 LookAndFeel.installColors(splitPane, "SplitPane.background",
982 "SplitPane.foreground");
983 LookAndFeel.installBorder(splitPane, "SplitPane.border");
984 divider = createDefaultDivider();
985 divider.setBorder(UIManager.getBorder("SplitPaneDivider.border"));
986 resetLayoutManager();
987 nonContinuousLayoutDivider = createDefaultNonContinuousLayoutDivider();
988 splitPane.add(divider, JSplitPane.DIVIDER);
990 // There is no need to add the nonContinuousLayoutDivider
991 splitPane.setDividerSize(UIManager.getInt("SplitPane.dividerSize"));
992 splitPane.setOpaque(true);
996 * This method uninstalls the defaults and nulls any objects created during
997 * install.
999 protected void uninstallDefaults()
1001 layoutManager = null;
1002 splitPane.remove(divider);
1003 divider = null;
1004 nonContinuousLayoutDivider = null;
1006 if (splitPane.getBackground() instanceof UIResource)
1007 splitPane.setBackground(null);
1008 if (splitPane.getBorder() instanceof UIResource)
1009 splitPane.setBorder(null);
1013 * This method installs the listeners needed for this UI to function.
1015 protected void installListeners()
1017 propertyChangeListener = createPropertyChangeListener();
1018 focusListener = createFocusListener();
1020 splitPane.addPropertyChangeListener(propertyChangeListener);
1021 splitPane.addFocusListener(focusListener);
1025 * This method uninstalls all listeners registered for the UI.
1027 protected void uninstallListeners()
1029 splitPane.removePropertyChangeListener(propertyChangeListener);
1030 splitPane.removeFocusListener(focusListener);
1032 focusListener = null;
1033 propertyChangeListener = null;
1037 * This method installs the keyboard actions for the JSplitPane.
1039 protected void installKeyboardActions()
1041 // FIXME: implement.
1045 * This method reverses the work done in installKeyboardActions.
1047 protected void uninstallKeyboardActions()
1049 // FIXME: implement.
1053 * This method creates a new PropertyChangeListener.
1055 * @return A new PropertyChangeListener.
1057 protected PropertyChangeListener createPropertyChangeListener()
1059 return new PropertyHandler();
1063 * This method creates a new FocusListener.
1065 * @return A new FocusListener.
1067 protected FocusListener createFocusListener()
1069 return new FocusHandler();
1073 * This method creates a new ActionListener for up and left key presses.
1075 * @return A new ActionListener for up and left keys.
1077 * @deprecated 1.3
1079 protected ActionListener createKeyboardUpLeftListener()
1081 return new KeyboardUpLeftHandler();
1085 * This method creates a new ActionListener for down and right key presses.
1087 * @return A new ActionListener for down and right keys.
1089 * @deprecated 1.3
1091 protected ActionListener createKeyboardDownRightListener()
1093 return new KeyboardDownRightHandler();
1097 * This method creates a new ActionListener for home key presses.
1099 * @return A new ActionListener for home keys.
1101 * @deprecated
1103 protected ActionListener createKeyboardHomeListener()
1105 return new KeyboardHomeHandler();
1109 * This method creates a new ActionListener for end key presses.i
1111 * @return A new ActionListener for end keys.
1113 * @deprecated 1.3
1115 protected ActionListener createKeyboardEndListener()
1117 return new KeyboardEndHandler();
1121 * This method creates a new ActionListener for resize toggle key events.
1123 * @return A new ActionListener for resize toggle keys.
1125 * @deprecated 1.3
1127 protected ActionListener createKeyboardResizeToggleListener()
1129 return new KeyboardResizeToggleHandler();
1133 * This method returns the orientation of the JSplitPane.
1135 * @return The orientation of the JSplitPane.
1137 public int getOrientation()
1139 return splitPane.getOrientation();
1143 * This method sets the orientation of the JSplitPane.
1145 * @param orientation The new orientation of the JSplitPane.
1147 public void setOrientation(int orientation)
1149 splitPane.setOrientation(orientation);
1153 * This method returns true if the JSplitPane is using continuous layout.
1155 * @return True if the JSplitPane is using continuous layout.
1157 public boolean isContinuousLayout()
1159 return splitPane.isContinuousLayout();
1163 * This method sets the continuous layout property of the JSplitPane.
1165 * @param b True if the JsplitPane is to use continuous layout.
1167 public void setContinuousLayout(boolean b)
1169 splitPane.setContinuousLayout(b);
1173 * This method returns the last location the divider was dragged to.
1175 * @return The last location the divider was dragged to.
1177 public int getLastDragLocation()
1179 return lastDragLocation;
1183 * This method sets the last location the divider was dragged to.
1185 * @param l The last location the divider was dragged to.
1187 public void setLastDragLocation(int l)
1189 lastDragLocation = l;
1193 * This method returns the BasicSplitPaneDivider that divides this
1194 * JSplitPane.
1196 * @return The divider for the JSplitPane.
1198 public BasicSplitPaneDivider getDivider()
1200 return divider;
1204 * This method creates a nonContinuousLayoutDivider for use with the
1205 * JSplitPane in nonContinousLayout mode. The default divider is a gray
1206 * Canvas.
1208 * @return The default nonContinousLayoutDivider.
1210 protected Component createDefaultNonContinuousLayoutDivider()
1212 if (nonContinuousLayoutDivider == null)
1214 nonContinuousLayoutDivider = new Canvas();
1215 Color c = UIManager.getColor("SplitPaneDivider.draggingColor");
1216 nonContinuousLayoutDivider.setBackground(c);
1218 return nonContinuousLayoutDivider;
1222 * This method sets the component to use as the nonContinuousLayoutDivider.
1224 * @param newDivider The component to use as the nonContinuousLayoutDivider.
1226 protected void setNonContinuousLayoutDivider(Component newDivider)
1228 setNonContinuousLayoutDivider(newDivider, true);
1232 * This method sets the component to use as the nonContinuousLayoutDivider.
1234 * @param newDivider The component to use as the nonContinuousLayoutDivider.
1235 * @param rememberSizes FIXME: document.
1237 protected void setNonContinuousLayoutDivider(Component newDivider,
1238 boolean rememberSizes)
1240 // FIXME: use rememberSizes for something
1241 nonContinuousLayoutDivider = newDivider;
1245 * This method returns the nonContinuousLayoutDivider.
1247 * @return The nonContinuousLayoutDivider.
1249 public Component getNonContinuousLayoutDivider()
1251 return nonContinuousLayoutDivider;
1255 * This method returns the JSplitPane that this BasicSplitPaneUI draws.
1257 * @return The JSplitPane.
1259 public JSplitPane getSplitPane()
1261 return splitPane;
1265 * This method creates the divider used normally with the JSplitPane.
1267 * @return The default divider.
1269 public BasicSplitPaneDivider createDefaultDivider()
1271 if (divider == null)
1272 divider = new BasicSplitPaneDivider(this);
1273 return divider;
1277 * This method is called when JSplitPane's resetToPreferredSizes is called.
1278 * It resets the sizes of all components in the JSplitPane.
1280 * @param jc The JSplitPane to reset.
1282 public void resetToPreferredSizes(JSplitPane jc)
1284 layoutManager.resetToPreferredSizes();
1288 * This method sets the location of the divider.
1290 * @param jc The JSplitPane to set the divider location in.
1291 * @param location The new location of the divider.
1293 public void setDividerLocation(JSplitPane jc, int location)
1295 dividerLocation = location;
1296 splitPane.revalidate();
1297 splitPane.repaint();
1301 * This method returns the location of the divider.
1303 * @param jc The JSplitPane to retrieve the location for.
1305 * @return The location of the divider.
1307 public int getDividerLocation(JSplitPane jc)
1309 return dividerLocation;
1313 * This method returns the smallest value possible for the location of the
1314 * divider.
1316 * @param jc The JSplitPane.
1318 * @return The minimum divider location.
1320 public int getMinimumDividerLocation(JSplitPane jc)
1322 int value = layoutManager.getInitialLocation(jc.getInsets());
1323 if (layoutManager.components[0] != null)
1324 value += layoutManager.minimumSizeOfComponent(0);
1325 return value;
1329 * This method returns the largest value possible for the location of the
1330 * divider.
1332 * @param jc The JSplitPane.
1334 * @return The maximum divider location.
1336 public int getMaximumDividerLocation(JSplitPane jc)
1338 int value = layoutManager.getInitialLocation(jc.getInsets())
1339 + layoutManager.getAvailableSize(jc.getSize(), jc.getInsets())
1340 - splitPane.getDividerSize();
1341 if (layoutManager.components[1] != null)
1342 value -= layoutManager.minimumSizeOfComponent(1);
1343 return value;
1347 * This method is called after the children of the JSplitPane are painted.
1349 * @param jc The JSplitPane.
1350 * @param g The Graphics object to paint with.
1352 public void finishedPaintingChildren(JSplitPane jc, Graphics g)
1354 if (! splitPane.isContinuousLayout() && nonContinuousLayoutDivider != null
1355 && nonContinuousLayoutDivider.isVisible())
1356 javax.swing.SwingUtilities.paintComponent(g, nonContinuousLayoutDivider,
1357 null,
1358 nonContinuousLayoutDivider
1359 .getBounds());
1363 * This method is called to paint the JSplitPane.
1365 * @param g The Graphics object to paint with.
1366 * @param jc The JSplitPane to paint.
1368 public void paint(Graphics g, JComponent jc)
1370 // TODO: What should be done here?
1374 * This method returns the preferred size of the JSplitPane.
1376 * @param jc The JSplitPane.
1378 * @return The preferred size of the JSplitPane.
1380 public Dimension getPreferredSize(JComponent jc)
1382 return layoutManager.preferredLayoutSize((Container) jc);
1386 * This method returns the minimum size of the JSplitPane.
1388 * @param jc The JSplitPane.
1390 * @return The minimum size of the JSplitPane.
1392 public Dimension getMinimumSize(JComponent jc)
1394 return layoutManager.minimumLayoutSize((Container) jc);
1398 * This method returns the maximum size of the JSplitPane.
1400 * @param jc The JSplitPane.
1402 * @return The maximum size of the JSplitPane.
1404 public Dimension getMaximumSize(JComponent jc)
1406 return layoutManager.maximumLayoutSize((Container) jc);
1410 * This method returns the border insets of the current border.
1412 * @param jc The JSplitPane.
1414 * @return The current border insets.
1416 public Insets getInsets(JComponent jc)
1418 return splitPane.getBorder().getBorderInsets(splitPane);
1422 * This method resets the current layout manager. The type of layout manager
1423 * is dependent on the current orientation.
1425 protected void resetLayoutManager()
1427 if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT)
1428 layoutManager = new BasicHorizontalLayoutManager();
1429 else
1430 layoutManager = new BasicVerticalLayoutManager();
1431 getSplitPane().setLayout(layoutManager);
1432 layoutManager.updateComponents();
1434 // invalidating by itself does not invalidate the layout.
1435 getSplitPane().revalidate();
1439 * This method is called when dragging starts. It resets lastDragLocation
1440 * and dividerSize.
1442 protected void startDragging()
1444 Component left = splitPane.getLeftComponent();
1445 Component right = splitPane.getRightComponent();
1446 dividerSize = divider.getDividerSize();
1447 setLastDragLocation(-1);
1449 if ((left != null && !left.isLightweight())
1450 || (right != null && !right.isLightweight()))
1451 draggingHW = true;
1453 if (splitPane.isContinuousLayout())
1454 nonContinuousLayoutDivider.setVisible(false);
1455 else
1457 nonContinuousLayoutDivider.setVisible(true);
1458 nonContinuousLayoutDivider.setBounds(divider.getBounds());
1463 * This method is called whenever the divider is dragged. If the JSplitPane
1464 * is in continuousLayout mode, the divider needs to be moved and the
1465 * JSplitPane needs to be laid out.
1467 * @param location The new location of the divider.
1469 protected void dragDividerTo(int location)
1471 location = validLocation(location);
1472 if (beginDragDividerLocation == -1)
1473 beginDragDividerLocation = location;
1475 if (splitPane.isContinuousLayout())
1476 splitPane.setDividerLocation(location);
1477 else
1479 Point p = nonContinuousLayoutDivider.getLocation();
1480 if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT)
1481 p.x = location;
1482 else
1483 p.y = location;
1484 nonContinuousLayoutDivider.setLocation(p);
1486 setLastDragLocation(location);
1487 splitPane.repaint();
1491 * This method is called when the dragging is finished.
1493 * @param location The location where the drag finished.
1495 protected void finishDraggingTo(int location)
1497 if (nonContinuousLayoutDivider != null)
1498 nonContinuousLayoutDivider.setVisible(false);
1499 draggingHW = false;
1500 location = validLocation(location);
1501 splitPane.setDividerLocation(location);
1502 splitPane.setLastDividerLocation(beginDragDividerLocation);
1503 beginDragDividerLocation = -1;
1507 * This method returns the width of one of the sides of the divider's border.
1509 * @return The width of one side of the divider's border.
1511 * @deprecated 1.3
1513 protected int getDividerBorderSize()
1515 if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT)
1516 return divider.getBorder().getBorderInsets(divider).left;
1517 else
1518 return divider.getBorder().getBorderInsets(divider).top;
1522 * This is a helper method that returns a valid location for the divider
1523 * when dragging.
1525 * @param location The location to check.
1527 * @return A valid location.
1529 private int validLocation(int location)
1531 int min = getMinimumDividerLocation(splitPane);
1532 int max = getMaximumDividerLocation(splitPane);
1533 if (min > 0 && location < min)
1534 return min;
1535 if (max > 0 && location > max)
1536 return max;
1537 return location;