From 23347b645b56beb4baff53ccfa3d270483a39792 Mon Sep 17 00:00:00 2001 From: serb Date: Wed, 21 Jan 2015 17:54:35 +0300 Subject: [PATCH] 6459798: JDesktopPane,JFileChooser violate encapsulation by returning internal Dimensions Reviewed-by: azvegint, alexsch --- .../com/apple/laf/AquaFileChooserUI.java | 34 ++- .../java/swing/plaf/gtk/GTKFileChooserUI.java | 10 +- .../swing/plaf/motif/MotifFileChooserUI.java | 13 +- .../plaf/windows/WindowsFileChooserUI.java | 6 +- .../swing/plaf/basic/BasicDesktopPaneUI.java | 24 +- .../swing/plaf/metal/MetalFileChooserUI.java | 12 +- .../DimensionEncapsulation.java | 215 ++++++++++++++++++ 7 files changed, 277 insertions(+), 37 deletions(-) create mode 100644 test/java/awt/Component/DimensionEncapsulation/DimensionEncapsulation.java diff --git a/src/macosx/classes/com/apple/laf/AquaFileChooserUI.java b/src/macosx/classes/com/apple/laf/AquaFileChooserUI.java index d847bd7ca..6c4ee805e 100644 --- a/src/macosx/classes/com/apple/laf/AquaFileChooserUI.java +++ b/src/macosx/classes/com/apple/laf/AquaFileChooserUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2015, Oracle and/or its affiliates. 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 @@ -1089,8 +1089,15 @@ public class AquaFileChooserUI extends FileChooserUI { super(f); } - public Component getTableCellRendererComponent(final JTable list, final Object value, final boolean isSelected, final boolean cellHasFocus, final int index, final int col) { - super.getTableCellRendererComponent(list, value, isSelected, false, index, col); // No focus border, thanks + public Component getTableCellRendererComponent(final JTable list, + final Object value, + final boolean isSelected, + final boolean cellHasFocus, + final int index, + final int col) { + super.getTableCellRendererComponent(list, value, isSelected, false, + index, + col); // No focus border, thanks final File file = (File)value; final JFileChooser fc = getFileChooser(); setText(fc.getName(file)); @@ -1105,8 +1112,14 @@ public class AquaFileChooserUI extends FileChooserUI { super(f); } - public Component getTableCellRendererComponent(final JTable list, final Object value, final boolean isSelected, final boolean cellHasFocus, final int index, final int col) { - super.getTableCellRendererComponent(list, value, isSelected, false, index, col); + public Component getTableCellRendererComponent(final JTable list, + final Object value, + final boolean isSelected, + final boolean cellHasFocus, + final int index, + final int col) { + super.getTableCellRendererComponent(list, value, isSelected, false, + index, col); final File file = (File)fFileList.getValueAt(index, 0); setEnabled(isSelectableInList(file)); final DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT); @@ -1122,14 +1135,17 @@ public class AquaFileChooserUI extends FileChooserUI { } } + @Override public Dimension getPreferredSize(final JComponent c) { - return PREF_SIZE; + return new Dimension(PREF_WIDTH, PREF_HEIGHT); } + @Override public Dimension getMinimumSize(final JComponent c) { - return MIN_SIZE; + return new Dimension(MIN_WIDTH, MIN_HEIGHT); } + @Override public Dimension getMaximumSize(final JComponent c) { return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } @@ -1793,12 +1809,8 @@ public class AquaFileChooserUI extends FileChooserUI { private static final int PREF_WIDTH = 550; private static final int PREF_HEIGHT = 400; - private static final Dimension PREF_SIZE = new Dimension(PREF_WIDTH, PREF_HEIGHT); - private static final int MIN_WIDTH = 400; private static final int MIN_HEIGHT = 250; - private static final Dimension MIN_SIZE = new Dimension(MIN_WIDTH, MIN_HEIGHT); - private static final int LIST_MIN_WIDTH = 400; private static final int LIST_MIN_HEIGHT = 100; private static final Dimension LIST_MIN_SIZE = new Dimension(LIST_MIN_WIDTH, LIST_MIN_HEIGHT); diff --git a/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java b/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java index 530cecea2..258e3e3c7 100644 --- a/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java +++ b/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java @@ -100,7 +100,8 @@ class GTKFileChooserUI extends SynthFileChooserUI { private static Dimension prefListSize = new Dimension(75, 150); private static Dimension PREF_SIZE = new Dimension(435, 360); - private static Dimension MIN_SIZE = new Dimension(200, 300); + private static final int MIN_WIDTH = 200; + private static final int MIN_HEIGHT = 300; private static Dimension ZERO_ACC_SIZE = new Dimension(1, 1); @@ -1038,6 +1039,7 @@ class GTKFileChooserUI extends SynthFileChooserUI { } } + @Override public Dimension getPreferredSize(JComponent c) { Dimension prefSize = new Dimension(PREF_SIZE); JComponent accessory = getFileChooser().getAccessory(); @@ -1053,10 +1055,12 @@ class GTKFileChooserUI extends SynthFileChooserUI { } } - public Dimension getMinimumSize(JComponent x) { - return new Dimension(MIN_SIZE); + @Override + public Dimension getMinimumSize(JComponent x) { + return new Dimension(MIN_WIDTH, MIN_HEIGHT); } + @Override public Dimension getMaximumSize(JComponent x) { return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } diff --git a/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java b/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java index ae7baa53b..e6b33bc3f 100644 --- a/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java +++ b/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. 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 @@ -65,8 +65,8 @@ public class MotifFileChooserUI extends BasicFileChooserUI { private static Dimension WITH_ACCELERATOR_PREF_SIZE = new Dimension(650, 450); private static Dimension PREF_SIZE = new Dimension(350, 450); - private static Dimension MIN_SIZE = new Dimension(200, 300); - + private static final int MIN_WIDTH = 200; + private static final int MIN_HEIGHT = 300; private static Dimension PREF_ACC_SIZE = new Dimension(10, 10); private static Dimension ZERO_ACC_SIZE = new Dimension(1, 1); @@ -615,6 +615,7 @@ public class MotifFileChooserUI extends BasicFileChooserUI { return scrollpane; } + @Override public Dimension getPreferredSize(JComponent c) { Dimension prefSize = (getFileChooser().getAccessory() != null) ? WITH_ACCELERATOR_PREF_SIZE : PREF_SIZE; @@ -627,10 +628,12 @@ public class MotifFileChooserUI extends BasicFileChooserUI { } } - public Dimension getMinimumSize(JComponent x) { - return MIN_SIZE; + @Override + public Dimension getMinimumSize(JComponent x) { + return new Dimension(MIN_WIDTH, MIN_HEIGHT); } + @Override public Dimension getMaximumSize(JComponent x) { return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } diff --git a/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java b/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java index b22ebf958..b9b9b91e0 100644 --- a/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java +++ b/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java @@ -93,7 +93,6 @@ public class WindowsFileChooserUI extends BasicFileChooserUI { private static int MIN_WIDTH = 425; private static int MIN_HEIGHT = 245; - private static Dimension MIN_SIZE = new Dimension(MIN_WIDTH, MIN_HEIGHT); private static int LIST_PREF_WIDTH = 444; private static int LIST_PREF_HEIGHT = 138; @@ -631,6 +630,7 @@ public class WindowsFileChooserUI extends BasicFileChooserUI { * @return a Dimension specifying the preferred * width and height of the file chooser */ + @Override public Dimension getPreferredSize(JComponent c) { int prefWidth = PREF_SIZE.width; Dimension d = c.getLayout().preferredLayoutSize(c); @@ -649,8 +649,9 @@ public class WindowsFileChooserUI extends BasicFileChooserUI { * @return a Dimension specifying the minimum * width and height of the file chooser */ + @Override public Dimension getMinimumSize(JComponent c) { - return MIN_SIZE; + return new Dimension(MIN_WIDTH, MIN_HEIGHT); } /** @@ -660,6 +661,7 @@ public class WindowsFileChooserUI extends BasicFileChooserUI { * @return a Dimension specifying the maximum * width and height of the file chooser */ + @Override public Dimension getMaximumSize(JComponent c) { return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } diff --git a/src/share/classes/javax/swing/plaf/basic/BasicDesktopPaneUI.java b/src/share/classes/javax/swing/plaf/basic/BasicDesktopPaneUI.java index 2d0067789..64dace356 100644 --- a/src/share/classes/javax/swing/plaf/basic/BasicDesktopPaneUI.java +++ b/src/share/classes/javax/swing/plaf/basic/BasicDesktopPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. 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 @@ -36,10 +36,9 @@ import java.awt.Insets; import java.awt.Graphics; import java.awt.KeyboardFocusManager; import java.awt.*; -import java.util.Vector; + import sun.swing.DefaultLookup; import sun.swing.UIAction; -import sun.awt.AppContext; /** * Basic L&F for a desktop. @@ -49,9 +48,6 @@ import sun.awt.AppContext; public class BasicDesktopPaneUI extends DesktopPaneUI { // Old actions forward to an instance of this. private static final Actions SHARED_ACTION = new Actions(); - private static Dimension minSize = new Dimension(0,0); - private static Dimension maxSize = new Dimension(Integer.MAX_VALUE, - Integer.MAX_VALUE); private Handler handler; private PropertyChangeListener pcl; @@ -264,13 +260,19 @@ public class BasicDesktopPaneUI extends DesktopPaneUI { public void paint(Graphics g, JComponent c) {} - public Dimension getPreferredSize(JComponent c) {return null;} + @Override + public Dimension getPreferredSize(JComponent c) { + return null; + } + @Override public Dimension getMinimumSize(JComponent c) { - return minSize; - } - public Dimension getMaximumSize(JComponent c){ - return maxSize; + return new Dimension(0, 0); + } + + @Override + public Dimension getMaximumSize(JComponent c) { + return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } /** diff --git a/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java b/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java index ddc70c91c..a7b0f52c4 100644 --- a/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java +++ b/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. 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 @@ -92,8 +92,6 @@ public class MetalFileChooserUI extends BasicFileChooserUI { private static int MIN_WIDTH = 500; private static int MIN_HEIGHT = 326; - private static Dimension MIN_SIZE = new Dimension(MIN_WIDTH, MIN_HEIGHT); - private static int LIST_PREF_WIDTH = 405; private static int LIST_PREF_HEIGHT = 135; private static Dimension LIST_PREF_SIZE = new Dimension(LIST_PREF_WIDTH, LIST_PREF_HEIGHT); @@ -565,6 +563,7 @@ public class MetalFileChooserUI extends BasicFileChooserUI { * @return a Dimension specifying the preferred * width and height of the file chooser */ + @Override public Dimension getPreferredSize(JComponent c) { int prefWidth = PREF_SIZE.width; Dimension d = c.getLayout().preferredLayoutSize(c); @@ -583,8 +582,9 @@ public class MetalFileChooserUI extends BasicFileChooserUI { * @return a Dimension specifying the minimum * width and height of the file chooser */ + @Override public Dimension getMinimumSize(JComponent c) { - return MIN_SIZE; + return new Dimension(MIN_WIDTH, MIN_HEIGHT); } /** @@ -594,6 +594,7 @@ public class MetalFileChooserUI extends BasicFileChooserUI { * @return a Dimension specifying the maximum * width and height of the file chooser */ + @Override public Dimension getMaximumSize(JComponent c) { return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } @@ -604,7 +605,8 @@ public class MetalFileChooserUI extends BasicFileChooserUI { } else { JFileChooser fc = getFileChooser(); if ((fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) || - (fc.isDirectorySelectionEnabled() && fc.isFileSelectionEnabled() && fc.getFileSystemView().isFileSystemRoot(file))) { + (fc.isDirectorySelectionEnabled() && fc.isFileSelectionEnabled() + && fc.getFileSystemView().isFileSystemRoot(file))) { return file.getPath(); } else { return file.getName(); diff --git a/test/java/awt/Component/DimensionEncapsulation/DimensionEncapsulation.java b/test/java/awt/Component/DimensionEncapsulation/DimensionEncapsulation.java new file mode 100644 index 000000000..3955453ba --- /dev/null +++ b/test/java/awt/Component/DimensionEncapsulation/DimensionEncapsulation.java @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Canvas; +import java.awt.Checkbox; +import java.awt.Choice; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.FileDialog; +import java.awt.Frame; +import java.awt.Label; +import java.awt.List; +import java.awt.Panel; +import java.awt.ScrollPane; +import java.awt.Scrollbar; +import java.awt.TextArea; +import java.awt.TextField; +import java.awt.Window; +import java.util.ArrayList; +import java.util.Objects; + +import javax.swing.Box; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JColorChooser; +import javax.swing.JDesktopPane; +import javax.swing.JDialog; +import javax.swing.JEditorPane; +import javax.swing.JFileChooser; +import javax.swing.JFormattedTextField; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.JLabel; +import javax.swing.JLayeredPane; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPasswordField; +import javax.swing.JPopupMenu; +import javax.swing.JProgressBar; +import javax.swing.JRadioButton; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.JRootPane; +import javax.swing.JScrollPane; +import javax.swing.JSeparator; +import javax.swing.JSlider; +import javax.swing.JSpinner; +import javax.swing.JSplitPane; +import javax.swing.JTabbedPane; +import javax.swing.JTable; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.JTextPane; +import javax.swing.JToggleButton; +import javax.swing.JToolBar; +import javax.swing.JTree; +import javax.swing.JViewport; +import javax.swing.JWindow; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UIManager.LookAndFeelInfo; +import javax.swing.UnsupportedLookAndFeelException; +import javax.swing.table.JTableHeader; + +import static javax.swing.UIManager.getInstalledLookAndFeels; + +/** + * @test + * @bug 6459798 + * @author Sergey Bylokhov + */ +public final class DimensionEncapsulation implements Runnable { + + java.util.List failures = new ArrayList<>(); + + public static void main(final String[] args) throws Exception { + for (final LookAndFeelInfo laf : getInstalledLookAndFeels()) { + SwingUtilities.invokeAndWait(() -> setLookAndFeel(laf)); + SwingUtilities.invokeAndWait(new DimensionEncapsulation()); + } + } + + @Override + public void run() { + runTest(new Panel()); + runTest(new Button()); + runTest(new Checkbox()); + runTest(new Canvas()); + runTest(new Choice()); + runTest(new Label()); + runTest(new Scrollbar()); + runTest(new TextArea()); + runTest(new TextField()); + runTest(new Dialog(new JFrame())); + runTest(new Frame()); + runTest(new Window(new JFrame())); + runTest(new FileDialog(new JFrame())); + runTest(new List()); + runTest(new ScrollPane()); + runTest(new JFrame()); + runTest(new JDialog(new JFrame())); + runTest(new JWindow(new JFrame())); + runTest(new JLabel("hi")); + runTest(new JMenu()); + runTest(new JTree()); + runTest(new JTable()); + runTest(new JMenuItem()); + runTest(new JCheckBoxMenuItem()); + runTest(new JToggleButton()); + runTest(new JSpinner()); + runTest(new JSlider()); + runTest(Box.createVerticalBox()); + runTest(Box.createHorizontalBox()); + runTest(new JTextField()); + runTest(new JTextArea()); + runTest(new JTextPane()); + runTest(new JPasswordField()); + runTest(new JFormattedTextField()); + runTest(new JEditorPane()); + runTest(new JButton()); + runTest(new JColorChooser()); + runTest(new JFileChooser()); + runTest(new JCheckBox()); + runTest(new JInternalFrame()); + runTest(new JDesktopPane()); + runTest(new JTableHeader()); + runTest(new JLayeredPane()); + runTest(new JRootPane()); + runTest(new JMenuBar()); + runTest(new JOptionPane()); + runTest(new JRadioButton()); + runTest(new JRadioButtonMenuItem()); + runTest(new JPopupMenu()); + //runTest(new JScrollBar()); --> don't test defines max and min in + // terms of preferred + runTest(new JScrollPane()); + runTest(new JViewport()); + runTest(new JSplitPane()); + runTest(new JTabbedPane()); + runTest(new JToolBar()); + runTest(new JSeparator()); + runTest(new JProgressBar()); + if (!failures.isEmpty()) { + System.out.println("These classes failed"); + for (final Component failure : failures) { + System.out.println(failure.getClass()); + } + throw new RuntimeException("Test failed"); + } + } + + public void runTest(final Component c) { + try { + test(c); + c.setMinimumSize(new Dimension(100, 10)); + c.setMaximumSize(new Dimension(200, 20)); + c.setPreferredSize(new Dimension(300, 30)); + test(c); + } catch (final Throwable ignored) { + failures.add(c); + } + } + + public void test(final Component component) { + final Dimension psize = component.getPreferredSize(); + psize.width += 200; + if (Objects.equals(psize, component.getPreferredSize())) { + throw new RuntimeException("PreferredSize is wrong"); + } + final Dimension msize = component.getMaximumSize(); + msize.width += 200; + if (Objects.equals(msize, component.getMaximumSize())) { + throw new RuntimeException("MaximumSize is wrong"); + } + final Dimension misize = component.getMinimumSize(); + misize.width += 200; + if (Objects.equals(misize, component.getMinimumSize())) { + throw new RuntimeException("MinimumSize is wrong"); + } + } + + private static void setLookAndFeel(final LookAndFeelInfo laf) { + try { + UIManager.setLookAndFeel(laf.getClassName()); + System.out.println("LookAndFeel: " + laf.getClassName()); + } catch (ClassNotFoundException | InstantiationException | + UnsupportedLookAndFeelException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file -- GitLab