1 /*
   2  * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package javax.swing;
  26 
  27 import javax.swing.plaf.*;
  28 import javax.accessibility.*;
  29 
  30 import java.beans.JavaBean;
  31 import java.beans.BeanProperty;
  32 import java.io.ObjectOutputStream;
  33 import java.io.IOException;
  34 
  35 /**
  36  * <code>JSeparator</code> provides a general purpose component for
  37  * implementing divider lines - most commonly used as a divider
  38  * between menu items that breaks them up into logical groupings.
  39  * Instead of using <code>JSeparator</code> directly,
  40  * you can use the <code>JMenu</code> or <code>JPopupMenu</code>
  41  * <code>addSeparator</code> method to create and add a separator.
  42  * <code>JSeparator</code>s may also be used elsewhere in a GUI
  43  * wherever a visual divider is useful.
  44  *
  45  * <p>
  46  *
  47  * For more information and examples see
  48  * <a
  49  href="https://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>,
  50  * a section in <em>The Java Tutorial.</em>
  51  * <p>
  52  * <strong>Warning:</strong> Swing is not thread safe. For more
  53  * information see <a
  54  * href="package-summary.html#threading">Swing's Threading
  55  * Policy</a>.
  56  * <p>
  57  * <strong>Warning:</strong>
  58  * Serialized objects of this class will not be compatible with
  59  * future Swing releases. The current serialization support is
  60  * appropriate for short term storage or RMI between applications running
  61  * the same version of Swing.  As of 1.4, support for long term storage
  62  * of all JavaBeans&trade;
  63  * has been added to the <code>java.beans</code> package.
  64  * Please see {@link java.beans.XMLEncoder}.
  65  *
  66  * @author Georges Saab
  67  * @author Jeff Shapiro
  68  * @since 1.2
  69  */
  70 @JavaBean(defaultProperty = "UI", description = "A divider between menu items.")
  71 @SwingContainer(false)
  72 @SuppressWarnings("serial")
  73 public class JSeparator extends JComponent implements SwingConstants, Accessible
  74 {
  75     /**
  76      * @see #getUIClassID
  77      * @see #readObject
  78      */
  79     private static final String uiClassID = "SeparatorUI";
  80 
  81     private int orientation = HORIZONTAL;
  82 
  83     /** Creates a new horizontal separator. */
  84     public JSeparator()
  85     {
  86         this( HORIZONTAL );
  87     }
  88 
  89     /**
  90      * Creates a new separator with the specified horizontal or
  91      * vertical orientation.
  92      *
  93      * @param orientation an integer specifying
  94      *          <code>SwingConstants.HORIZONTAL</code> or
  95      *          <code>SwingConstants.VERTICAL</code>
  96      * @exception IllegalArgumentException if <code>orientation</code>
  97      *          is neither <code>SwingConstants.HORIZONTAL</code> nor
  98      *          <code>SwingConstants.VERTICAL</code>
  99      */
 100     public JSeparator( int orientation )
 101     {
 102         checkOrientation( orientation );
 103         this.orientation = orientation;
 104         setFocusable(false);
 105         updateUI();
 106     }
 107 
 108     /**
 109      * Returns the L&amp;F object that renders this component.
 110      *
 111      * @return the SeparatorUI object that renders this component
 112      */
 113     public SeparatorUI getUI() {
 114         return (SeparatorUI)ui;
 115     }
 116 
 117     /**
 118      * Sets the L&amp;F object that renders this component.
 119      *
 120      * @param ui  the SeparatorUI L&amp;F object
 121      * @see UIDefaults#getUI
 122      */
 123     @BeanProperty(hidden = true, visualUpdate = true, description
 124             = "The UI object that implements the Component's LookAndFeel.")
 125     public void setUI(SeparatorUI ui) {
 126         super.setUI(ui);
 127     }
 128 
 129     /**
 130      * Resets the UI property to a value from the current look and feel.
 131      *
 132      * @see JComponent#updateUI
 133      */
 134     public void updateUI() {
 135         setUI((SeparatorUI)UIManager.getUI(this));
 136     }
 137 
 138 
 139     /**
 140      * Returns the name of the L&amp;F class that renders this component.
 141      *
 142      * @return the string "SeparatorUI"
 143      * @see JComponent#getUIClassID
 144      * @see UIDefaults#getUI
 145      */
 146     @BeanProperty(bound = false)
 147     public String getUIClassID() {
 148         return uiClassID;
 149     }
 150 
 151 
 152     /**
 153      * See <code>readObject</code> and <code>writeObject</code> in
 154      * <code>JComponent</code> for more
 155      * information about serialization in Swing.
 156      */
 157     private void writeObject(ObjectOutputStream s) throws IOException {
 158         s.defaultWriteObject();
 159         if (getUIClassID().equals(uiClassID)) {
 160             byte count = JComponent.getWriteObjCounter(this);
 161             JComponent.setWriteObjCounter(this, --count);
 162             if (count == 0 && ui != null) {
 163                 ui.installUI(this);
 164             }
 165         }
 166     }
 167 
 168     /**
 169      * Returns the orientation of this separator.
 170      *
 171      * @return   The value of the orientation property, one of the
 172      *           following constants defined in <code>SwingConstants</code>:
 173      *           <code>VERTICAL</code>, or
 174      *           <code>HORIZONTAL</code>.
 175      *
 176      * @see SwingConstants
 177      * @see #setOrientation
 178      */
 179     public int getOrientation() {
 180         return this.orientation;
 181     }
 182 
 183     /**
 184      * Sets the orientation of the separator.
 185      * The default value of this property is HORIZONTAL.
 186      * @param orientation  either <code>SwingConstants.HORIZONTAL</code>
 187      *                  or <code>SwingConstants.VERTICAL</code>
 188      * @exception IllegalArgumentException  if <code>orientation</code>
 189      *          is neither <code>SwingConstants.HORIZONTAL</code>
 190      *          nor <code>SwingConstants.VERTICAL</code>
 191      *
 192      * @see SwingConstants
 193      * @see #getOrientation
 194      */
 195     @BeanProperty(preferred = true, visualUpdate = true, enumerationValues = {
 196             "SwingConstants.HORIZONTAL",
 197             "SwingConstants.VERTICAL"}, description
 198             = "The orientation of the separator.")
 199     public void setOrientation( int orientation ) {
 200         if (this.orientation == orientation) {
 201             return;
 202         }
 203         int oldValue = this.orientation;
 204         checkOrientation( orientation );
 205         this.orientation = orientation;
 206         firePropertyChange("orientation", oldValue, orientation);
 207         revalidate();
 208         repaint();
 209     }
 210 
 211     private void checkOrientation( int orientation )
 212     {
 213         switch ( orientation )
 214         {
 215             case VERTICAL:
 216             case HORIZONTAL:
 217                 break;
 218             default:
 219                 throw new IllegalArgumentException( "orientation must be one of: VERTICAL, HORIZONTAL" );
 220         }
 221     }
 222 
 223 
 224     /**
 225      * Returns a string representation of this <code>JSeparator</code>.
 226      * This method
 227      * is intended to be used only for debugging purposes, and the
 228      * content and format of the returned string may vary between
 229      * implementations. The returned string may be empty but may not
 230      * be <code>null</code>.
 231      *
 232      * @return  a string representation of this <code>JSeparator</code>
 233      */
 234     protected String paramString() {
 235         String orientationString = (orientation == HORIZONTAL ?
 236                                     "HORIZONTAL" : "VERTICAL");
 237 
 238         return super.paramString() +
 239         ",orientation=" + orientationString;
 240     }
 241 
 242 /////////////////
 243 // Accessibility support
 244 ////////////////
 245 
 246     /**
 247      * Gets the AccessibleContext associated with this JSeparator.
 248      * For separators, the AccessibleContext takes the form of an
 249      * AccessibleJSeparator.
 250      * A new AccessibleJSeparator instance is created if necessary.
 251      *
 252      * @return an AccessibleJSeparator that serves as the
 253      *         AccessibleContext of this JSeparator
 254      */
 255     @BeanProperty(bound = false)
 256     public AccessibleContext getAccessibleContext() {
 257         if (accessibleContext == null) {
 258             accessibleContext = new AccessibleJSeparator();
 259         }
 260         return accessibleContext;
 261     }
 262 
 263     /**
 264      * This class implements accessibility support for the
 265      * <code>JSeparator</code> class.  It provides an implementation of the
 266      * Java Accessibility API appropriate to separator user-interface elements.
 267      * <p>
 268      * <strong>Warning:</strong>
 269      * Serialized objects of this class will not be compatible with
 270      * future Swing releases. The current serialization support is
 271      * appropriate for short term storage or RMI between applications running
 272      * the same version of Swing.  As of 1.4, support for long term storage
 273      * of all JavaBeans&trade;
 274      * has been added to the <code>java.beans</code> package.
 275      * Please see {@link java.beans.XMLEncoder}.
 276      */
 277     @SuppressWarnings("serial")
 278     protected class AccessibleJSeparator extends AccessibleJComponent {
 279 
 280         /**
 281          * Get the role of this object.
 282          *
 283          * @return an instance of AccessibleRole describing the role of the
 284          * object
 285          */
 286         public AccessibleRole getAccessibleRole() {
 287             return AccessibleRole.SEPARATOR;
 288         }
 289     }
 290 }