mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-19 18:07:49 +00:00
Merge
This commit is contained in:
commit
093ffa46b3
@ -48,7 +48,7 @@ public final class BeanInfoFinder
|
||||
}
|
||||
|
||||
private static boolean isValid(Class<?> type, Method method) {
|
||||
return (method != null) && type.equals(method.getDeclaringClass());
|
||||
return (method != null) && method.getDeclaringClass().isAssignableFrom(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -38,7 +38,7 @@ import java.util.Locale;
|
||||
* a character's category (lowercase letter, digit, etc.) and for converting
|
||||
* characters from uppercase to lowercase and vice versa.
|
||||
* <p>
|
||||
* Character information is based on the Unicode Standard, version 4.0.
|
||||
* Character information is based on the Unicode Standard, version 5.1.0.
|
||||
* <p>
|
||||
* The methods and data of class <code>Character</code> are defined by
|
||||
* the information in the <i>UnicodeData</i> file that is part of the
|
||||
|
||||
788
jdk/src/share/classes/javax/swing/JLayer.java
Normal file
788
jdk/src/share/classes/javax/swing/JLayer.java
Normal file
@ -0,0 +1,788 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
|
||||
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package javax.swing;
|
||||
|
||||
import javax.swing.plaf.LayerUI;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* {@code JLayer} is a universal decorator for Swing components
|
||||
* which enables you to implement various advanced painting effects as well as
|
||||
* receive notifications of all {@code AWTEvent}s generated within its borders.
|
||||
* <p/>
|
||||
* {@code JLayer} delegates the handling of painting and input events to a
|
||||
* {@link javax.swing.plaf.LayerUI} object, which performs the actual decoration.
|
||||
* <p/>
|
||||
* The custom painting implemented in the {@code LayerUI} and events notification
|
||||
* work for the JLayer itself and all its subcomponents.
|
||||
* This combination enables you to enrich existing components
|
||||
* by adding new advanced functionality such as temporary locking of a hierarchy,
|
||||
* data tips for compound components, enhanced mouse scrolling etc and so on.
|
||||
* <p/>
|
||||
* {@code JLayer} is a good solution if you only need to do custom painting
|
||||
* over compound component or catch input events from its subcomponents.
|
||||
* <pre>
|
||||
* // create a component to be decorated with the layer
|
||||
* JPanel panel = new JPanel();
|
||||
* panel.add(new JButton("JButton"));
|
||||
* // This custom layerUI will fill the layer with translucent green
|
||||
* // and print out all mouseMotion events generated within its borders
|
||||
* LayerUI<JPanel> layerUI = new LayerUI<JPanel>() {
|
||||
* public void paint(Graphics g, JCompo nent c) {
|
||||
* // paint the layer as is
|
||||
* super.paint(g, c);
|
||||
* // fill it with the translucent green
|
||||
* g.setColor(new Color(0, 128, 0, 128));
|
||||
* g.fillRect(0, 0, c.getWidth(), c.getHeight());
|
||||
* }
|
||||
* // overridden method which catches MouseMotion events
|
||||
* public void eventDispatched(AWTEvent e, JLayer<JPanel> l) {
|
||||
* System.out.println("AWTEvent detected: " + e);
|
||||
* }
|
||||
* };
|
||||
* // create the layer for the panel using our custom layerUI
|
||||
* JLayer<JPanel> layer = new JLayer<JPanel>(panel, layerUI);
|
||||
* // work with the layer as with any other Swing component
|
||||
* frame.add(layer);
|
||||
* </pre>
|
||||
*
|
||||
* <b>Note:</b> {@code JLayer} doesn't support the following methods:
|
||||
* <ul>
|
||||
* <li>{@link Container#add(java.awt.Component)}</li>
|
||||
* <li>{@link Container#add(String, java.awt.Component)}</li>
|
||||
* <li>{@link Container#add(java.awt.Component, int)}</li>
|
||||
* <li>{@link Container#add(java.awt.Component, Object)}</li>
|
||||
* <li>{@link Container#add(java.awt.Component, Object, int)}</li>
|
||||
* </ul>
|
||||
* using any of of them will cause {@code UnsupportedOperationException} to be thrown,
|
||||
* to add a component to {@code JLayer}
|
||||
* use {@link #setView(Component)} or {@link #setGlassPane(JPanel)}.
|
||||
*
|
||||
* @param <V> the type of {@code JLayer}'s view component
|
||||
*
|
||||
* @see #JLayer(Component)
|
||||
* @see #setView(Component)
|
||||
* @see #getView()
|
||||
* @see javax.swing.plaf.LayerUI
|
||||
* @see #JLayer(Component, LayerUI)
|
||||
* @see #setUI(javax.swing.plaf.LayerUI)
|
||||
* @see #getUI()
|
||||
* @since 1.7
|
||||
*
|
||||
* @author Alexander Potochkin
|
||||
*/
|
||||
public final class JLayer<V extends Component>
|
||||
extends JComponent
|
||||
implements Scrollable, PropertyChangeListener {
|
||||
private V view;
|
||||
// this field is necessary because JComponent.ui is transient
|
||||
// when layerUI is serializable
|
||||
private LayerUI<? super V> layerUI;
|
||||
private JPanel glassPane;
|
||||
private boolean isPainting;
|
||||
private static final DefaultLayerLayout sharedLayoutInstance =
|
||||
new DefaultLayerLayout();
|
||||
private long eventMask;
|
||||
|
||||
private static final LayerEventController eventController =
|
||||
new LayerEventController();
|
||||
|
||||
private static final long ACCEPTED_EVENTS =
|
||||
AWTEvent.COMPONENT_EVENT_MASK |
|
||||
AWTEvent.CONTAINER_EVENT_MASK |
|
||||
AWTEvent.FOCUS_EVENT_MASK |
|
||||
AWTEvent.KEY_EVENT_MASK |
|
||||
AWTEvent.MOUSE_WHEEL_EVENT_MASK |
|
||||
AWTEvent.MOUSE_MOTION_EVENT_MASK |
|
||||
AWTEvent.MOUSE_EVENT_MASK |
|
||||
AWTEvent.INPUT_METHOD_EVENT_MASK |
|
||||
AWTEvent.HIERARCHY_EVENT_MASK |
|
||||
AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK;
|
||||
|
||||
/**
|
||||
* Creates a new {@code JLayer} object with a {@code null} view component
|
||||
* and {@code null} {@link javax.swing.plaf.LayerUI}.
|
||||
*
|
||||
* @see #setView
|
||||
* @see #setUI
|
||||
*/
|
||||
public JLayer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@code JLayer} object
|
||||
* with {@code null} {@link javax.swing.plaf.LayerUI}.
|
||||
*
|
||||
* @param view the component to be decorated by this {@code JLayer}
|
||||
*
|
||||
* @see #setUI
|
||||
*/
|
||||
public JLayer(V view) {
|
||||
this(view, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@code JLayer} object with the specified view component
|
||||
* and {@link javax.swing.plaf.LayerUI} object.
|
||||
*
|
||||
* @param view the component to be decorated
|
||||
* @param ui the {@link javax.swing.plaf.LayerUI} delegate
|
||||
* to be used by this {@code JLayer}
|
||||
*/
|
||||
public JLayer(V view, LayerUI<V> ui) {
|
||||
setLayout(sharedLayoutInstance);
|
||||
setGlassPane(createGlassPane());
|
||||
setView(view);
|
||||
setUI(ui);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code JLayer}'s view component or {@code null}.
|
||||
* <br/>This is a bound property.
|
||||
*
|
||||
* @return the {@code JLayer}'s view component
|
||||
* or {@code null} if none exists
|
||||
*
|
||||
* @see #setView(V)
|
||||
*/
|
||||
public V getView() {
|
||||
return view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@code JLayer}'s view component, which can be {@code null}.
|
||||
* <br/>This is a bound property.
|
||||
*
|
||||
* @param view the view component for this {@code JLayer}
|
||||
*
|
||||
* @see #getView()
|
||||
*/
|
||||
public void setView(V view) {
|
||||
Component oldView = getView();
|
||||
if (oldView != null) {
|
||||
super.remove(oldView);
|
||||
}
|
||||
if (view != null) {
|
||||
super.addImpl(view, null, getComponentCount());
|
||||
}
|
||||
this.view = view;
|
||||
firePropertyChange("view", oldView, view);
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link javax.swing.plaf.LayerUI} which will perform painting
|
||||
* and receive input events for this {@code JLayer}.
|
||||
*
|
||||
* @param ui the {@link javax.swing.plaf.LayerUI} for this {@code JLayer}
|
||||
*/
|
||||
public void setUI(LayerUI<? super V> ui) {
|
||||
this.layerUI = ui;
|
||||
super.setUI(ui);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link javax.swing.plaf.LayerUI} for this {@code JLayer}.
|
||||
*
|
||||
* @return the {@code LayerUI} for this {@code JLayer}
|
||||
*/
|
||||
public LayerUI<? super V> getUI() {
|
||||
return layerUI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code JLayer}'s glassPane component or {@code null}.
|
||||
* <br/>This is a bound property.
|
||||
*
|
||||
* @return the {@code JLayer}'s glassPane component
|
||||
* or {@code null} if none exists
|
||||
*
|
||||
* @see #setGlassPane(JPanel)
|
||||
*/
|
||||
public JPanel getGlassPane() {
|
||||
return glassPane;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@code JLayer}'s glassPane component, which can be {@code null}.
|
||||
* <br/>This is a bound property.
|
||||
*
|
||||
* @param glassPane the glassPane component of this {@code JLayer}
|
||||
*
|
||||
* @see #getGlassPane()
|
||||
*/
|
||||
public void setGlassPane(JPanel glassPane) {
|
||||
Component oldGlassPane = getGlassPane();
|
||||
if (oldGlassPane != null) {
|
||||
super.remove(oldGlassPane);
|
||||
}
|
||||
if (glassPane != null) {
|
||||
super.addImpl(glassPane, null, 0);
|
||||
}
|
||||
this.glassPane = glassPane;
|
||||
firePropertyChange("glassPane", oldGlassPane, glassPane);
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the constructor methods to create a default {@code glassPane}.
|
||||
* By default this method creates a new JPanel with visibility set to true
|
||||
* and opacity set to false.
|
||||
*
|
||||
* @return the default {@code glassPane}
|
||||
*/
|
||||
public JPanel createGlassPane() {
|
||||
return new DefaultLayerGlassPane();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is not supported by {@code JLayer}
|
||||
* and always throws {@code UnsupportedOperationException}
|
||||
*
|
||||
* @throws UnsupportedOperationException this method is not supported
|
||||
*
|
||||
* @see #setView(Component)
|
||||
* @see #setGlassPane(Component)
|
||||
*/
|
||||
protected void addImpl(Component comp, Object constraints, int index) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Adding components to JLayer is not supported, " +
|
||||
"use setView() or setGlassPane() instead");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void remove(Component comp) {
|
||||
if (comp == getView()) {
|
||||
setView(null);
|
||||
} else if (comp == getGlassPane()) {
|
||||
setGlassPane(null);
|
||||
} else {
|
||||
super.remove(comp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void removeAll() {
|
||||
setView(null);
|
||||
setGlassPane(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates all painting to the {@link javax.swing.plaf.LayerUI} object.
|
||||
*
|
||||
* @param g the {@code Graphics} to render to
|
||||
*/
|
||||
public void paint(Graphics g) {
|
||||
if (!isPainting) {
|
||||
isPainting = true;
|
||||
super.paintComponent(g);
|
||||
isPainting = false;
|
||||
} else {
|
||||
super.paint(g);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is empty, because all painting is done by
|
||||
* {@link #paint(Graphics)} and
|
||||
* {@link javax.swing.plaf.LayerUI#update(Graphics, JComponent)} methods
|
||||
*/
|
||||
protected void paintComponent(Graphics g) {
|
||||
}
|
||||
|
||||
/**
|
||||
* To enable the correct painting of the {@code glassPane} and view component,
|
||||
* the {@code JLayer} overrides the default implementation of
|
||||
* this method to return {@code false} when the {@code glassPane} is visible.
|
||||
*
|
||||
* @return false if {@code JLayer}'s {@code glassPane} is visible
|
||||
*/
|
||||
public boolean isOptimizedDrawingEnabled() {
|
||||
return !glassPane.isVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (getUI() != null) {
|
||||
getUI().applyPropertyChange(evt, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bitmask of event types to receive by this {@code JLayer}.
|
||||
* Here is the list of the supported event types:
|
||||
* <ul>
|
||||
* <li>AWTEvent.COMPONENT_EVENT_MASK</li>
|
||||
* <li>AWTEvent.CONTAINER_EVENT_MASK</li>
|
||||
* <li>AWTEvent.FOCUS_EVENT_MASK</li>
|
||||
* <li>AWTEvent.KEY_EVENT_MASK</li>
|
||||
* <li>AWTEvent.MOUSE_WHEEL_EVENT_MASK</li>
|
||||
* <li>AWTEvent.MOUSE_MOTION_EVENT_MASK</li>
|
||||
* <li>AWTEvent.MOUSE_EVENT_MASK</li>
|
||||
* <li>AWTEvent.INPUT_METHOD_EVENT_MASK</li>
|
||||
* <li>AWTEvent.HIERARCHY_EVENT_MASK</li>
|
||||
* <li>AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK</li>
|
||||
* </ul>
|
||||
* <p/>
|
||||
* If {@code LayerUI} is installed,
|
||||
* {@link javax.swing.plaf.LayerUI#eventDispatched(AWTEvent, JLayer)} method
|
||||
* will only receive events that match the event mask.
|
||||
* <p/>
|
||||
* The following example shows how to correclty use this method
|
||||
* in the {@code LayerUI} implementations:
|
||||
* <pre>
|
||||
* public void installUI(JComponent c) {
|
||||
* super.installUI(c);
|
||||
* JLayer l = (JLayer) c;
|
||||
* // this LayerUI will receive only key and focus events
|
||||
* l.setLayerEventMask(AWTEvent.KEY_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK);
|
||||
* }
|
||||
*
|
||||
* public void uninstallUI(JComponent c) {
|
||||
* super.uninstallUI(c);
|
||||
* JLayer l = (JLayer) c;
|
||||
* // JLayer must be returned to its initial state
|
||||
* l.setLayerEventMask(0);
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* By default {@code JLayer} receives no events.
|
||||
*
|
||||
* @param layerEventMask the bitmask of event types to receive
|
||||
*
|
||||
* @throws IllegalArgumentException if the {@code layerEventMask} parameter
|
||||
* contains unsupported event types
|
||||
* @see #getLayerEventMask()
|
||||
*/
|
||||
public void setLayerEventMask(long layerEventMask) {
|
||||
if (layerEventMask != (layerEventMask & ACCEPTED_EVENTS)) {
|
||||
throw new IllegalArgumentException(
|
||||
"The event bitmask contains unsupported event types");
|
||||
}
|
||||
long oldEventMask = getLayerEventMask();
|
||||
this.eventMask = layerEventMask;
|
||||
firePropertyChange("layerEventMask", oldEventMask, layerEventMask);
|
||||
if (layerEventMask != oldEventMask) {
|
||||
disableEvents(oldEventMask);
|
||||
enableEvents(eventMask);
|
||||
eventController.updateAWTEventListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bitmap of event mask to receive by this {@code JLayer}
|
||||
* and its {@code LayerUI}.
|
||||
* <p/>
|
||||
* It means that {@link javax.swing.plaf.LayerUI#eventDispatched(AWTEvent, JLayer)} method
|
||||
* will only receive events that match the event mask.
|
||||
* <p/>
|
||||
* By default {@code JLayer} receives no events.
|
||||
*
|
||||
* @return the bitmask of event types to receive for this {@code JLayer}
|
||||
*/
|
||||
public long getLayerEventMask() {
|
||||
return eventMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates its functionality to the {@link javax.swing.plaf.LayerUI#updateUI(JLayer)} method,
|
||||
* if {@code LayerUI} is set.
|
||||
*/
|
||||
public void updateUI() {
|
||||
if (getUI() != null) {
|
||||
getUI().updateUI(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preferred size of the viewport for a view component.
|
||||
* <p/>
|
||||
* If the ui delegate of this layer is not {@code null}, this method delegates its
|
||||
* implementation to the {@code LayerUI.getPreferredScrollableViewportSize(JLayer)}
|
||||
*
|
||||
* @return the preferred size of the viewport for a view component
|
||||
*
|
||||
* @see Scrollable
|
||||
* @see LayerUI#getPreferredScrollableViewportSize(JLayer)
|
||||
*/
|
||||
public Dimension getPreferredScrollableViewportSize() {
|
||||
if (getUI() != null) {
|
||||
return getUI().getPreferredScrollableViewportSize(this);
|
||||
}
|
||||
return getPreferredSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a scroll increment, which is required for components
|
||||
* that display logical rows or columns in order to completely expose
|
||||
* one block of rows or columns, depending on the value of orientation.
|
||||
* <p/>
|
||||
* If the ui delegate of this layer is not {@code null}, this method delegates its
|
||||
* implementation to the {@code LayerUI.getScrollableBlockIncrement(JLayer,Rectangle,int,int)}
|
||||
*
|
||||
* @return the "block" increment for scrolling in the specified direction
|
||||
*
|
||||
* @see Scrollable
|
||||
* @see LayerUI#getScrollableBlockIncrement(JLayer, Rectangle, int, int)
|
||||
*/
|
||||
public int getScrollableBlockIncrement(Rectangle visibleRect,
|
||||
int orientation, int direction) {
|
||||
if (getUI() != null) {
|
||||
return getUI().getScrollableBlockIncrement(this, visibleRect,
|
||||
orientation, direction);
|
||||
}
|
||||
return (orientation == SwingConstants.VERTICAL) ? visibleRect.height :
|
||||
visibleRect.width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code false} to indicate that the height of the viewport does not
|
||||
* determine the height of the layer, unless the preferred height
|
||||
* of the layer is smaller than the height of the viewport.
|
||||
* <p/>
|
||||
* If the ui delegate of this layer is not null, this method delegates its
|
||||
* implementation to the {@code LayerUI.getScrollableTracksViewportHeight(JLayer)}
|
||||
*
|
||||
* @return whether the layer should track the height of the viewport
|
||||
*
|
||||
* @see Scrollable
|
||||
* @see LayerUI#getScrollableTracksViewportHeight(JLayer)
|
||||
*/
|
||||
public boolean getScrollableTracksViewportHeight() {
|
||||
if (getUI() != null) {
|
||||
return getUI().getScrollableTracksViewportHeight(this);
|
||||
}
|
||||
if (getParent() instanceof JViewport) {
|
||||
return ((getParent()).getHeight() > getPreferredSize().height);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code false} to indicate that the width of the viewport does not
|
||||
* determine the width of the layer, unless the preferred width
|
||||
* of the layer is smaller than the width of the viewport.
|
||||
* <p/>
|
||||
* If the ui delegate of this layer is not null, this method delegates its
|
||||
* implementation to the {@code LayerUI.getScrollableTracksViewportWidth(JLayer)}
|
||||
*
|
||||
* @return whether the layer should track the width of the viewport
|
||||
*
|
||||
* @see Scrollable
|
||||
* @see LayerUI#getScrollableTracksViewportWidth(JLayer)
|
||||
*/
|
||||
public boolean getScrollableTracksViewportWidth() {
|
||||
if (getUI() != null) {
|
||||
return getUI().getScrollableTracksViewportWidth(this);
|
||||
}
|
||||
if (getParent() instanceof JViewport) {
|
||||
return ((getParent()).getWidth() > getPreferredSize().width);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a scroll increment, which is required for components
|
||||
* that display logical rows or columns in order to completely expose
|
||||
* one new row or column, depending on the value of orientation.
|
||||
* Ideally, components should handle a partially exposed row or column
|
||||
* by returning the distance required to completely expose the item.
|
||||
* <p/>
|
||||
* Scrolling containers, like {@code JScrollPane}, will use this method
|
||||
* each time the user requests a unit scroll.
|
||||
* <p/>
|
||||
* If the ui delegate of this layer is not {@code null}, this method delegates its
|
||||
* implementation to the {@code LayerUI.getScrollableUnitIncrement(JLayer,Rectangle,int,int)}
|
||||
*
|
||||
* @return The "unit" increment for scrolling in the specified direction.
|
||||
* This value should always be positive.
|
||||
*
|
||||
* @see Scrollable
|
||||
* @see LayerUI#getScrollableUnitIncrement(JLayer, Rectangle, int, int)
|
||||
*/
|
||||
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
|
||||
int direction) {
|
||||
if (getUI() != null) {
|
||||
return getUI().getScrollableUnitIncrement(
|
||||
this, visibleRect, orientation, direction);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
s.defaultReadObject();
|
||||
if (getUI() != null) {
|
||||
setUI(getUI());
|
||||
}
|
||||
if (getLayerEventMask() != 0) {
|
||||
eventController.updateAWTEventListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* static AWTEventListener to be shared with all AbstractLayerUIs
|
||||
*/
|
||||
private static class LayerEventController implements AWTEventListener {
|
||||
private ArrayList<WeakReference<JLayer>> layerList =
|
||||
new ArrayList<WeakReference<JLayer>>();
|
||||
|
||||
private long currentEventMask;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void eventDispatched(AWTEvent event) {
|
||||
Object source = event.getSource();
|
||||
if (source instanceof Component) {
|
||||
Component component = (Component) source;
|
||||
while (component != null) {
|
||||
if (component instanceof JLayer) {
|
||||
JLayer l = (JLayer) component;
|
||||
LayerUI ui = l.getUI();
|
||||
if (ui != null &&
|
||||
isEventEnabled(l.getLayerEventMask(),
|
||||
event.getID())) {
|
||||
ui.eventDispatched(event, l);
|
||||
}
|
||||
}
|
||||
component = component.getParent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean layerListContains(JLayer l) {
|
||||
for (WeakReference<JLayer> layerWeakReference : layerList) {
|
||||
if (layerWeakReference.get() == l) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void updateAWTEventListener(JLayer layer) {
|
||||
if (!layerListContains(layer) && layer.getLayerEventMask() != 0) {
|
||||
layerList.add(new WeakReference<JLayer>(layer));
|
||||
}
|
||||
long combinedMask = 0;
|
||||
Iterator<WeakReference<JLayer>> it = layerList.iterator();
|
||||
while (it.hasNext()) {
|
||||
WeakReference<JLayer> weakRef = it.next();
|
||||
JLayer currLayer = weakRef.get();
|
||||
if (currLayer == null) {
|
||||
it.remove();
|
||||
} else {
|
||||
combinedMask |= currLayer.getLayerEventMask();
|
||||
}
|
||||
}
|
||||
if (combinedMask == 0) {
|
||||
removeAWTEventListener();
|
||||
layerList.clear();
|
||||
} else if (getCurrentEventMask() != combinedMask) {
|
||||
removeAWTEventListener();
|
||||
addAWTEventListener(combinedMask);
|
||||
}
|
||||
}
|
||||
|
||||
private long getCurrentEventMask() {
|
||||
return currentEventMask;
|
||||
}
|
||||
|
||||
private void addAWTEventListener(final long eventMask) {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
Toolkit.getDefaultToolkit().
|
||||
addAWTEventListener(LayerEventController.this, eventMask);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
currentEventMask = eventMask;
|
||||
}
|
||||
|
||||
private void removeAWTEventListener() {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
Toolkit.getDefaultToolkit().
|
||||
removeAWTEventListener(LayerEventController.this);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
currentEventMask = 0;
|
||||
}
|
||||
|
||||
private boolean isEventEnabled(long eventMask, int id) {
|
||||
return (((eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 &&
|
||||
id >= ComponentEvent.COMPONENT_FIRST &&
|
||||
id <= ComponentEvent.COMPONENT_LAST)
|
||||
|| ((eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 &&
|
||||
id >= ContainerEvent.CONTAINER_FIRST &&
|
||||
id <= ContainerEvent.CONTAINER_LAST)
|
||||
|| ((eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0 &&
|
||||
id >= FocusEvent.FOCUS_FIRST &&
|
||||
id <= FocusEvent.FOCUS_LAST)
|
||||
|| ((eventMask & AWTEvent.KEY_EVENT_MASK) != 0 &&
|
||||
id >= KeyEvent.KEY_FIRST &&
|
||||
id <= KeyEvent.KEY_LAST)
|
||||
|| ((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0 &&
|
||||
id == MouseEvent.MOUSE_WHEEL)
|
||||
|| ((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0 &&
|
||||
(id == MouseEvent.MOUSE_MOVED ||
|
||||
id == MouseEvent.MOUSE_DRAGGED))
|
||||
|| ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0 &&
|
||||
id != MouseEvent.MOUSE_MOVED &&
|
||||
id != MouseEvent.MOUSE_DRAGGED &&
|
||||
id != MouseEvent.MOUSE_WHEEL &&
|
||||
id >= MouseEvent.MOUSE_FIRST &&
|
||||
id <= MouseEvent.MOUSE_LAST)
|
||||
|| ((eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0 &&
|
||||
id >= InputMethodEvent.INPUT_METHOD_FIRST &&
|
||||
id <= InputMethodEvent.INPUT_METHOD_LAST)
|
||||
|| ((eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 &&
|
||||
id == HierarchyEvent.HIERARCHY_CHANGED)
|
||||
|| ((eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 &&
|
||||
(id == HierarchyEvent.ANCESTOR_MOVED ||
|
||||
id == HierarchyEvent.ANCESTOR_RESIZED)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The default glassPane for the {@link javax.swing.JLayer}.
|
||||
* It is a subclass of {@code JPanel} which is non opaque by default.
|
||||
*/
|
||||
private static class DefaultLayerGlassPane extends JPanel {
|
||||
/**
|
||||
* Creates a new {@link DefaultLayerGlassPane}
|
||||
*/
|
||||
public DefaultLayerGlassPane() {
|
||||
setOpaque(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* First, implementatation of this method iterates through
|
||||
* glassPane's child components and returns {@code true}
|
||||
* if any of them is visible and contains passed x,y point.
|
||||
* After that it checks if no mouseListeners is attached to this component
|
||||
* and no mouse cursor is set, then it returns {@code false},
|
||||
* otherwise calls the super implementation of this method.
|
||||
*
|
||||
* @param x the <i>x</i> coordinate of the point
|
||||
* @param y the <i>y</i> coordinate of the point
|
||||
* @return true if this component logically contains x,y
|
||||
*/
|
||||
public boolean contains(int x, int y) {
|
||||
for (int i = 0; i < getComponentCount(); i++) {
|
||||
Component c = getComponent(i);
|
||||
Point point = SwingUtilities.convertPoint(this, new Point(x, y), c);
|
||||
if(c.isVisible() && c.contains(point)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (getMouseListeners().length == 0
|
||||
&& getMouseMotionListeners().length == 0
|
||||
&& getMouseWheelListeners().length == 0
|
||||
&& !isCursorSet()) {
|
||||
return false;
|
||||
}
|
||||
return super.contains(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The default layout manager for the {@link javax.swing.JLayer}.<br/>
|
||||
* It places the glassPane on top of the view component
|
||||
* and makes it the same size as {@code JLayer},
|
||||
* it also makes the view component the same size but minus layer's insets<br/>
|
||||
*/
|
||||
private static class DefaultLayerLayout implements LayoutManager, Serializable {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void layoutContainer(Container parent) {
|
||||
JLayer layer = (JLayer) parent;
|
||||
Component view = layer.getView();
|
||||
Component glassPane = layer.getGlassPane();
|
||||
if (view != null) {
|
||||
Insets insets = layer.getInsets();
|
||||
view.setLocation(insets.left, insets.top);
|
||||
view.setSize(layer.getWidth() - insets.left - insets.right,
|
||||
layer.getHeight() - insets.top - insets.bottom);
|
||||
}
|
||||
if (glassPane != null) {
|
||||
glassPane.setLocation(0, 0);
|
||||
glassPane.setSize(layer.getWidth(), layer.getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Dimension minimumLayoutSize(Container parent) {
|
||||
JLayer layer = (JLayer) parent;
|
||||
Insets insets = layer.getInsets();
|
||||
Dimension ret = new Dimension(insets.left + insets.right,
|
||||
insets.top + insets.bottom);
|
||||
Component view = layer.getView();
|
||||
if (view != null) {
|
||||
Dimension size = view.getMinimumSize();
|
||||
ret.width += size.width;
|
||||
ret.height += size.height;
|
||||
}
|
||||
if (ret.width == 0 || ret.height == 0) {
|
||||
ret.width = ret.height = 4;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Dimension preferredLayoutSize(Container parent) {
|
||||
JLayer layer = (JLayer) parent;
|
||||
Insets insets = layer.getInsets();
|
||||
Dimension ret = new Dimension(insets.left + insets.right,
|
||||
insets.top + insets.bottom);
|
||||
Component view = layer.getView();
|
||||
if (view != null) {
|
||||
Dimension size = view.getPreferredSize();
|
||||
if (size.width > 0 && size.height > 0) {
|
||||
ret.width += size.width;
|
||||
ret.height += size.height;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void addLayoutComponent(String name, Component comp) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void removeLayoutComponent(Component comp) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -37,6 +37,8 @@ import java.util.Vector;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
import sun.awt.shell.*;
|
||||
|
||||
@ -718,8 +720,13 @@ class WindowsFileSystemView extends FileSystemView {
|
||||
return isFileSystemRoot(dir);
|
||||
}
|
||||
|
||||
public boolean isFloppyDrive(File dir) {
|
||||
String path = dir.getAbsolutePath();
|
||||
public boolean isFloppyDrive(final File dir) {
|
||||
String path = AccessController.doPrivileged(new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return dir.getAbsolutePath();
|
||||
}
|
||||
});
|
||||
|
||||
return (path != null && (path.equals("A:\\") || path.equals("B:\\")));
|
||||
}
|
||||
|
||||
|
||||
370
jdk/src/share/classes/javax/swing/plaf/LayerUI.java
Normal file
370
jdk/src/share/classes/javax/swing/plaf/LayerUI.java
Normal file
@ -0,0 +1,370 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
|
||||
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package javax.swing.plaf;
|
||||
|
||||
import javax.accessibility.Accessible;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* The base class for all {@link javax.swing.JLayer}'s UI delegates.
|
||||
* <p/>
|
||||
* {@link #paint(java.awt.Graphics, javax.swing.JComponent)} method performes the
|
||||
* painting of the {@code JLayer}
|
||||
* and {@link #eventDispatched(AWTEvent, JLayer)} method is notified
|
||||
* about any {@code AWTEvent}s which have been generated by a {@code JLayer}
|
||||
* or any of its subcomponents.
|
||||
* <p/>
|
||||
* The {@code LayerUI} differs from the UI delegates of the other components,
|
||||
* because it is LookAndFeel independent and is not updated by default when
|
||||
* the system LookAndFeel is changed.
|
||||
* <p/>
|
||||
* The subclasses of {@code LayerUI} can either be stateless and shareable
|
||||
* by multiple {@code JLayer}s or not shareable.
|
||||
*
|
||||
* @param <V> one of the super types of {@code JLayer}'s view component
|
||||
*
|
||||
* @see JLayer#setUI(LayerUI)
|
||||
* @see JLayer#setView(Component)
|
||||
* @see JLayer#getView()
|
||||
* @since 1.7
|
||||
*
|
||||
* @author Alexander Potochkin
|
||||
*/
|
||||
public class LayerUI<V extends Component>
|
||||
extends ComponentUI implements Serializable {
|
||||
|
||||
private final PropertyChangeSupport propertyChangeSupport =
|
||||
new PropertyChangeSupport(this);
|
||||
|
||||
/**
|
||||
* Paints the specified component.
|
||||
* Subclasses should override this method and use
|
||||
* the specified {@code Graphics} object to
|
||||
* render the content of the component.
|
||||
*
|
||||
* @param g the {@code Graphics} context in which to paint;
|
||||
* @param c the component being painted;
|
||||
* it can be safely cast to the {@code JLayer<V>}
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
c.paint(g);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches {@code AWTEvent}s for {@code JLayer}
|
||||
* and <b>all it subcomponents</b> to this {@code LayerUI} instance.
|
||||
* <p>
|
||||
* To enable the {@code AWTEvent} of the particular type,
|
||||
* you call {@link javax.swing.JLayer#setLayerEventMask}
|
||||
* in {@link #installUI(javax.swing.JComponent)}
|
||||
* and set the layer event mask to {@code 0}
|
||||
* in {@link #uninstallUI(javax.swing.JComponent)} after that
|
||||
*
|
||||
* @param e the event to be dispatched
|
||||
* @param l the layer this LayerUI is set to
|
||||
*
|
||||
* @see JLayer#setLayerEventMask(long)
|
||||
* @see javax.swing.JLayer#getLayerEventMask()
|
||||
*/
|
||||
public void eventDispatched(AWTEvent e, JLayer<? extends V> l){
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when {@link javax.swing.JLayer#updateUI()} is called
|
||||
* by the {@code JLayer} this {@code LayerUI} is set to.
|
||||
*
|
||||
* @param l the {@code JLayer} which UI is updated
|
||||
*/
|
||||
public void updateUI(JLayer<? extends V> l){
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the {@code JLayer} this {@code LayerUI} is set to.
|
||||
* The default implementation registers the {@code LayerUI}
|
||||
* as a property change listener for the passed {@code JLayer} component.
|
||||
*
|
||||
* @param c the {@code JLayer} component where this UI delegate is being installed
|
||||
*/
|
||||
public void installUI(JComponent c) {
|
||||
addPropertyChangeListener((JLayer) c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverses the configuration which was previously set
|
||||
* in the {@link #installUI(JComponent)} method.
|
||||
* The default implementation unregisters the property change listener
|
||||
* for the passed JLayer component.
|
||||
*
|
||||
* @param c the component from which this UI delegate is being removed.
|
||||
*/
|
||||
public void uninstallUI(JComponent c) {
|
||||
removePropertyChangeListener((JLayer) c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a PropertyChangeListener to the listener list. The listener is
|
||||
* registered for all bound properties of this class.
|
||||
* <p/>
|
||||
* If {@code listener} is {@code null},
|
||||
* no exception is thrown and no action is performed.
|
||||
*
|
||||
* @param listener the property change listener to be added
|
||||
* @see #removePropertyChangeListener
|
||||
* @see #getPropertyChangeListeners
|
||||
* @see #addPropertyChangeListener(String, java.beans.PropertyChangeListener)
|
||||
*/
|
||||
public void addPropertyChangeListener(PropertyChangeListener listener) {
|
||||
propertyChangeSupport.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a PropertyChangeListener from the listener list. This method
|
||||
* should be used to remove PropertyChangeListeners that were registered
|
||||
* for all bound properties of this class.
|
||||
* <p/>
|
||||
* If {@code listener} is {@code null},
|
||||
* no exception is thrown and no action is performed.
|
||||
*
|
||||
* @param listener the PropertyChangeListener to be removed
|
||||
* @see #addPropertyChangeListener
|
||||
* @see #getPropertyChangeListeners
|
||||
* @see #removePropertyChangeListener(String, PropertyChangeListener)
|
||||
*/
|
||||
public void removePropertyChangeListener(PropertyChangeListener listener) {
|
||||
propertyChangeSupport.removePropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the property change listeners
|
||||
* registered on this component.
|
||||
*
|
||||
* @return all of this ui's {@code PropertyChangeListener}s
|
||||
* or an empty array if no property change
|
||||
* listeners are currently registered
|
||||
* @see #addPropertyChangeListener
|
||||
* @see #removePropertyChangeListener
|
||||
* @see #getPropertyChangeListeners(String)
|
||||
*/
|
||||
public PropertyChangeListener[] getPropertyChangeListeners() {
|
||||
return propertyChangeSupport.getPropertyChangeListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a PropertyChangeListener to the listener list for a specific
|
||||
* property.
|
||||
* <p/>
|
||||
* If {@code propertyName} or {@code listener} is {@code null},
|
||||
* no exception is thrown and no action is taken.
|
||||
*
|
||||
* @param propertyName one of the property names listed above
|
||||
* @param listener the property change listener to be added
|
||||
* @see #removePropertyChangeListener(String, PropertyChangeListener)
|
||||
* @see #getPropertyChangeListeners(String)
|
||||
* @see #addPropertyChangeListener(String, PropertyChangeListener)
|
||||
*/
|
||||
public void addPropertyChangeListener(String propertyName,
|
||||
PropertyChangeListener listener) {
|
||||
propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a {@code PropertyChangeListener} from the listener
|
||||
* list for a specific property. This method should be used to remove
|
||||
* {@code PropertyChangeListener}s
|
||||
* that were registered for a specific bound property.
|
||||
* <p/>
|
||||
* If {@code propertyName} or {@code listener} is {@code null},
|
||||
* no exception is thrown and no action is taken.
|
||||
*
|
||||
* @param propertyName a valid property name
|
||||
* @param listener the PropertyChangeListener to be removed
|
||||
* @see #addPropertyChangeListener(String, PropertyChangeListener)
|
||||
* @see #getPropertyChangeListeners(String)
|
||||
* @see #removePropertyChangeListener(PropertyChangeListener)
|
||||
*/
|
||||
public void removePropertyChangeListener(String propertyName,
|
||||
PropertyChangeListener listener) {
|
||||
propertyChangeSupport.removePropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the listeners which have been associated
|
||||
* with the named property.
|
||||
*
|
||||
* @return all of the {@code PropertyChangeListener}s associated with
|
||||
* the named property; if no such listeners have been added or
|
||||
* if {@code propertyName} is {@code null}, an empty
|
||||
* array is returned
|
||||
* @see #addPropertyChangeListener(String, PropertyChangeListener)
|
||||
* @see #removePropertyChangeListener(String, PropertyChangeListener)
|
||||
* @see #getPropertyChangeListeners
|
||||
*/
|
||||
public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
|
||||
return propertyChangeSupport.getPropertyChangeListeners(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Support for reporting bound property changes for Object properties.
|
||||
* This method can be called when a bound property has changed and it will
|
||||
* send the appropriate PropertyChangeEvent to any registered
|
||||
* PropertyChangeListeners.
|
||||
*
|
||||
* @param propertyName the property whose value has changed
|
||||
* @param oldValue the property's previous value
|
||||
* @param newValue the property's new value
|
||||
*/
|
||||
protected void firePropertyChange(String propertyName,
|
||||
Object oldValue, Object newValue) {
|
||||
propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the {@code LayerUI} when any of its property are changed
|
||||
* and enables updating every {@code JLayer} this {@code LayerUI} instance is set to.
|
||||
*
|
||||
* @param evt the PropertyChangeEvent generated by this {@code LayerUI}
|
||||
* @param l the {@code JLayer} this LayerUI is set to
|
||||
*/
|
||||
public void applyPropertyChange(PropertyChangeEvent evt, JLayer<? extends V> l) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preferred size of the viewport for a view component.
|
||||
*
|
||||
* @return the preferred size of the viewport for a view component
|
||||
* @see Scrollable#getPreferredScrollableViewportSize()
|
||||
*/
|
||||
public Dimension getPreferredScrollableViewportSize(JLayer<? extends V> l) {
|
||||
if (l.getView() instanceof Scrollable) {
|
||||
return ((Scrollable)l.getView()).getPreferredScrollableViewportSize();
|
||||
}
|
||||
return l.getPreferredSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a scroll increment, which is required for components
|
||||
* that display logical rows or columns in order to completely expose
|
||||
* one block of rows or columns, depending on the value of orientation.
|
||||
*
|
||||
* @return the "block" increment for scrolling in the specified direction
|
||||
* @see Scrollable#getScrollableBlockIncrement(Rectangle, int, int)
|
||||
*/
|
||||
public int getScrollableBlockIncrement(JLayer<? extends V> l,
|
||||
Rectangle visibleRect,
|
||||
int orientation, int direction) {
|
||||
if (l.getView() instanceof Scrollable) {
|
||||
return ((Scrollable)l.getView()).getScrollableBlockIncrement(
|
||||
visibleRect,orientation, direction);
|
||||
}
|
||||
return (orientation == SwingConstants.VERTICAL) ? visibleRect.height :
|
||||
visibleRect.width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code false} to indicate that the height of the viewport does not
|
||||
* determine the height of the layer, unless the preferred height
|
||||
* of the layer is smaller than the height of the viewport.
|
||||
*
|
||||
* @return whether the layer should track the height of the viewport
|
||||
* @see Scrollable#getScrollableTracksViewportHeight()
|
||||
*/
|
||||
public boolean getScrollableTracksViewportHeight(JLayer<? extends V> l) {
|
||||
if (l.getView() instanceof Scrollable) {
|
||||
return ((Scrollable)l.getView()).getScrollableTracksViewportHeight();
|
||||
}
|
||||
if (l.getParent() instanceof JViewport) {
|
||||
return (((JViewport)l.getParent()).getHeight() > l.getPreferredSize().height);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code false} to indicate that the width of the viewport does not
|
||||
* determine the width of the layer, unless the preferred width
|
||||
* of the layer is smaller than the width of the viewport.
|
||||
*
|
||||
* @return whether the layer should track the width of the viewport
|
||||
* @see Scrollable
|
||||
* @see LayerUI#getScrollableTracksViewportWidth(JLayer)
|
||||
*/
|
||||
public boolean getScrollableTracksViewportWidth(JLayer<? extends V> l) {
|
||||
if (l.getView() instanceof Scrollable) {
|
||||
return ((Scrollable)l.getView()).getScrollableTracksViewportWidth();
|
||||
}
|
||||
if (l.getParent() instanceof JViewport) {
|
||||
return (((JViewport)l.getParent()).getWidth() > l.getPreferredSize().width);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a scroll increment, which is required for components
|
||||
* that display logical rows or columns in order to completely expose
|
||||
* one new row or column, depending on the value of orientation.
|
||||
* Ideally, components should handle a partially exposed row or column
|
||||
* by returning the distance required to completely expose the item.
|
||||
* <p>
|
||||
* Scrolling containers, like JScrollPane, will use this method
|
||||
* each time the user requests a unit scroll.
|
||||
*
|
||||
* @return The "unit" increment for scrolling in the specified direction.
|
||||
* This value should always be positive.
|
||||
* @see Scrollable#getScrollableUnitIncrement(Rectangle, int, int)
|
||||
*/
|
||||
public int getScrollableUnitIncrement(JLayer<? extends V> l,
|
||||
Rectangle visibleRect,
|
||||
int orientation, int direction) {
|
||||
if (l.getView() instanceof Scrollable) {
|
||||
return ((Scrollable)l.getView()).getScrollableUnitIncrement(
|
||||
visibleRect, orientation, direction);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the {@code JLayer}'s view component is not {@code null},
|
||||
* this calls the view's {@code getBaseline()} method.
|
||||
* Otherwise, the default implementation is called.
|
||||
*
|
||||
* @param c {@code JLayer} to return baseline resize behavior for
|
||||
* @param width the width to get the baseline for
|
||||
* @param height the height to get the baseline for
|
||||
* @return baseline or a value < 0 indicating there is no reasonable
|
||||
* baseline
|
||||
*/
|
||||
public int getBaseline(JComponent c, int width, int height) {
|
||||
JLayer l = (JLayer) c;
|
||||
if (l.getView() != null) {
|
||||
return l.getView().getBaseline(width, height);
|
||||
}
|
||||
return super.getBaseline(c, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the {@code JLayer}'s view component is not {@code null},
|
||||
* this calls the view's {@code getBaselineResizeBehavior()} method.
|
||||
* Otherwise, the default implementation is called.
|
||||
*
|
||||
* @param c {@code JLayer} to return baseline resize behavior for
|
||||
* @return an enum indicating how the baseline changes as the component
|
||||
* size changes
|
||||
*/
|
||||
public Component.BaselineResizeBehavior getBaselineResizeBehavior(JComponent c) {
|
||||
JLayer l = (JLayer) c;
|
||||
if (l.getView() != null) {
|
||||
return l.getView().getBaselineResizeBehavior();
|
||||
}
|
||||
return super.getBaselineResizeBehavior(c);
|
||||
}
|
||||
}
|
||||
@ -540,30 +540,7 @@ public class GlyphView extends View implements TabableView, Cloneable {
|
||||
*/
|
||||
@Override
|
||||
public float getMinimumSpan(int axis) {
|
||||
switch (axis) {
|
||||
case View.X_AXIS:
|
||||
if (minimumSpan < 0) {
|
||||
minimumSpan = 0;
|
||||
int p0 = getStartOffset();
|
||||
int p1 = getEndOffset();
|
||||
while (p1 > p0) {
|
||||
int breakSpot = getBreakSpot(p0, p1);
|
||||
if (breakSpot == BreakIterator.DONE) {
|
||||
// the rest of the view is non-breakable
|
||||
breakSpot = p0;
|
||||
}
|
||||
minimumSpan = Math.max(minimumSpan,
|
||||
getPartialSpan(breakSpot, p1));
|
||||
// Note: getBreakSpot returns the *last* breakspot
|
||||
p1 = breakSpot - 1;
|
||||
}
|
||||
}
|
||||
return minimumSpan;
|
||||
case View.Y_AXIS:
|
||||
return super.getMinimumSpan(axis);
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid axis: " + axis);
|
||||
}
|
||||
return super.getMinimumSpan(axis);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -721,35 +721,7 @@ public class ParagraphView extends FlowView implements TabExpander {
|
||||
@Override
|
||||
protected SizeRequirements calculateMinorAxisRequirements(int axis,
|
||||
SizeRequirements r) {
|
||||
r = super.calculateMinorAxisRequirements(axis, r);
|
||||
|
||||
float min = 0;
|
||||
float glue = 0;
|
||||
int n = getLayoutViewCount();
|
||||
for (int i = 0; i < n; i++) {
|
||||
View v = getLayoutView(i);
|
||||
float span = v.getMinimumSpan(axis);
|
||||
if (v.getBreakWeight(axis, 0, v.getMaximumSpan(axis))
|
||||
> View.BadBreakWeight) {
|
||||
// find the longest non-breakable fragments at the view edges
|
||||
int p0 = v.getStartOffset();
|
||||
int p1 = v.getEndOffset();
|
||||
float start = findEdgeSpan(v, axis, p0, p0, p1);
|
||||
float end = findEdgeSpan(v, axis, p1, p0, p1);
|
||||
glue += start;
|
||||
min = Math.max(min, Math.max(span, glue));
|
||||
glue = end;
|
||||
} else {
|
||||
// non-breakable view
|
||||
glue += span;
|
||||
min = Math.max(min, glue);
|
||||
}
|
||||
}
|
||||
r.minimum = Math.max(r.minimum, (int) min);
|
||||
r.preferred = Math.max(r.minimum, r.preferred);
|
||||
r.maximum = Math.max(r.preferred, r.maximum);
|
||||
|
||||
return r;
|
||||
return super.calculateMinorAxisRequirements(axis, r);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -327,13 +327,45 @@ public class WrappedPlainView extends BoxView implements TabExpander {
|
||||
/**
|
||||
* Return reasonable default values for the view dimensions. The standard
|
||||
* text terminal size 80x24 is pretty suitable for the wrapped plain view.
|
||||
*
|
||||
* The size should not be larger than the component housing the view's
|
||||
* container.
|
||||
*/
|
||||
private float getDefaultSpan(int axis) {
|
||||
Container host = getContainer();
|
||||
Component parent = null;
|
||||
|
||||
if (host != null) {
|
||||
parent = host.getParent();
|
||||
}
|
||||
|
||||
switch (axis) {
|
||||
case View.X_AXIS:
|
||||
return 80 * metrics.getWidths()['M'];
|
||||
int defaultWidth = 80 * metrics.getWidths()['M'];
|
||||
int parentWidth = 0;
|
||||
|
||||
if (parent != null) {
|
||||
parentWidth = parent.getWidth();
|
||||
}
|
||||
|
||||
if (defaultWidth > parentWidth) {
|
||||
return parentWidth;
|
||||
}
|
||||
return defaultWidth;
|
||||
|
||||
case View.Y_AXIS:
|
||||
return 24 * metrics.getHeight();
|
||||
int defaultHeight = 24 * metrics.getHeight();
|
||||
int parentHeight = 0;
|
||||
|
||||
if (parent != null) {
|
||||
parentHeight = parent.getHeight();
|
||||
}
|
||||
|
||||
if (defaultHeight > parentHeight) {
|
||||
return parentHeight;
|
||||
}
|
||||
return defaultHeight;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid axis: " + axis);
|
||||
}
|
||||
|
||||
@ -73,12 +73,7 @@ final class Win32ShellFolder2 extends ShellFolder {
|
||||
|
||||
private static native void initIDs();
|
||||
|
||||
private static final boolean is98;
|
||||
|
||||
static {
|
||||
String osName = System.getProperty("os.name");
|
||||
is98 = (osName != null && osName.startsWith("Windows 98"));
|
||||
|
||||
initIDs();
|
||||
}
|
||||
|
||||
@ -305,7 +300,6 @@ final class Win32ShellFolder2 extends ShellFolder {
|
||||
}, RuntimeException.class)
|
||||
);
|
||||
this.disposer.relativePIDL = relativePIDL;
|
||||
getAbsolutePath();
|
||||
sun.java2d.Disposer.addRecord(this, disposer);
|
||||
}
|
||||
|
||||
@ -616,11 +610,8 @@ final class Win32ShellFolder2 extends ShellFolder {
|
||||
public boolean isDirectory() {
|
||||
if (isDir == null) {
|
||||
// Folders with SFGAO_BROWSABLE have "shell extension" handlers and are
|
||||
// not traversable in JFileChooser. An exception is "My Documents" on
|
||||
// Windows 98.
|
||||
if (hasAttribute(ATTRIB_FOLDER)
|
||||
&& (!hasAttribute(ATTRIB_BROWSABLE) ||
|
||||
(is98 && equals(Win32ShellFolderManager2.getPersonal())))) {
|
||||
// not traversable in JFileChooser.
|
||||
if (hasAttribute(ATTRIB_FOLDER) && !hasAttribute(ATTRIB_BROWSABLE)) {
|
||||
isDir = Boolean.TRUE;
|
||||
} else if (isLink()) {
|
||||
ShellFolder linkLocation = getLinkLocation(false);
|
||||
|
||||
@ -105,9 +105,11 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
|
||||
private static Win32ShellFolder2 network;
|
||||
private static Win32ShellFolder2 personal;
|
||||
|
||||
private static String osVersion = System.getProperty("os.version");
|
||||
private static final boolean useShell32Icons =
|
||||
(osVersion != null && osVersion.compareTo("5.1") >= 0);
|
||||
private static final boolean USE_SHELL32_ICONS = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
|
||||
public Boolean run() {
|
||||
return OSInfo.getWindowsVersion().compareTo(OSInfo.WINDOWS_XP) >= 0;
|
||||
}
|
||||
});
|
||||
|
||||
static Win32ShellFolder2 getDesktop() {
|
||||
if (desktop == null) {
|
||||
@ -307,15 +309,15 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
|
||||
i = Integer.parseInt(name);
|
||||
} catch (NumberFormatException ex) {
|
||||
if (name.equals("ListView")) {
|
||||
i = (useShell32Icons) ? 21 : 2;
|
||||
i = (USE_SHELL32_ICONS) ? 21 : 2;
|
||||
} else if (name.equals("DetailsView")) {
|
||||
i = (useShell32Icons) ? 23 : 3;
|
||||
i = (USE_SHELL32_ICONS) ? 23 : 3;
|
||||
} else if (name.equals("UpFolder")) {
|
||||
i = (useShell32Icons) ? 28 : 8;
|
||||
i = (USE_SHELL32_ICONS) ? 28 : 8;
|
||||
} else if (name.equals("NewFolder")) {
|
||||
i = (useShell32Icons) ? 31 : 11;
|
||||
i = (USE_SHELL32_ICONS) ? 31 : 11;
|
||||
} else if (name.equals("ViewMenu")) {
|
||||
i = (useShell32Icons) ? 21 : 2;
|
||||
i = (USE_SHELL32_ICONS) ? 21 : 2;
|
||||
}
|
||||
}
|
||||
if (i >= 0) {
|
||||
@ -352,11 +354,16 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
|
||||
* Does <code>dir</code> represent a "computer" such as a node on the network, or
|
||||
* "My Computer" on the desktop.
|
||||
*/
|
||||
public boolean isComputerNode(File dir) {
|
||||
public boolean isComputerNode(final File dir) {
|
||||
if (dir != null && dir == getDrives()) {
|
||||
return true;
|
||||
} else {
|
||||
String path = dir.getAbsolutePath();
|
||||
String path = AccessController.doPrivileged(new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return dir.getAbsolutePath();
|
||||
}
|
||||
});
|
||||
|
||||
return (path.startsWith("\\\\") && path.indexOf("\\", 2) < 0); //Network path
|
||||
}
|
||||
}
|
||||
@ -501,7 +508,7 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
|
||||
// thread, we don't need to delegate the task
|
||||
return task.call();
|
||||
} else {
|
||||
Future<T> future;
|
||||
final Future<T> future;
|
||||
|
||||
try {
|
||||
future = submit(task);
|
||||
@ -512,7 +519,13 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
|
||||
try {
|
||||
return future.get();
|
||||
} catch (InterruptedException e) {
|
||||
future.cancel(true);
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
future.cancel(true);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
throw e;
|
||||
} catch (ExecutionException e) {
|
||||
|
||||
66
jdk/test/java/beans/Introspector/Test6868189.java
Normal file
66
jdk/test/java/beans/Introspector/Test6868189.java
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6868189
|
||||
* @summary Tests custom BeanInfo in the same package
|
||||
* @author Sergey Malenkov
|
||||
*/
|
||||
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.beans.SimpleBeanInfo;
|
||||
|
||||
public class Test6868189 {
|
||||
|
||||
private static final String PROPERTY = "$?"; // NON-NLS: the property name
|
||||
private static final String GETTER = "name"; // NON-NLS: the method name
|
||||
private static final String SETTER = null;
|
||||
|
||||
public static void main(String[] args) throws IntrospectionException {
|
||||
PropertyDescriptor[] pds = Introspector.getBeanInfo(Enumeration.class).getPropertyDescriptors();
|
||||
if ((pds.length != 1)|| !PROPERTY.equals(pds[0].getName())){
|
||||
throw new Error("unexpected property");
|
||||
}
|
||||
}
|
||||
|
||||
public enum Enumeration {
|
||||
FIRST, SECOND
|
||||
}
|
||||
|
||||
public static class EnumerationBeanInfo extends SimpleBeanInfo {
|
||||
@Override
|
||||
public PropertyDescriptor[] getPropertyDescriptors() {
|
||||
try {
|
||||
return new PropertyDescriptor[] {
|
||||
new PropertyDescriptor(PROPERTY, Enumeration.class, GETTER, SETTER)
|
||||
};
|
||||
}
|
||||
catch (IntrospectionException exception) {
|
||||
throw new Error("unexpected exception", exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
105
jdk/test/javax/swing/JInternalFrame/Test6325652.java
Normal file
105
jdk/test/javax/swing/JInternalFrame/Test6325652.java
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6325652
|
||||
* @summary Tests keyboard shortcuts
|
||||
* @author Sergey Malenkov
|
||||
* @library ..
|
||||
*/
|
||||
|
||||
import java.awt.AWTException;
|
||||
import java.awt.Robot;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.beans.PropertyVetoException;
|
||||
import javax.swing.JDesktopPane;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JInternalFrame;
|
||||
import javax.swing.JTextArea;
|
||||
|
||||
public class Test6325652 {
|
||||
|
||||
private static final int WIDTH = 300;
|
||||
private static final int HEIGHT = 300;
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
SwingTest.start(Test6325652.class);
|
||||
}
|
||||
|
||||
private static Robot robot;
|
||||
private JInternalFrame internal;
|
||||
|
||||
public Test6325652(JFrame frame) {
|
||||
JDesktopPane desktop = new JDesktopPane();
|
||||
desktop.add(create(0));
|
||||
desktop.add(this.internal = create(1));
|
||||
frame.add(desktop);
|
||||
}
|
||||
|
||||
public void select() throws PropertyVetoException {
|
||||
this.internal.setSelected(true);
|
||||
}
|
||||
|
||||
public static void stepFirst() throws AWTException {
|
||||
robot = new Robot(); // initialize shared static field first time
|
||||
click(KeyEvent.VK_CONTROL, KeyEvent.VK_F9); // iconify internal frame
|
||||
}
|
||||
|
||||
public void stepFirstValidate() {
|
||||
if (!this.internal.isIcon()) {
|
||||
throw new Error("frame should be an icon");
|
||||
}
|
||||
}
|
||||
|
||||
public static void stepSecond() {
|
||||
click(KeyEvent.VK_CONTROL, KeyEvent.VK_F6); // navigate to the icon
|
||||
click(KeyEvent.VK_CONTROL, KeyEvent.VK_F5); // restore the icon
|
||||
}
|
||||
|
||||
public void stepSecondValidate() {
|
||||
if (this.internal.isIcon()) {
|
||||
throw new Error("frame should not be an icon");
|
||||
}
|
||||
}
|
||||
|
||||
private static void click(int... keys) {
|
||||
for (int key : keys) {
|
||||
robot.keyPress(key);
|
||||
}
|
||||
for (int key : keys) {
|
||||
robot.keyRelease(key);
|
||||
}
|
||||
}
|
||||
|
||||
private static JInternalFrame create(int index) {
|
||||
String text = "test" + index; // NON-NLS: frame identification
|
||||
index = index * 3 + 1;
|
||||
|
||||
JInternalFrame internal = new JInternalFrame(text, true, true, true, true);
|
||||
internal.getContentPane().add(new JTextArea(text));
|
||||
internal.setBounds(10 * index, 10 * index, WIDTH, HEIGHT);
|
||||
internal.setVisible(true);
|
||||
return internal;
|
||||
}
|
||||
}
|
||||
@ -26,6 +26,7 @@
|
||||
* @bug 6505027
|
||||
* @summary Tests focus problem inside internal frame
|
||||
* @author Sergey Malenkov
|
||||
* @library ..
|
||||
*/
|
||||
|
||||
import java.awt.AWTException;
|
||||
@ -45,11 +46,10 @@ import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.WindowConstants;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.table.TableColumn;
|
||||
|
||||
public class Test6505027 implements Runnable {
|
||||
public class Test6505027 {
|
||||
|
||||
private static final boolean INTERNAL = true;
|
||||
private static final boolean TERMINATE = true;
|
||||
@ -57,80 +57,53 @@ public class Test6505027 implements Runnable {
|
||||
private static final int WIDTH = 450;
|
||||
private static final int HEIGHT = 200;
|
||||
private static final int OFFSET = 10;
|
||||
private static final long PAUSE = 2048L;
|
||||
|
||||
private static final String[] COLUMNS = { "Size", "Shape" }; // NON-NLS
|
||||
private static final String[] ITEMS = { "a", "b", "c", "d" }; // NON-NLS
|
||||
private static final String KEY = "terminateEditOnFocusLost"; // NON-NLS
|
||||
private static final String[] COLUMNS = { "Size", "Shape" }; // NON-NLS: column names
|
||||
private static final String[] ITEMS = { "a", "b", "c", "d" }; // NON-NLS: combobox content
|
||||
private static final String KEY = "terminateEditOnFocusLost"; // NON-NLS: property name
|
||||
|
||||
public static void main(String[] args) {
|
||||
SwingUtilities.invokeLater(new Test6505027());
|
||||
public static void main(String[] args) throws Throwable {
|
||||
SwingTest.start(Test6505027.class);
|
||||
}
|
||||
|
||||
Component component = null;
|
||||
while (component == null) {
|
||||
try {
|
||||
Thread.sleep(PAUSE);
|
||||
}
|
||||
catch (InterruptedException exception) {
|
||||
// ignore interrupted exception
|
||||
}
|
||||
component = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
|
||||
private final JTable table = new JTable(new DefaultTableModel(COLUMNS, 2));
|
||||
|
||||
public Test6505027(JFrame main) {
|
||||
Container container = main;
|
||||
if (INTERNAL) {
|
||||
JInternalFrame frame = new JInternalFrame();
|
||||
frame.setBounds(OFFSET, OFFSET, WIDTH, HEIGHT);
|
||||
frame.setVisible(true);
|
||||
|
||||
JDesktopPane desktop = new JDesktopPane();
|
||||
desktop.add(frame, new Integer(1));
|
||||
|
||||
container.add(desktop);
|
||||
container = frame;
|
||||
}
|
||||
if (TERMINATE) {
|
||||
this.table.putClientProperty(KEY, Boolean.TRUE);
|
||||
}
|
||||
TableColumn column = this.table.getColumn(COLUMNS[1]);
|
||||
column.setCellEditor(new DefaultCellEditor(new JComboBox(ITEMS)));
|
||||
|
||||
container.add(BorderLayout.NORTH, new JTextField());
|
||||
container.add(BorderLayout.CENTER, new JScrollPane(this.table));
|
||||
}
|
||||
|
||||
public void press() throws AWTException {
|
||||
Point point = this.table.getCellRect(1, 1, false).getLocation();
|
||||
SwingUtilities.convertPointToScreen(point, this.table);
|
||||
|
||||
Robot robot = new Robot();
|
||||
robot.mouseMove(point.x + 1, point.y + 1);
|
||||
robot.mousePress(InputEvent.BUTTON1_MASK);
|
||||
}
|
||||
|
||||
public static void validate() {
|
||||
Component component = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
|
||||
if (!component.getClass().equals(JComboBox.class)) {
|
||||
throw new Error("unexpected focus owner: " + component);
|
||||
}
|
||||
SwingUtilities.getWindowAncestor(component).dispose();
|
||||
}
|
||||
|
||||
private JTable table;
|
||||
private Point point;
|
||||
|
||||
public void run() {
|
||||
if (this.table == null) {
|
||||
JFrame main = new JFrame();
|
||||
main.setSize(WIDTH + OFFSET * 3, HEIGHT + OFFSET * 5);
|
||||
main.setLocationRelativeTo(null);
|
||||
main.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
main.setVisible(true);
|
||||
|
||||
Container container = main;
|
||||
if (INTERNAL) {
|
||||
JInternalFrame frame = new JInternalFrame();
|
||||
frame.setBounds(OFFSET, OFFSET, WIDTH, HEIGHT);
|
||||
frame.setVisible(true);
|
||||
|
||||
JDesktopPane desktop = new JDesktopPane();
|
||||
desktop.add(frame, new Integer(1));
|
||||
|
||||
container.add(desktop);
|
||||
container = frame;
|
||||
}
|
||||
this.table = new JTable(new DefaultTableModel(COLUMNS, 2));
|
||||
if (TERMINATE) {
|
||||
this.table.putClientProperty(KEY, Boolean.TRUE);
|
||||
}
|
||||
TableColumn column = this.table.getColumn(COLUMNS[1]);
|
||||
column.setCellEditor(new DefaultCellEditor(new JComboBox(ITEMS)));
|
||||
|
||||
container.add(BorderLayout.NORTH, new JTextField());
|
||||
container.add(BorderLayout.CENTER, new JScrollPane(this.table));
|
||||
|
||||
SwingUtilities.invokeLater(this);
|
||||
}
|
||||
else if (this.point == null) {
|
||||
this.point = this.table.getCellRect(1, 1, false).getLocation();
|
||||
SwingUtilities.convertPointToScreen(this.point, this.table);
|
||||
SwingUtilities.invokeLater(this);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
robot.mouseMove(this.point.x + 1, this.point.y + 1);
|
||||
robot.mousePress(InputEvent.BUTTON1_MASK);
|
||||
}
|
||||
catch (AWTException exception) {
|
||||
throw new Error("unexpected exception", exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,83 +26,73 @@
|
||||
* @bug 6802868
|
||||
* @summary JInternalFrame is not maximized when maximized parent frame
|
||||
* @author Alexander Potochkin
|
||||
* @library ..
|
||||
*/
|
||||
|
||||
import sun.awt.SunToolkit;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Point;
|
||||
import java.awt.Robot;
|
||||
import java.awt.Toolkit;
|
||||
import java.beans.PropertyVetoException;
|
||||
import javax.swing.JDesktopPane;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JInternalFrame;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
public class Test6802868 {
|
||||
static JInternalFrame jif;
|
||||
static JFrame frame;
|
||||
static Dimension size;
|
||||
static Point location;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Robot robot = new Robot();
|
||||
robot.setAutoDelay(20);
|
||||
SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
|
||||
public static void main(String[] args) throws Throwable {
|
||||
SwingTest.start(Test6802868.class);
|
||||
}
|
||||
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
public void run() {
|
||||
frame = new JFrame();
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
private final JFrame frame;
|
||||
private final JInternalFrame internal;
|
||||
private Dimension size;
|
||||
private Point location;
|
||||
|
||||
JDesktopPane jdp = new JDesktopPane();
|
||||
frame.getContentPane().add(jdp);
|
||||
public Test6802868(JFrame frame) {
|
||||
JDesktopPane desktop = new JDesktopPane();
|
||||
|
||||
jif = new JInternalFrame("Title", true, true, true, true);
|
||||
jdp.add(jif);
|
||||
jif.setVisible(true);
|
||||
this.frame = frame;
|
||||
this.frame.add(desktop);
|
||||
|
||||
frame.setSize(200, 200);
|
||||
frame.setLocationRelativeTo(null);
|
||||
frame.setVisible(true);
|
||||
this.internal = new JInternalFrame(getClass().getName(), true, true, true, true);
|
||||
this.internal.setVisible(true);
|
||||
|
||||
try {
|
||||
jif.setMaximum(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
toolkit.realSync();
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
public void run() {
|
||||
size = jif.getSize();
|
||||
frame.setSize(300, 300);
|
||||
}
|
||||
});
|
||||
toolkit.realSync();
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
public void run() {
|
||||
if (jif.getSize().equals(size)) {
|
||||
throw new RuntimeException("InternalFrame hasn't changed its size");
|
||||
}
|
||||
try {
|
||||
jif.setIcon(true);
|
||||
} catch (PropertyVetoException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
location = jif.getDesktopIcon().getLocation();
|
||||
frame.setSize(400, 400);
|
||||
}
|
||||
});
|
||||
toolkit.realSync();
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
public void run() {
|
||||
if (jif.getDesktopIcon().getLocation().equals(location)) {
|
||||
throw new RuntimeException("JDesktopIcon hasn't moved");
|
||||
}
|
||||
}
|
||||
});
|
||||
desktop.add(this.internal);
|
||||
}
|
||||
|
||||
public void firstAction() throws PropertyVetoException {
|
||||
this.internal.setMaximum(true);
|
||||
}
|
||||
|
||||
public void firstTest() {
|
||||
this.size = this.internal.getSize();
|
||||
resizeFrame();
|
||||
}
|
||||
|
||||
public void firstValidation() {
|
||||
if (this.internal.getSize().equals(this.size)) {
|
||||
throw new Error("InternalFrame hasn't changed its size");
|
||||
}
|
||||
}
|
||||
|
||||
public void secondAction() throws PropertyVetoException {
|
||||
this.internal.setIcon(true);
|
||||
}
|
||||
|
||||
public void secondTest() {
|
||||
this.location = this.internal.getDesktopIcon().getLocation();
|
||||
resizeFrame();
|
||||
}
|
||||
|
||||
public void secondValidation() {
|
||||
if (this.internal.getDesktopIcon().getLocation().equals(this.location)) {
|
||||
throw new Error("JDesktopIcon hasn't moved");
|
||||
}
|
||||
}
|
||||
|
||||
private void resizeFrame() {
|
||||
Dimension size = this.frame.getSize();
|
||||
size.width += 10;
|
||||
size.height += 10;
|
||||
this.frame.setSize(size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* @test
|
||||
* @summary Makes sure that JLayer is synchronizable
|
||||
* @author Alexander Potochkin
|
||||
* @run main SerializationTest
|
||||
*/
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.LayerUI;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
public class SerializationTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
|
||||
|
||||
JLayer<JButton> layer = new JLayer<JButton>(new JButton("Hello"));
|
||||
|
||||
layer.setUI(new TestLayerUI<JButton>());
|
||||
|
||||
outputStream.writeObject(layer);
|
||||
outputStream.flush();
|
||||
|
||||
ByteArrayInputStream byteArrayInputStream =
|
||||
new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
|
||||
ObjectInputStream inputStream = new ObjectInputStream(byteArrayInputStream);
|
||||
|
||||
JLayer newLayer = (JLayer) inputStream.readObject();
|
||||
|
||||
if (newLayer.getLayout() == null) {
|
||||
throw new RuntimeException("JLayer's layout is null");
|
||||
}
|
||||
if (newLayer.getGlassPane() == null) {
|
||||
throw new RuntimeException("JLayer's glassPane is null");
|
||||
}
|
||||
if (newLayer.getUI().getClass() != layer.getUI().getClass()) {
|
||||
throw new RuntimeException("Different UIs");
|
||||
}
|
||||
if (newLayer.getView().getClass() != layer.getView().getClass()) {
|
||||
throw new RuntimeException("Different Views");
|
||||
}
|
||||
}
|
||||
|
||||
static class TestLayerUI<V extends JComponent> extends LayerUI<V> {
|
||||
public String toString() {
|
||||
return "TestLayerUI";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -27,10 +27,9 @@
|
||||
* @summary Resizes right-oriented scroll pane
|
||||
* @author Sergey Malenkov
|
||||
* @library ..
|
||||
* @build SwingTest
|
||||
* @run main Test6526631
|
||||
*/
|
||||
|
||||
import java.awt.ComponentOrientation;
|
||||
import java.awt.Dimension;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JScrollBar;
|
||||
@ -38,15 +37,13 @@ import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JViewport;
|
||||
|
||||
import static java.awt.ComponentOrientation.RIGHT_TO_LEFT;
|
||||
|
||||
public class Test6526631 {
|
||||
|
||||
private static final int COLS = 90;
|
||||
private static final int ROWS = 50;
|
||||
private static final int OFFSET = 10;
|
||||
|
||||
public static void main(String[] args) {
|
||||
public static void main(String[] args) throws Throwable {
|
||||
SwingTest.start(Test6526631.class);
|
||||
}
|
||||
|
||||
@ -55,7 +52,7 @@ public class Test6526631 {
|
||||
|
||||
public Test6526631(JFrame frame) {
|
||||
this.pane = new JScrollPane(new JTextArea(ROWS, COLS));
|
||||
this.pane.setComponentOrientation(RIGHT_TO_LEFT);
|
||||
this.pane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
|
||||
this.frame = frame;
|
||||
this.frame.add(this.pane);
|
||||
}
|
||||
@ -79,24 +76,24 @@ public class Test6526631 {
|
||||
public void validateThird() {
|
||||
JViewport viewport = this.pane.getViewport();
|
||||
JScrollBar scroller = this.pane.getHorizontalScrollBar();
|
||||
if (!scroller.getComponentOrientation().equals(RIGHT_TO_LEFT)) {
|
||||
throw new IllegalStateException("unexpected component orientation");
|
||||
if (!scroller.getComponentOrientation().equals(ComponentOrientation.RIGHT_TO_LEFT)) {
|
||||
throw new Error("unexpected component orientation");
|
||||
}
|
||||
int value = scroller.getValue();
|
||||
if (value != 0) {
|
||||
throw new IllegalStateException("unexpected scroll value");
|
||||
throw new Error("unexpected scroll value");
|
||||
}
|
||||
int extent = viewport.getExtentSize().width;
|
||||
if (extent != scroller.getVisibleAmount()) {
|
||||
throw new IllegalStateException("unexpected visible amount");
|
||||
throw new Error("unexpected visible amount");
|
||||
}
|
||||
int size = viewport.getViewSize().width;
|
||||
if (size != scroller.getMaximum()) {
|
||||
throw new IllegalStateException("unexpected maximum");
|
||||
throw new Error("unexpected maximum");
|
||||
}
|
||||
int pos = size - extent - value;
|
||||
if (pos != viewport.getViewPosition().x) {
|
||||
throw new IllegalStateException("unexpected position");
|
||||
throw new Error("unexpected position");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
89
jdk/test/javax/swing/JTextArea/Test6593649.java
Normal file
89
jdk/test/javax/swing/JTextArea/Test6593649.java
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
@bug 6593649
|
||||
@summary Word wrap does not work in JTextArea: long lines are not wrapped
|
||||
@author Lillian Angel
|
||||
@run main Test6593649
|
||||
*/
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class Test6593649 extends JFrame {
|
||||
static JTextArea txt;
|
||||
static JPanel innerPanel;
|
||||
|
||||
public Test6593649(Dimension d)
|
||||
{
|
||||
super("Word Wrap Testcase");
|
||||
|
||||
setSize(d);
|
||||
|
||||
final Container contentPane = getContentPane();
|
||||
|
||||
innerPanel = new JPanel();
|
||||
innerPanel.setLayout(new BoxLayout(innerPanel, BoxLayout.LINE_AXIS));
|
||||
|
||||
txt = new JTextArea("This is a long line that should wrap, but doesn't...");
|
||||
txt.setLineWrap(true);
|
||||
txt.setWrapStyleWord(true);
|
||||
|
||||
innerPanel.add(txt);
|
||||
|
||||
contentPane.add(innerPanel, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws InterruptedException
|
||||
{
|
||||
int size = 100;
|
||||
Dimension d;
|
||||
Test6593649 cp;
|
||||
Dimension txtSize;
|
||||
Dimension innerSize;
|
||||
Dimension cpSize;
|
||||
|
||||
while (size <= 600)
|
||||
{
|
||||
d = new Dimension(size, size);
|
||||
cp = new Test6593649(d);
|
||||
cp.setVisible(true);
|
||||
|
||||
txtSize = txt.getPreferredSize();
|
||||
innerSize = innerPanel.getPreferredSize();
|
||||
cpSize = cp.getSize();
|
||||
|
||||
if (!(txtSize.getWidth() == innerPanel.getWidth() && txtSize.getHeight() == innerPanel.getHeight() &&
|
||||
txtSize.getWidth() <= cpSize.getWidth() && txtSize.getHeight() <= cpSize.getHeight()))
|
||||
{
|
||||
throw new RuntimeException("Test failed: Text area size does not properly match panel and frame sizes");
|
||||
}
|
||||
|
||||
Thread.sleep(2000);
|
||||
|
||||
cp.hide();
|
||||
size += 50;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -21,7 +21,8 @@
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import sun.awt.SunToolkit;
|
||||
import java.awt.Toolkit;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
@ -30,12 +31,18 @@ import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import javax.swing.JFrame;
|
||||
|
||||
import static javax.swing.SwingUtilities.invokeLater;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
/**
|
||||
* SwingTestHelper is a utility class for writing regression tests
|
||||
* SwingTest is a utility class for writing regression tests
|
||||
* that require interacting with the UI.
|
||||
* It uses reflection to invoke all public methods without parameters.
|
||||
* All static methods are starting on the current thread.
|
||||
* Other methods including constructor are starting on the EDT.
|
||||
* Between each method invocation all pending events are processed.
|
||||
* The methods are sorted by name and invoked in that order.
|
||||
* Failure of the test is signaled by any method throwing an exception.
|
||||
* If no methods throw an exception the test is assumed to have passed.
|
||||
*
|
||||
* @author Sergey A. Malenkov
|
||||
*/
|
||||
@ -44,99 +51,56 @@ final class SwingTest implements Runnable {
|
||||
private static final int WIDTH = 640;
|
||||
private static final int HEIGHT = 480;
|
||||
|
||||
public static void start(Class<?> type) {
|
||||
public static void start(Class<?> type) throws Throwable {
|
||||
new SwingTest(type).start();
|
||||
}
|
||||
|
||||
private final PrintWriter writer = new PrintWriter(System.out, true);
|
||||
private final Class<?> type;
|
||||
private final Iterator<Method> methods;
|
||||
|
||||
private Class<?> type;
|
||||
private JFrame frame;
|
||||
private Iterator<Method> methods;
|
||||
private Object object;
|
||||
private Method method;
|
||||
private Throwable error;
|
||||
|
||||
private SwingTest(Class<?> type) {
|
||||
Set<Method> methods = new TreeSet<Method>(new Comparator<Method>() {
|
||||
public int compare(Method first, Method second) {
|
||||
return first.getName().compareTo(second.getName());
|
||||
}
|
||||
});
|
||||
for (Method method : type.getMethods()) {
|
||||
if (method.getDeclaringClass().equals(type)) {
|
||||
if (method.getReturnType().equals(void.class)) {
|
||||
if (0 == method.getParameterTypes().length) {
|
||||
methods.add(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.type = type;
|
||||
this.methods = methods.iterator();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
synchronized (this.writer) {
|
||||
if (this.error != null) {
|
||||
this.frame.dispose();
|
||||
this.frame = null;
|
||||
}
|
||||
else if (this.object == null) {
|
||||
invoke();
|
||||
Set<Method> methods = new TreeSet<Method>(new Comparator<Method>() {
|
||||
public int compare(Method first, Method second) {
|
||||
return first.getName().compareTo(second.getName());
|
||||
}
|
||||
});
|
||||
for (Method method : this.type.getMethods()) {
|
||||
if (method.getDeclaringClass().equals(this.type)) {
|
||||
if (method.getReturnType().equals(void.class)) {
|
||||
if (0 == method.getParameterTypes().length) {
|
||||
methods.add(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.methods = methods.iterator();
|
||||
}
|
||||
else if (this.method != null) {
|
||||
invoke();
|
||||
}
|
||||
else if (this.methods.hasNext()) {
|
||||
this.method = this.methods.next();
|
||||
}
|
||||
else {
|
||||
this.frame.dispose();
|
||||
this.frame = null;
|
||||
this.type = null;
|
||||
}
|
||||
this.writer.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
private void start() {
|
||||
synchronized (this.writer) {
|
||||
while (this.type != null) {
|
||||
if ((this.method != null) && Modifier.isStatic(this.method.getModifiers())) {
|
||||
invoke();
|
||||
}
|
||||
else {
|
||||
invokeLater(this);
|
||||
try {
|
||||
this.writer.wait();
|
||||
}
|
||||
catch (InterruptedException exception) {
|
||||
exception.printStackTrace(this.writer);
|
||||
}
|
||||
}
|
||||
if ((this.frame == null) && (this.error != null)) {
|
||||
throw new Error("unexpected error", this.error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void invoke() {
|
||||
try {
|
||||
if (this.method != null) {
|
||||
this.writer.println(this.method);
|
||||
this.method.invoke(this.object);
|
||||
this.method = null;
|
||||
}
|
||||
else {
|
||||
this.writer.println(this.type);
|
||||
if (this.object == null) {
|
||||
System.out.println(this.type);
|
||||
this.frame = new JFrame(this.type.getSimpleName());
|
||||
this.frame.setSize(WIDTH, HEIGHT);
|
||||
this.frame.setLocationRelativeTo(null);
|
||||
this.object = this.type.getConstructor(JFrame.class).newInstance(this.frame);
|
||||
this.object = this.type.getConstructor(this.frame.getClass()).newInstance(this.frame);
|
||||
this.frame.setVisible(true);
|
||||
}
|
||||
else if (this.method != null) {
|
||||
System.out.println(this.method);
|
||||
this.method.invoke(this.object);
|
||||
}
|
||||
else {
|
||||
System.out.println((this.error == null) ? "PASSED" : "FAILED"); // NON-NLS: debug
|
||||
this.frame.dispose();
|
||||
this.frame = null;
|
||||
}
|
||||
}
|
||||
catch (NoSuchMethodException exception) {
|
||||
this.error = exception;
|
||||
@ -156,5 +120,29 @@ final class SwingTest implements Runnable {
|
||||
catch (InvocationTargetException exception) {
|
||||
this.error = exception.getTargetException();
|
||||
}
|
||||
System.out.flush();
|
||||
this.method = this.methods.hasNext() && (this.error == null)
|
||||
? this.methods.next()
|
||||
: null;
|
||||
}
|
||||
|
||||
private void start() throws Throwable {
|
||||
do {
|
||||
if ((this.method != null) && Modifier.isStatic(this.method.getModifiers())) {
|
||||
run(); // invoke static method on the current thread
|
||||
}
|
||||
else {
|
||||
SwingUtilities.invokeLater(this); // invoke on the event dispatch thread
|
||||
}
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
if (tk instanceof SunToolkit) {
|
||||
SunToolkit stk = (SunToolkit) tk;
|
||||
stk.realSync(); // wait until done
|
||||
}
|
||||
}
|
||||
while (this.frame != null);
|
||||
if (this.error != null) {
|
||||
throw this.error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
114
jdk/test/javax/swing/text/GlyphView/6539700/bug6539700.java
Normal file
114
jdk/test/javax/swing/text/GlyphView/6539700/bug6539700.java
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6539700
|
||||
* @summary test that the long space-less lines are correctly soft-wrapped
|
||||
* @author Sergey Groznyh
|
||||
* @run main bug6539700
|
||||
*/
|
||||
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.text.ParagraphView;
|
||||
import javax.swing.text.View;
|
||||
|
||||
public class bug6539700 {
|
||||
static JFrame f;
|
||||
static JEditorPane ep;
|
||||
static String text = "AAAAAAAA<b>AAAAAA</b>AAAAAAAA<b>AAAAAAAAA</b>" +
|
||||
"AA<b>AAA</b>AAAAAAAAA";
|
||||
static int size = 100;
|
||||
static Class rowClass = null;
|
||||
|
||||
static void createContentPane() {
|
||||
ep = new JEditorPane();
|
||||
ep.setContentType("text/html");
|
||||
ep.setEditable(false);
|
||||
ep.setText(text);
|
||||
f = new JFrame();
|
||||
f.setSize(size, 2 * size);
|
||||
f.add(ep);
|
||||
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
f.setVisible(true);
|
||||
}
|
||||
|
||||
static void checkRows(View v, boolean last) {
|
||||
int width = (int) v.getPreferredSpan(View.X_AXIS);
|
||||
|
||||
if (v.getClass() == rowClass) {
|
||||
// Row width shouldn't exceed the container width
|
||||
if (width > size) {
|
||||
throw new RuntimeException("too long row: " + width);
|
||||
}
|
||||
|
||||
// Row shouldn't be too short (except for the last one)
|
||||
if (!last) {
|
||||
if (width < size * 2 / 3) {
|
||||
throw new RuntimeException("too short row: " + width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int n = v.getViewCount();
|
||||
if (n > 0) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
View c = v.getView(i);
|
||||
checkRows(c, i == n - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] argv) {
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
public void run() {
|
||||
createContentPane();
|
||||
}
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
Class[] pvchildren = ParagraphView.class.getDeclaredClasses();
|
||||
for (Class c : pvchildren) {
|
||||
if (c.getName().equals("javax.swing.text.ParagraphView$Row")) {
|
||||
rowClass = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rowClass == null) {
|
||||
throw new RuntimeException("can't find ParagraphView.Row class");
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
checkRows(ep.getUI().getRootView(ep), true);
|
||||
}
|
||||
});
|
||||
|
||||
System.out.println("OK");
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user