From 4b3a6a58b40ac5b71ef617fdc4180d6706e824d4 Mon Sep 17 00:00:00 2001 From: Peter Zhelezniakov Date: Thu, 22 May 2008 15:06:22 +0400 Subject: [PATCH 1/9] 6606443: Infinite loop in FlowView.layout when using HTML tables in JEditorPane FlowStrategy.damageStart now tracks position changes Reviewed-by: gsm --- .../classes/javax/swing/text/FlowView.java | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/text/FlowView.java b/jdk/src/share/classes/javax/swing/text/FlowView.java index 39f8a5d6035..e784b33c576 100644 --- a/jdk/src/share/classes/javax/swing/text/FlowView.java +++ b/jdk/src/share/classes/javax/swing/text/FlowView.java @@ -333,17 +333,24 @@ public abstract class FlowView extends BoxView { * @since 1.3 */ public static class FlowStrategy { - int damageStart = Integer.MAX_VALUE; + Position damageStart = null; Vector viewBuffer; void addDamage(FlowView fv, int offset) { if (offset >= fv.getStartOffset() && offset < fv.getEndOffset()) { - damageStart = Math.min(damageStart, offset); + if (damageStart == null || offset < damageStart.getOffset()) { + try { + damageStart = fv.getDocument().createPosition(offset); + } catch (BadLocationException e) { + // shouldn't happen since offset is inside view bounds + assert(false); + } + } } } void unsetDamage() { - damageStart = Integer.MAX_VALUE; + damageStart = null; } /** @@ -438,13 +445,14 @@ public abstract class FlowView extends BoxView { int p1 = fv.getEndOffset(); if (fv.majorAllocValid) { - if (damageStart == Integer.MAX_VALUE) { + if (damageStart == null) { return; } // In some cases there's no view at position damageStart, so // step back and search again. See 6452106 for details. - while ((rowIndex = fv.getViewIndexAtPosition(damageStart)) < 0) { - damageStart--; + int offset = damageStart.getOffset(); + while ((rowIndex = fv.getViewIndexAtPosition(offset)) < 0) { + offset--; } if (rowIndex > 0) { rowIndex--; From f0fd6aa12c20ebc844573b47383b7fd1a19d1b46 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Fri, 23 May 2008 20:14:20 +0400 Subject: [PATCH 2/9] 6668273: Example given in java.beans.EventHandler shows incorrect order of parameters Very simple misprint Reviewed-by: peterz, loneid --- jdk/src/share/classes/java/beans/EventHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/beans/EventHandler.java b/jdk/src/share/classes/java/beans/EventHandler.java index 0a15ed8d826..9d50dea91d1 100644 --- a/jdk/src/share/classes/java/beans/EventHandler.java +++ b/jdk/src/share/classes/java/beans/EventHandler.java @@ -636,7 +636,7 @@ public class EventHandler implements InvocationHandler { * time a mouse button is pressed, one would write: *
*
-     *EventHandler.create(MouseListener.class, "mousePressed", target, "origin", "point");
+     *EventHandler.create(MouseListener.class, target, "origin", "point", "mousePressed");
      *
*
* From 44b0d9abbe570c5cfad0fc3a0137faade4537af1 Mon Sep 17 00:00:00 2001 From: Mikhail Lapshin Date: Mon, 26 May 2008 17:58:09 +0400 Subject: [PATCH 3/9] 6694823: A popup menu can be partially hidden under the task bar in applets In applets popup menu is shifted above the task bar Reviewed-by: peterz --- .../share/classes/javax/swing/JPopupMenu.java | 117 +++++++++++------ .../classes/javax/swing/PopupFactory.java | 61 +++++---- .../swing/JPopupMenu/6694823/bug6694823.java | 122 ++++++++++++++++++ 3 files changed, 229 insertions(+), 71 deletions(-) create mode 100644 jdk/test/javax/swing/JPopupMenu/6694823/bug6694823.java diff --git a/jdk/src/share/classes/javax/swing/JPopupMenu.java b/jdk/src/share/classes/javax/swing/JPopupMenu.java index b1cdd7db6af..4edf073cd8c 100644 --- a/jdk/src/share/classes/javax/swing/JPopupMenu.java +++ b/jdk/src/share/classes/javax/swing/JPopupMenu.java @@ -41,6 +41,7 @@ import javax.swing.plaf.PopupMenuUI; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicComboPopup; import javax.swing.event.*; +import sun.security.util.SecurityConstants; import java.applet.Applet; @@ -320,17 +321,67 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { * This adustment may be cancelled by invoking the application with * -Djavax.swing.adjustPopupLocationToFit=false */ - Point adjustPopupLocationToFitScreen(int xposition, int yposition) { - Point p = new Point(xposition, yposition); + Point adjustPopupLocationToFitScreen(int xPosition, int yPosition) { + Point popupLocation = new Point(xPosition, yPosition); - if(popupPostionFixDisabled == true || GraphicsEnvironment.isHeadless()) - return p; + if(popupPostionFixDisabled == true || GraphicsEnvironment.isHeadless()) { + return popupLocation; + } + // Get screen bounds + Rectangle scrBounds; + GraphicsConfiguration gc = getCurrentGraphicsConfiguration(popupLocation); Toolkit toolkit = Toolkit.getDefaultToolkit(); - Rectangle screenBounds; + if(gc != null) { + // If we have GraphicsConfiguration use it to get screen bounds + scrBounds = gc.getBounds(); + } else { + // If we don't have GraphicsConfiguration use primary screen + scrBounds = new Rectangle(toolkit.getScreenSize()); + } + + // Calculate the screen size that popup should fit + Dimension popupSize = JPopupMenu.this.getPreferredSize(); + int popupRightX = popupLocation.x + popupSize.width; + int popupBottomY = popupLocation.y + popupSize.height; + int scrWidth = scrBounds.width; + int scrHeight = scrBounds.height; + if (!canPopupOverlapTaskBar()) { + // Insets include the task bar. Take them into account. + Insets scrInsets = toolkit.getScreenInsets(gc); + scrBounds.x += scrInsets.left; + scrBounds.y += scrInsets.top; + scrWidth -= scrInsets.left + scrInsets.right; + scrHeight -= scrInsets.top + scrInsets.bottom; + } + int scrRightX = scrBounds.x + scrWidth; + int scrBottomY = scrBounds.y + scrHeight; + + // Ensure that popup menu fits the screen + if (popupRightX > scrRightX) { + popupLocation.x = scrRightX - popupSize.width; + if( popupLocation.x < scrBounds.x ) { + popupLocation.x = scrBounds.x ; + } + } + if (popupBottomY > scrBottomY) { + popupLocation.y = scrBottomY - popupSize.height; + if( popupLocation.y < scrBounds.y ) { + popupLocation.y = scrBounds.y; + } + } + + return popupLocation; + } + + /** + * Tries to find GraphicsConfiguration + * that contains the mouse cursor position. + * Can return null. + */ + private GraphicsConfiguration getCurrentGraphicsConfiguration( + Point popupLocation) { GraphicsConfiguration gc = null; - // Try to find GraphicsConfiguration, that includes mouse - // pointer position GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice[] gd = ge.getScreenDevices(); @@ -338,50 +389,36 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { if(gd[i].getType() == GraphicsDevice.TYPE_RASTER_SCREEN) { GraphicsConfiguration dgc = gd[i].getDefaultConfiguration(); - if(dgc.getBounds().contains(p)) { + if(dgc.getBounds().contains(popupLocation)) { gc = dgc; break; } } } - // If not found and we have invoker, ask invoker about his gc if(gc == null && getInvoker() != null) { gc = getInvoker().getGraphicsConfiguration(); } + return gc; + } - if(gc != null) { - // If we have GraphicsConfiguration use it to get - // screen bounds - screenBounds = gc.getBounds(); - } else { - // If we don't have GraphicsConfiguration use primary screen - screenBounds = new Rectangle(toolkit.getScreenSize()); + /** + * Checks that there are enough security permissions + * to make popup "always on top", which allows to show it above the task bar. + */ + static boolean canPopupOverlapTaskBar() { + boolean result = true; + try { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission( + SecurityConstants.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION); + } + } catch (SecurityException se) { + // There is no permission to show popups over the task bar + result = false; } - - Dimension size; - - size = JPopupMenu.this.getPreferredSize(); - - // Use long variables to prevent overflow - long pw = (long) p.x + (long) size.width; - long ph = (long) p.y + (long) size.height; - - if( pw > screenBounds.x + screenBounds.width ) - p.x = screenBounds.x + screenBounds.width - size.width; - - if( ph > screenBounds.y + screenBounds.height) - p.y = screenBounds.y + screenBounds.height - size.height; - - /* Change is made to the desired (X,Y) values, when the - PopupMenu is too tall OR too wide for the screen - */ - if( p.x < screenBounds.x ) - p.x = screenBounds.x ; - if( p.y < screenBounds.y ) - p.y = screenBounds.y; - - return p; + return result; } diff --git a/jdk/src/share/classes/javax/swing/PopupFactory.java b/jdk/src/share/classes/javax/swing/PopupFactory.java index 86b737750dd..7a934150f4f 100644 --- a/jdk/src/share/classes/javax/swing/PopupFactory.java +++ b/jdk/src/share/classes/javax/swing/PopupFactory.java @@ -548,47 +548,46 @@ public class PopupFactory { } /** - * Returns true if the Popup can fit on the screen. + * Returns true if popup can fit the screen and the owner's top parent. + * It determines can popup be lightweight or mediumweight. */ boolean fitsOnScreen() { + boolean result = false; Component component = getComponent(); - if (owner != null && component != null) { - Container parent; - int width = component.getWidth(); - int height = component.getHeight(); - for(parent = owner.getParent(); parent != null ; - parent = parent.getParent()) { - if (parent instanceof JFrame || - parent instanceof JDialog || - parent instanceof JWindow) { + Container parent = (Container) SwingUtilities.getRoot(owner); + int popupWidth = component.getWidth(); + int popupHeight = component.getHeight(); + Rectangle parentBounds = parent.getBounds(); + if (parent instanceof JFrame || + parent instanceof JDialog || + parent instanceof JWindow) { - Rectangle r = parent.getBounds(); - Insets i = parent.getInsets(); - r.x += i.left; - r.y += i.top; - r.width -= (i.left + i.right); - r.height -= (i.top + i.bottom); + Insets i = parent.getInsets(); + parentBounds.x += i.left; + parentBounds.y += i.top; + parentBounds.width -= i.left + i.right; + parentBounds.height -= i.top + i.bottom; - GraphicsConfiguration gc = parent.getGraphicsConfiguration(); + if (JPopupMenu.canPopupOverlapTaskBar()) { + GraphicsConfiguration gc = + parent.getGraphicsConfiguration(); Rectangle popupArea = getContainerPopupArea(gc); - return r.intersection(popupArea).contains(x, y, width, height); - - } else if (parent instanceof JApplet) { - Rectangle r = parent.getBounds(); - Point p = parent.getLocationOnScreen(); - - r.x = p.x; - r.y = p.y; - return r.contains(x, y, width, height); - } else if (parent instanceof Window || - parent instanceof Applet) { - // No suitable swing component found - break; + result = parentBounds.intersection(popupArea) + .contains(x, y, popupWidth, popupHeight); + } else { + result = parentBounds + .contains(x, y, popupWidth, popupHeight); } + } else if (parent instanceof JApplet) { + Point p = parent.getLocationOnScreen(); + parentBounds.x = p.x; + parentBounds.y = p.y; + result = parentBounds + .contains(x, y, popupWidth, popupHeight); } } - return false; + return result; } Rectangle getContainerPopupArea(GraphicsConfiguration gc) { diff --git a/jdk/test/javax/swing/JPopupMenu/6694823/bug6694823.java b/jdk/test/javax/swing/JPopupMenu/6694823/bug6694823.java new file mode 100644 index 00000000000..2388137a3af --- /dev/null +++ b/jdk/test/javax/swing/JPopupMenu/6694823/bug6694823.java @@ -0,0 +1,122 @@ +/* + * Copyright 2008 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 6694823 + * @summary Checks that popup menu cannot be partially hidden + * by the task bar in applets. + * @author Mikhail Lapshin + * @run main bug6694823 + */ + +import javax.swing.*; +import java.awt.*; +import sun.awt.SunToolkit; + +public class bug6694823 { + private static JFrame frame; + private static JPopupMenu popup; + private static SunToolkit toolkit; + private static Insets screenInsets; + + public static void main(String[] args) throws Exception { + toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + createGui(); + } + }); + + // Get screen insets + screenInsets = toolkit.getScreenInsets(frame.getGraphicsConfiguration()); + if (screenInsets.bottom == 0) { + // This test is only for configurations with taskbar on the bottom + return; + } + + // Show popup as if from a standalone application + // The popup should be able to overlap the task bar + showPopup(false); + + // Emulate applet security restrictions + toolkit.realSync(); + System.setSecurityManager(new SecurityManager()); + + // Show popup as if from an applet + // The popup shouldn't overlap the task bar. It should be shifted up. + showPopup(true); + + toolkit.realSync(); + System.out.println("Test passed!"); + frame.dispose(); + } + + private static void createGui() { + frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.setUndecorated(true); + + popup = new JPopupMenu("Menu"); + for (int i = 0; i < 7; i++) { + popup.add(new JMenuItem("MenuItem")); + } + JPanel panel = new JPanel(); + panel.setComponentPopupMenu(popup); + frame.add(panel); + + frame.setSize(200, 200); + } + + private static void showPopup(final boolean shouldBeShifted) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + // Place frame just above the task bar + Dimension screenSize = toolkit.getScreenSize(); + frame.setLocation(screenSize.width / 2, + screenSize.height - frame.getHeight() - screenInsets.bottom); + frame.setVisible(true); + + // Place popup over the task bar + Point frameLoc = frame.getLocationOnScreen(); + int x = 0; + int y = frame.getHeight() + - popup.getPreferredSize().height + screenInsets.bottom; + popup.show(frame, x, y); + + if (shouldBeShifted) { + if (popup.getLocationOnScreen() + .equals(new Point(frameLoc.x, frameLoc.y + y))) { + throw new RuntimeException("Popup is not shifted"); + } + } else { + if (!popup.getLocationOnScreen() + .equals(new Point(frameLoc.x, frameLoc.y + y))) { + throw new RuntimeException("Popup is unexpectedly shifted"); + } + } + popup.setVisible(false); + } + }); + } +} From 2ae586bafcdfc13b1aede1ce146aebcecd6f217c Mon Sep 17 00:00:00 2001 From: Pavel Porvatov Date: Mon, 2 Jun 2008 19:08:13 +0400 Subject: [PATCH 4/9] 6709530: There are unnecessary code in slider classes, such as in JSlider and SliderUIs Removed unnecessary code like unused variables, castings, imports etc Reviewed-by: peterz --- .../share/classes/javax/swing/JSlider.java | 43 ++++++++----------- .../javax/swing/plaf/basic/BasicSliderUI.java | 40 ++++++----------- .../javax/swing/plaf/synth/SynthSliderUI.java | 30 +++---------- 3 files changed, 39 insertions(+), 74 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/JSlider.java b/jdk/src/share/classes/javax/swing/JSlider.java index e1a7909b073..95b49164b9a 100644 --- a/jdk/src/share/classes/javax/swing/JSlider.java +++ b/jdk/src/share/classes/javax/swing/JSlider.java @@ -25,14 +25,12 @@ package javax.swing; -import javax.swing.border.*; import javax.swing.event.*; import javax.swing.plaf.*; import javax.accessibility.*; import java.io.Serializable; import java.io.ObjectOutputStream; -import java.io.ObjectInputStream; import java.io.IOException; import java.awt.Color; @@ -409,8 +407,7 @@ public class JSlider extends JComponent implements SwingConstants, Accessible { * @since 1.4 */ public ChangeListener[] getChangeListeners() { - return (ChangeListener[])listenerList.getListeners( - ChangeListener.class); + return listenerList.getListeners(ChangeListener.class); } @@ -826,17 +823,16 @@ public class JSlider extends JComponent implements SwingConstants, Accessible { * @see JComponent#updateUI */ protected void updateLabelUIs() { - if ( getLabelTable() == null ) { + Dictionary labelTable = getLabelTable(); + + if (labelTable == null) { return; } - Enumeration labels = getLabelTable().keys(); + Enumeration labels = labelTable.keys(); while ( labels.hasMoreElements() ) { - Object value = getLabelTable().get( labels.nextElement() ); - if ( value instanceof JComponent ) { - JComponent component = (JComponent)value; - component.updateUI(); - component.setSize( component.getPreferredSize() ); - } + JComponent component = (JComponent) labelTable.get(labels.nextElement()); + component.updateUI(); + component.setSize(component.getPreferredSize()); } } @@ -845,11 +841,8 @@ public class JSlider extends JComponent implements SwingConstants, Accessible { if (labelTable != null) { Enumeration labels = labelTable.elements(); while (labels.hasMoreElements()) { - Object value = labels.nextElement(); - if (value instanceof JComponent) { - JComponent component = (JComponent)value; - component.setSize(component.getPreferredSize()); - } + JComponent component = (JComponent) labels.nextElement(); + component.setSize(component.getPreferredSize()); } } } @@ -960,14 +953,14 @@ public class JSlider extends JComponent implements SwingConstants, Accessible { if ( e.getPropertyName().equals( "minimum" ) || e.getPropertyName().equals( "maximum" ) ) { - Enumeration keys = getLabelTable().keys(); - Object key = null; + Dictionary labelTable = getLabelTable(); + Enumeration keys = labelTable.keys(); Hashtable hashtable = new Hashtable(); // Save the labels that were added by the developer while ( keys.hasMoreElements() ) { - key = keys.nextElement(); - Object value = getLabelTable().get( key ); + Object key = keys.nextElement(); + Object value = labelTable.get(key); if ( !(value instanceof LabelUIResource) ) { hashtable.put( key, value ); } @@ -979,7 +972,7 @@ public class JSlider extends JComponent implements SwingConstants, Accessible { // Add the saved labels keys = hashtable.keys(); while ( keys.hasMoreElements() ) { - key = keys.nextElement(); + Object key = keys.nextElement(); put( key, hashtable.get( key ) ); } @@ -996,8 +989,10 @@ public class JSlider extends JComponent implements SwingConstants, Accessible { SmartHashtable table = new SmartHashtable( increment, start ); - if ( getLabelTable() != null && (getLabelTable() instanceof PropertyChangeListener) ) { - removePropertyChangeListener( (PropertyChangeListener)getLabelTable() ); + Dictionary labelTable = getLabelTable(); + + if (labelTable != null && (labelTable instanceof PropertyChangeListener)) { + removePropertyChangeListener((PropertyChangeListener) labelTable); } addPropertyChangeListener( table ); diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java index c1aada74441..2b604301761 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java @@ -26,14 +26,11 @@ package javax.swing.plaf.basic; import java.awt.Component; -import java.awt.Container; -import java.awt.Adjustable; import java.awt.event.*; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Dimension; import java.awt.Rectangle; -import java.awt.Point; import java.awt.Insets; import java.awt.Color; import java.awt.IllegalComponentStateException; @@ -42,8 +39,6 @@ import java.beans.*; import java.util.Dictionary; import java.util.Enumeration; -import javax.swing.border.AbstractBorder; - import javax.swing.*; import javax.swing.event.*; import javax.swing.plaf.*; @@ -409,7 +404,7 @@ public class BasicSliderUI extends SliderUI{ Enumeration elements = dictionary.elements(); int baseline = -1; while (elements.hasMoreElements()) { - Component label = (Component)elements.nextElement(); + JComponent label = (JComponent) elements.nextElement(); Dimension pref = label.getPreferredSize(); int labelBaseline = label.getBaseline(pref.width, pref.height); @@ -634,7 +629,7 @@ public class BasicSliderUI extends SliderUI{ protected void calculateTrackRect() { - int centerSpacing = 0; // used to center sliders added using BorderLayout.CENTER (bug 4275631) + int centerSpacing; // used to center sliders added using BorderLayout.CENTER (bug 4275631) if ( slider.getOrientation() == JSlider.HORIZONTAL ) { centerSpacing = thumbRect.height; if ( slider.getPaintTicks() ) centerSpacing += getTickLength(); @@ -764,7 +759,7 @@ public class BasicSliderUI extends SliderUI{ if ( dictionary != null ) { Enumeration keys = dictionary.keys(); while ( keys.hasMoreElements() ) { - Component label = (Component)dictionary.get( keys.nextElement() ); + JComponent label = (JComponent) dictionary.get(keys.nextElement()); widest = Math.max( label.getPreferredSize().width, widest ); } } @@ -777,7 +772,7 @@ public class BasicSliderUI extends SliderUI{ if ( dictionary != null ) { Enumeration keys = dictionary.keys(); while ( keys.hasMoreElements() ) { - Component label = (Component)dictionary.get( keys.nextElement() ); + JComponent label = (JComponent) dictionary.get(keys.nextElement()); tallest = Math.max( label.getPreferredSize().height, tallest ); } } @@ -1001,22 +996,14 @@ public class BasicSliderUI extends SliderUI{ public void paintTicks(Graphics g) { Rectangle tickBounds = tickRect; - int i; - int maj, min, max; - int w = tickBounds.width; - int h = tickBounds.height; - int centerEffect, tickHeight; g.setColor(DefaultLookup.getColor(slider, this, "Slider.tickColor", Color.black)); - maj = slider.getMajorTickSpacing(); - min = slider.getMinorTickSpacing(); - if ( slider.getOrientation() == JSlider.HORIZONTAL ) { g.translate( 0, tickBounds.y); int value = slider.getMinimum(); - int xPos = 0; + int xPos; if ( slider.getMinorTickSpacing() > 0 ) { while ( value <= slider.getMaximum() ) { @@ -1042,7 +1029,7 @@ public class BasicSliderUI extends SliderUI{ g.translate(tickBounds.x, 0); int value = slider.getMinimum(); - int yPos = 0; + int yPos; if ( slider.getMinorTickSpacing() > 0 ) { int offset = 0; @@ -1111,10 +1098,9 @@ public class BasicSliderUI extends SliderUI{ Integer key = (Integer)keys.nextElement(); int value = key.intValue(); if (value >= minValue && value <= maxValue) { - Component label = (Component)dictionary.get( key ); - if (label instanceof JComponent) { - ((JComponent)label).setEnabled(enabled); - } + JComponent label = (JComponent) dictionary.get(key); + label.setEnabled(enabled); + if ( slider.getOrientation() == JSlider.HORIZONTAL ) { g.translate( 0, labelBounds.y ); paintHorizontalLabel( g, value, label ); @@ -1364,7 +1350,7 @@ public class BasicSliderUI extends SliderUI{ int min = slider.getMinimum(); int max = slider.getMaximum(); double valueRange = (double)max - (double)min; - double pixelsPerValue = (double)trackHeight / (double)valueRange; + double pixelsPerValue = (double)trackHeight / valueRange; int trackBottom = trackY + (trackHeight - 1); int yPosition; @@ -1715,7 +1701,7 @@ public class BasicSliderUI extends SliderUI{ * of the thumb relative to the origin of the track. */ public void mouseDragged(MouseEvent e) { - int thumbMiddle = 0; + int thumbMiddle; if (!slider.isEnabled()) { return; @@ -1841,7 +1827,7 @@ public class BasicSliderUI extends SliderUI{ public void componentResized(ComponentEvent e) { getHandler().componentResized(e); } - }; + } /** * Focus-change listener. @@ -1903,7 +1889,7 @@ public class BasicSliderUI extends SliderUI{ return b; } - }; + } /** diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthSliderUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthSliderUI.java index 0cf5ed22648..c8d5a0959ae 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthSliderUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthSliderUI.java @@ -25,26 +25,17 @@ package javax.swing.plaf.synth; -import java.awt.Component; -import java.awt.Container; -import java.awt.Adjustable; import java.awt.event.*; import java.awt.Graphics; import java.awt.Dimension; -import java.awt.Font; import java.awt.FontMetrics; import java.awt.Rectangle; import java.awt.Point; import java.awt.Insets; -import java.awt.Color; -import java.awt.IllegalComponentStateException; -import java.awt.Polygon; import java.beans.*; import java.util.Dictionary; import java.util.Enumeration; -import javax.swing.border.AbstractBorder; import javax.swing.*; -import javax.swing.event.*; import javax.swing.plaf.*; import javax.swing.plaf.basic.BasicSliderUI; import sun.swing.plaf.synth.SynthUI; @@ -203,8 +194,7 @@ class SynthSliderUI extends BasicSliderUI implements PropertyChangeListener, centerY += valueHeight + 2; centerY += trackHeight + trackInsets.top + trackInsets.bottom; centerY += tickHeight + 2; - Component label = (Component)slider.getLabelTable(). - elements().nextElement(); + JComponent label = (JComponent) slider.getLabelTable().elements().nextElement(); Dimension pref = label.getPreferredSize(); return centerY + label.getBaseline(pref.width, pref.height); } @@ -226,8 +216,7 @@ class SynthSliderUI extends BasicSliderUI implements PropertyChangeListener, int trackHeight = contentHeight - valueHeight; int yPosition = yPositionForValue(value.intValue(), trackY, trackHeight); - Component label = (Component)slider.getLabelTable(). - get(value); + JComponent label = (JComponent) slider.getLabelTable().get(value); Dimension pref = label.getPreferredSize(); return yPosition - pref.height / 2 + label.getBaseline(pref.width, pref.height); @@ -434,16 +423,14 @@ class SynthSliderUI extends BasicSliderUI implements PropertyChangeListener, /** * Calculates the pad for the label at the specified index. * - * @param index index of the label to calculate pad for. + * @param i index of the label to calculate pad for. * @return padding required to keep label visible. */ private int getPadForLabel(int i) { - Dictionary dictionary = slider.getLabelTable(); int pad = 0; - Object o = dictionary.get(i); - if (o != null) { - Component c = (Component)o; + JComponent c = (JComponent) slider.getLabelTable().get(i); + if (c != null) { int centerX = xPositionForValue(i); int cHalfWidth = c.getPreferredSize().width / 2; if (centerX - cHalfWidth < insetCache.left) { @@ -500,8 +487,6 @@ class SynthSliderUI extends BasicSliderUI implements PropertyChangeListener, } } - private static Rectangle unionRect = new Rectangle(); - public void setThumbLocation(int x, int y) { super.setThumbLocation(x, y); // Value rect is tied to the thumb location. We need to repaint when @@ -544,7 +529,7 @@ class SynthSliderUI extends BasicSliderUI implements PropertyChangeListener, trackBorder; int trackLength = trackBottom - trackTop; double valueRange = (double)max - (double)min; - double pixelsPerValue = (double)trackLength / (double)valueRange; + double pixelsPerValue = (double)trackLength / valueRange; int yPosition; if (!drawInverted()) { @@ -802,8 +787,7 @@ class SynthSliderUI extends BasicSliderUI implements PropertyChangeListener, } public void mouseDragged(MouseEvent e) { - SynthScrollBarUI ui; - int thumbMiddle = 0; + int thumbMiddle; if (!slider.isEnabled()) { return; From cda549c2c280ed548079f795ef0efbefa7546ccb Mon Sep 17 00:00:00 2001 From: Pavel Porvatov Date: Tue, 3 Jun 2008 18:00:04 +0400 Subject: [PATCH 5/9] 4987336: JSlider doesn't show label's animated icon JSlider registers as an image observer of label's icon Reviewed-by: alexp --- .../share/classes/javax/swing/JSlider.java | 30 ++++- .../javax/swing/plaf/basic/BasicSliderUI.java | 20 +-- jdk/test/javax/swing/JSlider/4987336/box.gif | Bin 0 -> 4241 bytes .../swing/JSlider/4987336/bug4987336.html | 9 ++ .../swing/JSlider/4987336/bug4987336.java | 120 ++++++++++++++++++ .../javax/swing/JSlider/4987336/cupanim.gif | Bin 0 -> 5856 bytes 6 files changed, 168 insertions(+), 11 deletions(-) create mode 100644 jdk/test/javax/swing/JSlider/4987336/box.gif create mode 100644 jdk/test/javax/swing/JSlider/4987336/bug4987336.html create mode 100644 jdk/test/javax/swing/JSlider/4987336/bug4987336.java create mode 100644 jdk/test/javax/swing/JSlider/4987336/cupanim.gif diff --git a/jdk/src/share/classes/javax/swing/JSlider.java b/jdk/src/share/classes/javax/swing/JSlider.java index 95b49164b9a..d436f32f1a6 100644 --- a/jdk/src/share/classes/javax/swing/JSlider.java +++ b/jdk/src/share/classes/javax/swing/JSlider.java @@ -33,8 +33,7 @@ import java.io.Serializable; import java.io.ObjectOutputStream; import java.io.IOException; -import java.awt.Color; -import java.awt.Font; +import java.awt.*; import java.util.*; import java.beans.*; @@ -761,6 +760,33 @@ public class JSlider extends JComponent implements SwingConstants, Accessible { updateLabelSizes(); } + /** + * {@inheritDoc} + * @since 1.7 + */ + public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) { + if (!isShowing()) { + return false; + } + + // Check that there is a label with such image + Enumeration elements = labelTable.elements(); + + while (elements.hasMoreElements()) { + Component component = (Component) elements.nextElement(); + + if (component instanceof JLabel) { + JLabel label = (JLabel) component; + + if (SwingUtilities.doesIconReferenceImage(label.getIcon(), img) || + SwingUtilities.doesIconReferenceImage(label.getDisabledIcon(), img)) { + return super.imageUpdate(img, infoflags, x, y, w, h); + } + } + } + + return false; + } /** * Returns the dictionary of what labels to draw at which values. diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java index 2b604301761..635efb04433 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java @@ -25,16 +25,8 @@ package javax.swing.plaf.basic; -import java.awt.Component; import java.awt.event.*; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.awt.Dimension; -import java.awt.Rectangle; -import java.awt.Insets; -import java.awt.Color; -import java.awt.IllegalComponentStateException; -import java.awt.Polygon; +import java.awt.*; import java.beans.*; import java.util.Dictionary; import java.util.Enumeration; @@ -1101,6 +1093,16 @@ public class BasicSliderUI extends SliderUI{ JComponent label = (JComponent) dictionary.get(key); label.setEnabled(enabled); + if (label instanceof JLabel) { + Icon icon = label.isEnabled() ? ((JLabel) label).getIcon() : ((JLabel) label).getDisabledIcon(); + + if (icon instanceof ImageIcon) { + // Register Slider as an image observer. It allows to catch notifications about + // image changes (e.g. gif animation) + Toolkit.getDefaultToolkit().checkImage(((ImageIcon) icon).getImage(), -1, -1, slider); + } + } + if ( slider.getOrientation() == JSlider.HORIZONTAL ) { g.translate( 0, labelBounds.y ); paintHorizontalLabel( g, value, label ); diff --git a/jdk/test/javax/swing/JSlider/4987336/box.gif b/jdk/test/javax/swing/JSlider/4987336/box.gif new file mode 100644 index 0000000000000000000000000000000000000000..69d8cdf9d423958daffe16554e41e68b08095bd2 GIT binary patch literal 4241 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 ZW6uKqw&9Cgn!0ubx$%}eyFozY{{a+l1oQv^ literal 0 HcmV?d00001 diff --git a/jdk/test/javax/swing/JSlider/4987336/bug4987336.html b/jdk/test/javax/swing/JSlider/4987336/bug4987336.html new file mode 100644 index 00000000000..b5c9a191f56 --- /dev/null +++ b/jdk/test/javax/swing/JSlider/4987336/bug4987336.html @@ -0,0 +1,9 @@ + + + +There are four Sliders. Each of them has a label with animated gif (a cup of coffee) +and a label with static image. + +Check that for every LAF animation works for all Sliders. + + diff --git a/jdk/test/javax/swing/JSlider/4987336/bug4987336.java b/jdk/test/javax/swing/JSlider/4987336/bug4987336.java new file mode 100644 index 00000000000..0e0e373034a --- /dev/null +++ b/jdk/test/javax/swing/JSlider/4987336/bug4987336.java @@ -0,0 +1,120 @@ +/* + * 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 4987336 + @summary JSlider doesn't show label's animated icon. + @author Pavel Porvatov + @run applet/manual=done bug4987336.html +*/ + +import javax.swing.*; +import javax.swing.border.TitledBorder; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Hashtable; + +public class bug4987336 extends JApplet { + private static final String IMAGE_RES = "box.gif"; + + private static final String ANIM_IMAGE_RES = "cupanim.gif"; + + public void init() { + JPanel pnLafs = new JPanel(); + pnLafs.setLayout(new BoxLayout(pnLafs, BoxLayout.Y_AXIS)); + + ButtonGroup group = new ButtonGroup(); + + pnLafs.setBorder(new TitledBorder("Available Lafs")); + + for (UIManager.LookAndFeelInfo lafInfo : UIManager.getInstalledLookAndFeels()) { + LafRadioButton comp = new LafRadioButton(lafInfo); + + pnLafs.add(comp); + group.add(comp); + } + + JPanel pnContent = new JPanel(); + + pnContent.setLayout(new BoxLayout(pnContent, BoxLayout.Y_AXIS)); + + pnContent.add(pnLafs); + pnContent.add(createSlider(true, IMAGE_RES, IMAGE_RES, ANIM_IMAGE_RES, ANIM_IMAGE_RES)); + pnContent.add(createSlider(false, IMAGE_RES, IMAGE_RES, ANIM_IMAGE_RES, ANIM_IMAGE_RES)); + pnContent.add(createSlider(true, ANIM_IMAGE_RES, null, IMAGE_RES, IMAGE_RES)); + pnContent.add(createSlider(false, ANIM_IMAGE_RES, null, IMAGE_RES, IMAGE_RES)); + + getContentPane().add(new JScrollPane(pnContent)); + } + + private static JSlider createSlider(boolean enabled, + String firstEnabledImage, String firstDisabledImage, + String secondEnabledImage, String secondDisabledImage) { + Hashtable dictionary = new Hashtable(); + + dictionary.put(0, createLabel(firstEnabledImage, firstDisabledImage)); + dictionary.put(1, createLabel(secondEnabledImage, secondDisabledImage)); + + JSlider result = new JSlider(0, 1); + + result.setLabelTable(dictionary); + result.setPaintLabels(true); + result.setEnabled(enabled); + + return result; + } + + private static JLabel createLabel(String enabledImage, String disabledImage) { + ImageIcon enabledIcon = enabledImage == null ? null : + new ImageIcon(bug4987336.class.getResource(enabledImage)); + + ImageIcon disabledIcon = disabledImage == null ? null : + new ImageIcon(bug4987336.class.getResource(disabledImage)); + + JLabel result = new JLabel(enabledImage == null && disabledImage == null ? "No image" : "Image", + enabledIcon, SwingConstants.LEFT); + + result.setDisabledIcon(disabledIcon); + + return result; + } + + private class LafRadioButton extends JRadioButton { + public LafRadioButton(final UIManager.LookAndFeelInfo lafInfo) { + super(lafInfo.getName(), lafInfo.getName().equals(UIManager.getLookAndFeel().getName())); + + addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + UIManager.setLookAndFeel(lafInfo.getClassName()); + + SwingUtilities.updateComponentTreeUI(bug4987336.this); + } catch (Exception ex) { + // Ignore such errors + System.out.println("Cannot set LAF " + lafInfo.getName()); + } + } + }); + } + } +} diff --git a/jdk/test/javax/swing/JSlider/4987336/cupanim.gif b/jdk/test/javax/swing/JSlider/4987336/cupanim.gif new file mode 100644 index 0000000000000000000000000000000000000000..934d093c580e5690a29612b5fc15ee46e5696058 GIT binary patch literal 5856 zcmZWtcT^K;`<*~YK_DRoLJvJOMNp(_ARtwwO2>ed(5r-QNC83-2whr0dJ_;71Xg+n zK`dZd0V~3~xa#h@?k+#v^A-Jl^ViHXbLQN0?|t6)d9S(UX^6M!9X9RchgTnh{P z<>mVU0sGq8`vCCm)4{v_{qp_&fc<^#{r#^W%kCetHFI(#8QYm@9oFOp0RSNT8O+BI zAOQ7)d*JJD0r20*8Oyd|-JQk3eKO&4DY3drldCR*46}i=LJ?h0A(O4wne=U{I3{|c zpc`qSdT1<*yS*^PB@qGhjuNhYnC4EOdO1qI)}s@g$5HF~Dg9M^8QSp&Xu&l*XnEc5n{{##cm>rYI!NKO0XXhrQheyY;kh%MFo3Q6EUaoH45q(H_H2Uf# zbbL+hNB9lVRjAg8`s%{bC0$Cz3E3LKkhvdo4~g2!T#EuWY6iksIr9r_MUVG=CHf>`IPDJ>lqjB+zRz6Zb=HUJQ&XO;sP49{IE*Szpv9)*M;n2oO=w*rH*f_Tj~XQs>tQfH zt^zUNx0&_aFF)*Dzde6Z*JyB)XUJ40=5F2SPK;=U|NU~kC4mn=DcJ@3^U>)3N={+G zSChDac%o2He=*^2;6Z^yfC^ypKMwZ`s;0Dds^f-C)aMz?;U-5bjV1lkK*ptS1uvV^ zIgx+1Bx=7tqnFRqag{FQ0T+Q0(jqODTp}p!O`2~1Gw66gu0`)l97*axo1ap!aE9VV zIB*G;kRBHm6Pli!85$>F8_(N49UGHF$OzKiH$%m)6ZxX=4=E zybDvl#CV1&dLPz0{iyU^+!KKYiK*?H(PS#*LCCAd)qcH}UuPJ6Ic1aCxTmfk@ZtA+ z^6uc31wd%j$P7p6HrLRN(@-YvsV=ZAw`pd>ubx3!=^>5Ta8S08wa+Y?;86!x6Jc&) zy{(EN2yEGNUD>u+BpRbD?%XOO;T7vn)+>Pl8VY?=P9ABy)*w*&$7KEuWxfidUh=GE zZ!5UN;KhS`>(pyjBbv9W|I+HEp{p$3c=KsrA8~HW?>>BEE>4TKq@suB8%*G#z$wG2 zX&&oueXpQZ_xHB?O&<2AEJFU;68}xK?p!bD?_`Da@D{N$)zL84uKBFYb5uWD>kRli ziLnO~>wcAZZ`SfWj&yHv@DiVJvY(qE81BgoC^41XlW4pz!dd*~;}pEW>>h5^Fmw^o8$4itc4me0a&gmT7X@)UlX%JZ z2rVs?>5n#&jz+Q3wyvfSxK|<8*3;BkKljL$3`@I4>2uAJ1^FG`dO&$I^BVP3?wJN9 zTZUBXNy@b{_()y5^(-`DAt7v9D%$#teje5926_Zx^k68g;28aEe>$*wZHsl^d2yZd z_MMNDX?u^r3f;5wnqmFMU8 zKw2^@H?|ljeBpIktk;1@xXdWJKnHf0{p@gcz09ME=a%SpqK26-Bo~-{^ zj%mrcW)(R8KEDceAs+w9c)I;CtD0aj%C}78hjJH{s#P- zi?BzMmifjCIeVJOSPg`R0I%UGA3E3SbpfAF^$3?3s$a9*{BiZUSf{hX%V6Dj1d7); zN7JsAJYn3nqlC&++X^djQr=b4m9CNBGrEW(Cn&&^5UDgbOe7ngntxf^H$OYakr9!J za64Bf;&L8aTp4Es^|!keRe=YR=$e@q8p|>5Q9X8pH-B(|7)jOLILneAxS4dmX;YYm4<8(rdN9*1q;mHtmmZ zF{=~0&VV8QcAx3m#DI7uttu_Lx0soHwnKY(+K8DrRX07KD_ctx%G9&KWX{y_qGV8} zafKW2p$NrO4h{v#m9g$@Q@_rBf4Qr0p=o{k?&makmKe4ywR!u+Yg&y_>>s|ImL@xX zr-pm=quA4zoBU4^HDvn~7Wt)=nGIXd+XO)8NgEpX>P8->lO8!>)a}#F;NLH9-#XtP zhJU8=2h5p}J^|!7*&!*`g1hoGXS{%!Y`@`e0>!Qox&yJ7rM8enM}5cA)tKNx!OoGE zIP0VMAD|=%nNWdvbL@}zRXNkeBspOb>tgDJf%f~mf)t1cJv4f6>N^JGyWFVw+s5@K}gs5rtx^*)*Ws)!w zFwOFx*GTTqtvY}2z8ut)7QA?yv}VX0UAjE+)O`Q}Z%;x$n|v4U4Foo0m@pL=H^l;L{Nc(%?9V-AZzK2CqBIZ& z+21t==3pJt|JORSBcQWmG>J1Iq~9H>qO=B7BLSia4BTBE$^AJd^J$ZGm~l)PkijT+ckJ zdu{IUl@aBpF=et^{bZycx<@UUJUxpT@XAt!!Qo58Pf(BGt7EfE>yKBrh`{oX2nhLc zOml8Ax=kW;@cx5J)Nj~*htRF!sq-TOeMKssGm(cz(-lLBmHiV?q=3E?q1=uJpbo_V zJf^kF@1LjhC@NSK#cwf~Jh;=40i33YHOgD?3@0 zPaTZC7@dF(i-5zZX$d*3R3E=gzd~PhU}{eA<xmCh>STI z+!mr7PVFWDaaRfC!odE@(ZFhNR35o%+O)%ic5B!w(saPg=Ux+Lw5iNHZ(=^Ee4%IX z!SYLVSTTCNtJkDvhB%FzateD_!MeSTM@`(ek>%y1QXfApaVR7s!xiR3rOgilQzH3Z0|DX z%TUgl8@fIuA&h(I8-==_2Sv&V_tT#uotRc~9tI=oS5{1yiXDH5UgIz1S;WXaid#Oa zLwka@zmjic|FN?GND@_&)pES*BWxpd+s;t-8$F-^1|a;mExb+X2lYH{Em{Q;)Yv$ULwdiA@Nl0E8p`&kIX1et|W z>KN-xlFNP%XtUvLNjh6F8-S z;r_D0Dk|k2TKN2#C}5jw8UxBy*?hs@WXPR+vfjYB$I*7~%i`t8O6InYG) zKRvP|u=aMb3CF-EIxkl_8FNubyIy~RfdCsFT8h#_RvCHk6@$;z;zc{`&?lWX<-#!r zyivSLvrIs^d!q|XCX~u#^d{y~ZVKA;Y$nYa2|!J^mb5bNm?glVF=@V(@NfhyTY`~+ z3JejaxyA<-i$l>Bj*uL)RB})(Au^X7px35DEe*=o)r;{z(a_x)P}kI5THY@bKh&5J z&t)gjx#;OYq&4CQNY-Z05JB}PN>ONwn2n9#7Q z{1*K@oVjACny1}zR2?mcgD`AmevYy5@#JO~WKiIfMX@rb znP#BuR8>ER=o|IDCg=lA{@Fgho|uX^-!4YrOq4I*C;Iulg@c7#eUUK6I-QWba$Fk2 zO0!iUAl1Pe_!IY%!3)H@zXwPA75gspR~#K6vwbSHB#}_YQnG~tvPwr^fH-tK?B2Sb9cg94kgNQ6eRfoe2#}%A?21$3f)-$Z?T!(Q+vz=n92|a85dtS?QbJ zSl`ikBZ5*=M7|I@Tt0Fp?7GOrxok>N0c$Gc=AG~^&Ct6*Kvrk^CH?5dGu5=V(Fd@J zwSjXf8B-5$vghX5>yJ@^dG9ms6c*F2KKFfyDYnLLBMq%Gdupv8?vRf}?8{mGDOX^E zlEtbi=y6u+3NHU3t>?=%CbOC1&W39QI1N&mi*g0Z-SFcWejUJ~w#Bq*Di1i!&s}k} z7AiZHY*PzcZ8Fa>QZ)7V#lY>_a20t|W5X&Dz5xF(yxzx>ET0KyPb-TJz7qku>8pB}<{y>BgQ?VXdo0 zDz(3snOwczV7WDE8$W+OK2%7Q>mTFdDfVh%d}rdYvc^D?HIRacb-M&G0w{JAK6Z)~ zFT2Q^FI2y%h{Tg0bBS1VF`_6u!u(1SxTS>JoOJ|ISHeW|7UuW%`Ozu|1J5Mhb~ryi zIX*KxH@~pBbZ2?x?&`h!4<4?qKYILx=f|baCtJpfUZAWW?Lf~0Z&o2d(C2x)Ppu@YR2VN7;JiBF~-f<07VQb7|T@asJFR!Sn4b&&9PUU>jJ#z zw-D-J%HpZVp8L_-b6u-cFRMB^E1yN6sDC-PE<}qYFxga6Y&t(w_i33L%cJr)MHdSj zEcjw_fca_aMT`;AQWnHeI|YRl$Y_xqu0XyfQr|+t9zYWQPu4No+|OAshD)7;$zpR} zDsWYZ$v?UEhIcoRMj^cH4js!S7f>qC5xGf1zKXJ*2QhARh~8JR?ap^Hgr$l@W0Sgy zN=5J<*0BL%>QbF=mN~^@3-qNA)bPVeE-7d*9v#ibGB2tqCrKF{%fWt&<0~~7K=Oc^ zk$QfWC%6UjYR*>oRHw73fXEm6-(xTKVV;v%d611Et&U8;&09 ze2)|~@t*1oZb6S6Io1T8|C_zEqJ9nLh9h6!{Z2&-zBiRv+#`v}RPFVT1~G-A4{mdZ zBR~DZjrVr<4D)sY8M9QaQI^SaI_8%CVjv9y4hj+HP0^D29uW9|A@Ku1u?K)uT67t8 z2C&Lf!BW>Wh9#eAb85#PkBR-v&*bOIQ}1w~gKP&2OUptI1WTRma9UNW!m&|-eH3fe zu*2b_9xD#PCvpn~Ttjj~HIw*?Xw6mbmORo_-*e<7F%563mozwulFD}0U|iCrsX7GV zz6FB$$Ho7S#~PY(*%e=KUgk6(EXGq$(2Q$qVmx$i9F#MNVU>b-mCudFRH2C&9<_qJ z*}GNdt|6%9N}J4- v#)*z&!PadtV#i)e2ZqW>d8KNF>1BpFW9_ARsG>Srj`~`MOSNcU4Q%j#O>kr* literal 0 HcmV?d00001 From 86031542b2e73fbbef1359244e672811ca90f7fc Mon Sep 17 00:00:00 2001 From: Pavel Porvatov Date: Wed, 4 Jun 2008 18:48:42 +0400 Subject: [PATCH 6/9] 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native Now sun.awt.shell.ShellFolder#sort uses system sorting instead of alphabetical Reviewed-by: loneid, peterz --- .../swing/plaf/basic/BasicDirectoryModel.java | 2 +- .../classes/sun/awt/shell/ShellFolder.java | 167 +++++++++++++++++- .../sun/awt/shell/ShellFolderManager.java | 144 --------------- .../sun/awt/shell/Win32ShellFolder2.java | 29 +-- .../awt/shell/Win32ShellFolderManager2.java | 53 +----- 5 files changed, 186 insertions(+), 209 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java index 06b4dc5b6e4..6bc400f9781 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java @@ -196,7 +196,7 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh } protected void sort(Vector v){ - ShellFolder.sortFiles(v); + ShellFolder.sort(v); } // Obsolete - not used diff --git a/jdk/src/share/classes/sun/awt/shell/ShellFolder.java b/jdk/src/share/classes/sun/awt/shell/ShellFolder.java index fe891c6ca16..21c2d129d7d 100644 --- a/jdk/src/share/classes/sun/awt/shell/ShellFolder.java +++ b/jdk/src/share/classes/sun/awt/shell/ShellFolder.java @@ -25,6 +25,7 @@ package sun.awt.shell; +import javax.swing.*; import java.awt.Image; import java.awt.Toolkit; import java.io.*; @@ -37,6 +38,10 @@ import java.util.*; */ public abstract class ShellFolder extends File { + private static final String COLUMN_NAME = "FileChooser.fileNameHeaderText"; + private static final String COLUMN_SIZE = "FileChooser.fileSizeHeaderText"; + private static final String COLUMN_DATE = "FileChooser.fileDateHeaderText"; + protected ShellFolder parent; /** @@ -268,8 +273,45 @@ public abstract class ShellFolder extends File { // Override File methods - public static void sortFiles(List files) { - shellFolderManager.sortFiles(files); + public static void sort(List files) { + if (files == null || files.size() <= 1) { + return; + } + + // Check that we can use the ShellFolder.sortChildren() method: + // 1. All files have the same non-null parent + // 2. All files is ShellFolders + File commonParent = null; + + for (File file : files) { + File parent = file.getParentFile(); + + if (parent == null || !(file instanceof ShellFolder)) { + commonParent = null; + + break; + } + + if (commonParent == null) { + commonParent = parent; + } else { + if (commonParent != parent && !commonParent.equals(parent)) { + commonParent = null; + + break; + } + } + } + + if (commonParent instanceof ShellFolder) { + ((ShellFolder) commonParent).sortChildren(files); + } else { + Collections.sort(files, FILE_COMPARATOR); + } + } + + public void sortChildren(List files) { + Collections.sort(files, FILE_COMPARATOR); } public boolean isAbsolute() { @@ -356,18 +398,131 @@ public abstract class ShellFolder extends File { } public static ShellFolderColumnInfo[] getFolderColumns(File dir) { - return shellFolderManager.getFolderColumns(dir); - } + ShellFolderColumnInfo[] columns = null; - public static Object getFolderColumnValue(File file, int column) { - return shellFolderManager.getFolderColumnValue(file, column); + if (dir instanceof ShellFolder) { + columns = ((ShellFolder) dir).getFolderColumns(); + } + + if (columns == null) { + columns = new ShellFolderColumnInfo[]{ + new ShellFolderColumnInfo(COLUMN_NAME, 150, + SwingConstants.LEADING, true, null, + FILE_COMPARATOR), + new ShellFolderColumnInfo(COLUMN_SIZE, 75, + SwingConstants.RIGHT, true, null, + DEFAULT_COMPARATOR, true), + new ShellFolderColumnInfo(COLUMN_DATE, 130, + SwingConstants.LEADING, true, null, + DEFAULT_COMPARATOR, true) + }; + } + + return columns; } public ShellFolderColumnInfo[] getFolderColumns() { return null; } + public static Object getFolderColumnValue(File file, int column) { + if (file instanceof ShellFolder) { + Object value = ((ShellFolder)file).getFolderColumnValue(column); + if (value != null) { + return value; + } + } + + if (file == null || !file.exists()) { + return null; + } + + switch (column) { + case 0: + // By default, file name will be rendered using getSystemDisplayName() + return file; + + case 1: // size + return file.isDirectory() ? null : Long.valueOf(file.length()); + + case 2: // date + if (isFileSystemRoot(file)) { + return null; + } + long time = file.lastModified(); + return (time == 0L) ? null : new Date(time); + + default: + return null; + } + } + public Object getFolderColumnValue(int column) { return null; } + + /** + * Provides a default comparator for the default column set + */ + private static final Comparator DEFAULT_COMPARATOR = new Comparator() { + public int compare(Object o1, Object o2) { + int gt; + + if (o1 == null && o2 == null) { + gt = 0; + } else if (o1 != null && o2 == null) { + gt = 1; + } else if (o1 == null && o2 != null) { + gt = -1; + } else if (o1 instanceof Comparable) { + gt = ((Comparable) o1).compareTo(o2); + } else { + gt = 0; + } + + return gt; + } + }; + + private static final Comparator FILE_COMPARATOR = new Comparator() { + public int compare(File f1, File f2) { + ShellFolder sf1 = null; + ShellFolder sf2 = null; + + if (f1 instanceof ShellFolder) { + sf1 = (ShellFolder) f1; + if (sf1.isFileSystem()) { + sf1 = null; + } + } + if (f2 instanceof ShellFolder) { + sf2 = (ShellFolder) f2; + if (sf2.isFileSystem()) { + sf2 = null; + } + } + + if (sf1 != null && sf2 != null) { + return sf1.compareTo(sf2); + } else if (sf1 != null) { + // Non-file shellfolders sort before files + return -1; + } else if (sf2 != null) { + return 1; + } else { + String name1 = f1.getName(); + String name2 = f2.getName(); + + // First ignore case when comparing + int diff = name1.compareToIgnoreCase(name2); + if (diff != 0) { + return diff; + } else { + // May differ in case (e.g. "mail" vs. "Mail") + // We need this test for consistent sorting + return name1.compareTo(name2); + } + } + } + }; } diff --git a/jdk/src/share/classes/sun/awt/shell/ShellFolderManager.java b/jdk/src/share/classes/sun/awt/shell/ShellFolderManager.java index 592fa1b580f..aea1bae2273 100644 --- a/jdk/src/share/classes/sun/awt/shell/ShellFolderManager.java +++ b/jdk/src/share/classes/sun/awt/shell/ShellFolderManager.java @@ -27,8 +27,6 @@ package sun.awt.shell; import java.io.File; import java.io.FileNotFoundException; -import java.util.*; -import javax.swing.SwingConstants; /** * @author Michael Martak @@ -36,10 +34,6 @@ import javax.swing.SwingConstants; */ class ShellFolderManager { - private static final String COLUMN_NAME = "FileChooser.fileNameHeaderText"; - private static final String COLUMN_SIZE = "FileChooser.fileSizeHeaderText"; - private static final String COLUMN_DATE = "FileChooser.fileDateHeaderText"; - /** * Create a shell folder from a file. * Override to return machine-dependent behavior. @@ -107,142 +101,4 @@ class ShellFolderManager { } return (dir.getParentFile() == null); } - - public void sortFiles(List files) { - Collections.sort(files, fileComparator); - } - - private Comparator fileComparator = new Comparator() { - public int compare(Object a, Object b) { - return compare((File)a, (File)b); - } - - public int compare(File f1, File f2) { - ShellFolder sf1 = null; - ShellFolder sf2 = null; - - if (f1 instanceof ShellFolder) { - sf1 = (ShellFolder)f1; - if (sf1.isFileSystem()) { - sf1 = null; - } - } - if (f2 instanceof ShellFolder) { - sf2 = (ShellFolder)f2; - if (sf2.isFileSystem()) { - sf2 = null; - } - } - - if (sf1 != null && sf2 != null) { - return sf1.compareTo(sf2); - } else if (sf1 != null) { - return -1; // Non-file shellfolders sort before files - } else if (sf2 != null) { - return 1; - } else { - String name1 = f1.getName(); - String name2 = f2.getName(); - - // First ignore case when comparing - int diff = name1.toLowerCase().compareTo(name2.toLowerCase()); - if (diff != 0) { - return diff; - } else { - // May differ in case (e.g. "mail" vs. "Mail") - // We need this test for consistent sorting - return name1.compareTo(name2); - } - } - } - }; - - public ShellFolderColumnInfo[] getFolderColumns(File dir) { - ShellFolderColumnInfo[] columns = null; - - if (dir instanceof ShellFolder) { - columns = ((ShellFolder)dir).getFolderColumns(); - } - - if (columns == null) { - columns = new ShellFolderColumnInfo[]{ - new ShellFolderColumnInfo(COLUMN_NAME, 150, - SwingConstants.LEADING, true, null, - fileComparator), - new ShellFolderColumnInfo(COLUMN_SIZE, 75, - SwingConstants.RIGHT, true, null, - ComparableComparator.getInstance(), true), - new ShellFolderColumnInfo(COLUMN_DATE, 130, - SwingConstants.LEADING, true, null, - ComparableComparator.getInstance(), true) - }; - } - - return columns; - } - - public Object getFolderColumnValue(File file, int column) { - if (file instanceof ShellFolder) { - Object value = ((ShellFolder)file).getFolderColumnValue(column); - if (value != null) { - return value; - } - } - - if (file == null || !file.exists()) { - return null; - } - - switch (column) { - case 0: - // By default, file name will be rendered using getSystemDisplayName() - return file; - - case 1: // size - return file.isDirectory() ? null : new Long(file.length()); - - case 2: // date - if (isFileSystemRoot(file)) { - return null; - } - long time = file.lastModified(); - return (time == 0L) ? null : new Date(time); - - default: - return null; - } - } - - /** - * This class provides a default comparator for the default column set - */ - private static class ComparableComparator implements Comparator { - private static Comparator instance; - - public static Comparator getInstance() { - if (instance == null) { - instance = new ComparableComparator(); - } - return instance; - } - - public int compare(Object o1, Object o2) { - int gt; - - if (o1 == null && o2 == null) { - gt = 0; - } else if (o1 != null && o2 == null) { - gt = 1; - } else if (o1 == null && o2 != null) { - gt = -1; - } else if (o1 instanceof Comparable) { - gt = ((Comparable) o1).compareTo(o2); - } else { - gt = 0; - } - - return gt; - } - } - } diff --git a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java index 74aecd4437f..0ae33818b79 100644 --- a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java +++ b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java @@ -306,7 +306,7 @@ final class Win32ShellFolder2 extends ShellFolder { * java.io.File instead. If not, then the object depends * on native PIDL state and should not be serialized. * - * @returns a java.io.File replacement object. If the folder + * @return a java.io.File replacement object. If the folder * is a not a normal directory, then returns the first non-removable * drive (normally "C:\"). */ @@ -605,10 +605,10 @@ final class Win32ShellFolder2 extends ShellFolder { // parent so we have an IShellFolder to query. long pIShellFolder = getIShellFolder(); // Now we can enumerate the objects in this folder. - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList(); long pEnumObjects = getEnumObjects(pIShellFolder, includeHiddenFiles); if (pEnumObjects != 0) { - long childPIDL = 0; + long childPIDL; int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR; do { if (Thread.currentThread().isInterrupted()) { @@ -635,7 +635,7 @@ final class Win32ShellFolder2 extends ShellFolder { } while (childPIDL != 0); releaseEnumObjects(pEnumObjects); } - return (ShellFolder[])list.toArray(new ShellFolder[list.size()]); + return list.toArray(new ShellFolder[list.size()]); } @@ -648,7 +648,7 @@ final class Win32ShellFolder2 extends ShellFolder { long pIShellFolder = getIShellFolder(); long pEnumObjects = getEnumObjects(pIShellFolder, true); Win32ShellFolder2 child = null; - long childPIDL = 0; + long childPIDL; while ((childPIDL = getNextChild(pEnumObjects)) != 0) { if (getAttributes0(pIShellFolder, childPIDL, ATTRIB_FILESYSTEM) != 0) { @@ -983,7 +983,7 @@ final class Win32ShellFolder2 extends ShellFolder { ? SwingConstants.CENTER : SwingConstants.LEADING); - column.setComparator(new ColumnComparator(i)); + column.setComparator(new ColumnComparator(getIShellFolder(), i)); notNullColumns.add(column); } @@ -1002,22 +1002,29 @@ final class Win32ShellFolder2 extends ShellFolder { private native Object doGetColumnValue(long parentIShellFolder2, long childPIDL, int columnIdx); - private native int compareIDsByColumn(long pParentIShellFolder, long pidl1, long pidl2, int columnIdx); + private static native int compareIDsByColumn(long pParentIShellFolder, long pidl1, long pidl2, int columnIdx); - private class ColumnComparator implements Comparator { + public void sortChildren(List files) { + Collections.sort(files, new ColumnComparator(getIShellFolder(), 0)); + } + + private static class ColumnComparator implements Comparator { + private final long parentIShellFolder; + private final int columnIdx; - public ColumnComparator(int columnIdx) { + public ColumnComparator(long parentIShellFolder, int columnIdx) { + this.parentIShellFolder = parentIShellFolder; this.columnIdx = columnIdx; } // compares 2 objects within this folder by the specified column - public int compare(Object o, Object o1) { + public int compare(File o, File o1) { if (o instanceof Win32ShellFolder2 && o1 instanceof Win32ShellFolder2) { // delegates comparison to native method - return compareIDsByColumn(getIShellFolder(), + return compareIDsByColumn(parentIShellFolder, ((Win32ShellFolder2) o).getRelativePIDL(), ((Win32ShellFolder2) o1).getRelativePIDL(), columnIdx); diff --git a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java index ef3dfa6a46d..0c7acf32ffd 100644 --- a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java +++ b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java @@ -234,11 +234,11 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { // Add third level for "My Computer" if (folder.equals(drives)) { File[] thirdLevelFolders = folder.listFiles(); - if (thirdLevelFolders != null) { - Arrays.sort(thirdLevelFolders, driveComparator); - for (File thirdLevelFolder : thirdLevelFolders) { - folders.add(thirdLevelFolder); - } + if (thirdLevelFolders != null && thirdLevelFolders.length > 0) { + List thirdLevelFoldersList = Arrays.asList(thirdLevelFolders); + + folder.sortChildren(thirdLevelFoldersList); + folders.addAll(thirdLevelFoldersList); } } } @@ -362,27 +362,6 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { return false; } - private Comparator driveComparator = new Comparator() { - public int compare(Object o1, Object o2) { - Win32ShellFolder2 shellFolder1 = (Win32ShellFolder2) o1; - Win32ShellFolder2 shellFolder2 = (Win32ShellFolder2) o2; - - // Put drives at first - boolean isDrive1 = shellFolder1.getPath().endsWith(":\\"); - - if (isDrive1 ^ shellFolder2.getPath().endsWith(":\\")) { - return isDrive1 ? -1 : 1; - } else { - return shellFolder1.getPath().compareTo(shellFolder2.getPath()); - } - } - }; - - - public void sortFiles(List files) { - Collections.sort(files, fileComparator); - } - private static List topFolderList = null; static int compareShellFolders(Win32ShellFolder2 sf1, Win32ShellFolder2 sf2) { boolean special1 = sf1.isSpecial(); @@ -418,19 +397,9 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { return compareNames(sf1.getAbsolutePath(), sf2.getAbsolutePath()); } - static int compareFiles(File f1, File f2) { - if (f1 instanceof Win32ShellFolder2) { - return f1.compareTo(f2); - } - if (f2 instanceof Win32ShellFolder2) { - return -1 * f2.compareTo(f1); - } - return compareNames(f1.getName(), f2.getName()); - } - static int compareNames(String name1, String name2) { // First ignore case when comparing - int diff = name1.toLowerCase().compareTo(name2.toLowerCase()); + int diff = name1.compareToIgnoreCase(name2); if (diff != 0) { return diff; } else { @@ -439,14 +408,4 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { return name1.compareTo(name2); } } - - private Comparator fileComparator = new Comparator() { - public int compare(Object a, Object b) { - return compare((File)a, (File)b); - } - - public int compare(File f1, File f2) { - return compareFiles(f1, f2); - } - }; } From 9a2ae13639adf0dbc3b98c8bd011fd2d48a6d63d Mon Sep 17 00:00:00 2001 From: Pavel Porvatov Date: Thu, 5 Jun 2008 13:30:41 +0400 Subject: [PATCH 7/9] 6688110: JSlider has incorrect javadoc for the setValueIsAdjusting method The sentence about ChangeEvents generation was removed Reviewed-by: peterz --- jdk/src/share/classes/javax/swing/JSlider.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/JSlider.java b/jdk/src/share/classes/javax/swing/JSlider.java index d436f32f1a6..6432b9f59d6 100644 --- a/jdk/src/share/classes/javax/swing/JSlider.java +++ b/jdk/src/share/classes/javax/swing/JSlider.java @@ -638,9 +638,7 @@ public class JSlider extends JComponent implements SwingConstants, Accessible { /** * Sets the model's {@code valueIsAdjusting} property. Slider look and * feel implementations should set this property to {@code true} when - * a knob drag begins, and to {@code false} when the drag ends. The - * slider model will not generate {@code ChangeEvent}s while - * {@code valueIsAdjusting} is {@code true}. + * a knob drag begins, and to {@code false} when the drag ends. * * @param b the new value for the {@code valueIsAdjusting} property * @see #getValueIsAdjusting From 8f7aabf9558f176f9ebf765aabb3dfe22d7822e4 Mon Sep 17 00:00:00 2001 From: Pavel Porvatov Date: Fri, 6 Jun 2008 13:30:20 +0400 Subject: [PATCH 8/9] 5035693: "Open" button should be a default one in JFileChooser under Windows XP LAF The "Open" button was made default button of FileChooser dialog windows Reviewed-by: loneid, peterz --- .../sun/java/swing/plaf/motif/MotifLookAndFeel.java | 4 +--- .../java/swing/plaf/windows/WindowsLookAndFeel.java | 4 +--- jdk/src/share/classes/javax/swing/JFileChooser.java | 4 +++- .../classes/javax/swing/plaf/FileChooserUI.java | 13 ++++++++++++- .../javax/swing/plaf/basic/BasicFileChooserUI.java | 4 ++++ .../javax/swing/plaf/metal/MetalLookAndFeel.java | 4 +--- 6 files changed, 22 insertions(+), 11 deletions(-) diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifLookAndFeel.java b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifLookAndFeel.java index e91dbb9e718..b758d50dcde 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifLookAndFeel.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifLookAndFeel.java @@ -1222,9 +1222,7 @@ public class MotifLookAndFeel extends BasicLookAndFeel "FileChooser.enterFileNameLabelMnemonic", new Integer (KeyEvent.VK_N), // 'n' "FileChooser.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] { - "ESCAPE", "cancelSelection", - "ENTER", "approveSelection", - "ctrl ENTER", "approveSelection" + "ESCAPE", "cancelSelection" }), diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java index 9af41fc39c8..69ccdf720a6 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java @@ -825,9 +825,7 @@ public class WindowsLookAndFeel extends BasicLookAndFeel "ESCAPE", "cancelSelection", "F2", "editFileName", "F5", "refresh", - "BACK_SPACE", "Go Up", - "ENTER", "approveSelection", - "ctrl ENTER", "approveSelection" + "BACK_SPACE", "Go Up" }), "FileView.directoryIcon", SwingUtilities2.makeIcon(getClass(), diff --git a/jdk/src/share/classes/javax/swing/JFileChooser.java b/jdk/src/share/classes/javax/swing/JFileChooser.java index 8a2b2d5393f..344565a1f3f 100644 --- a/jdk/src/share/classes/javax/swing/JFileChooser.java +++ b/jdk/src/share/classes/javax/swing/JFileChooser.java @@ -770,7 +770,8 @@ public class JFileChooser extends JComponent implements Accessible { * @since 1.4 */ protected JDialog createDialog(Component parent) throws HeadlessException { - String title = getUI().getDialogTitle(this); + FileChooserUI ui = getUI(); + String title = ui.getDialogTitle(this); putClientProperty(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY, title); @@ -794,6 +795,7 @@ public class JFileChooser extends JComponent implements Accessible { dialog.getRootPane().setWindowDecorationStyle(JRootPane.FILE_CHOOSER_DIALOG); } } + dialog.getRootPane().setDefaultButton(ui.getDefaultButton(this)); dialog.pack(); dialog.setLocationRelativeTo(parent); diff --git a/jdk/src/share/classes/javax/swing/plaf/FileChooserUI.java b/jdk/src/share/classes/javax/swing/plaf/FileChooserUI.java index 78064e08efc..aaab089cc81 100644 --- a/jdk/src/share/classes/javax/swing/plaf/FileChooserUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/FileChooserUI.java @@ -25,7 +25,7 @@ package javax.swing.plaf; -import javax.swing.JFileChooser; +import javax.swing.*; import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileView; import java.io.File; @@ -46,4 +46,15 @@ public abstract class FileChooserUI extends ComponentUI public abstract void rescanCurrentDirectory(JFileChooser fc); public abstract void ensureFileIsVisible(JFileChooser fc, File f); + + /** + * Returns default button for current LookAndFeel. + * JFileChooser will use this button as default button + * for dialog windows. + * + * @since 1.7 + */ + public JButton getDefaultButton(JFileChooser fc) { + return null; + } } diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java index 5a9daae328d..e8728d807a4 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java @@ -384,6 +384,10 @@ public class BasicFileChooserUI extends FileChooserUI { return null; } + public JButton getDefaultButton(JFileChooser fc) { + return getApproveButton(fc); + } + public String getApproveButtonToolTipText(JFileChooser fc) { String tooltipText = fc.getApproveButtonToolTipText(); if(tooltipText != null) { diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java index d1f7c05935d..27279940966 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java @@ -853,9 +853,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel "ESCAPE", "cancelSelection", "F2", "editFileName", "F5", "refresh", - "BACK_SPACE", "Go Up", - "ENTER", "approveSelection", - "ctrl ENTER", "approveSelection" + "BACK_SPACE", "Go Up" }), From 3bdf3063261947928db4880fdef2f64c9041d4f2 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Wed, 18 Jun 2008 19:15:23 +0400 Subject: [PATCH 9/9] 6708550: LTP: XMLEncoder does not encode instances of the File class Reviewed-by: peterz, loneid --- jdk/src/share/classes/java/io/File.java | 2 + .../java/beans/XMLEncoder/java_io_File.java | 47 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 jdk/test/java/beans/XMLEncoder/java_io_File.java diff --git a/jdk/src/share/classes/java/io/File.java b/jdk/src/share/classes/java/io/File.java index e36ee120b62..7c58136a44d 100644 --- a/jdk/src/share/classes/java/io/File.java +++ b/jdk/src/share/classes/java/io/File.java @@ -25,6 +25,7 @@ package java.io; +import java.beans.ConstructorProperties; import java.net.URI; import java.net.URL; import java.net.MalformedURLException; @@ -234,6 +235,7 @@ public class File * @throws NullPointerException * If the pathname argument is null */ + @ConstructorProperties("path") public File(String pathname) { if (pathname == null) { throw new NullPointerException(); diff --git a/jdk/test/java/beans/XMLEncoder/java_io_File.java b/jdk/test/java/beans/XMLEncoder/java_io_File.java new file mode 100644 index 00000000000..282949b0151 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/java_io_File.java @@ -0,0 +1,47 @@ +/* + * Copyright 2008 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 6708550 + * @summary Tests File encoding + * @author Sergey Malenkov + */ + +import java.io.File; + +public final class java_io_File extends AbstractTest { + public static void main(String[] args) { + new java_io_File().test(true); + } + + @Override + protected File getObject() { + return new File("test.txt"); // NON-NLS: local file + } + + @Override + protected File getAnotherObject() { + return new File("/pub/demo/"); // NON-NLS: path + } +}