From b5fdcb0851610dfe130d774b76a250cf241c9ba6 Mon Sep 17 00:00:00 2001 From: Pankaj Bansal Date: Fri, 21 Feb 2020 16:31:45 +0530 Subject: [PATCH] 8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition Reviewed-by: serb, psadhukhan --- .../swing/plaf/basic/BasicMenuItemUI.java | 10 - .../swing/plaf/windows/WindowsMenuItemUI.java | 63 ++++++ .../SynthCheckBoxMenuItem/Check_Icon.png | Bin 0 -> 192 bytes .../MenuItem_Selected.png | Bin 0 -> 136 bytes .../TestJCheckBoxMenuItem.java | 208 ++++++++++++++++++ 5 files changed, 271 insertions(+), 10 deletions(-) create mode 100644 test/jdk/javax/swing/plaf/synth/SynthCheckBoxMenuItem/Check_Icon.png create mode 100644 test/jdk/javax/swing/plaf/synth/SynthCheckBoxMenuItem/MenuItem_Selected.png create mode 100644 test/jdk/javax/swing/plaf/synth/SynthCheckBoxMenuItem/TestJCheckBoxMenuItem.java diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java index fc3859f2c8c..4da1141d2aa 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java @@ -228,14 +228,6 @@ public class BasicMenuItemUI extends MenuItemUI arrowIcon instanceof UIResource) { arrowIcon = UIManager.getIcon(prefix + ".arrowIcon"); } - updateCheckIcon(); - } - - /** - * Updates check Icon based on column layout - */ - private void updateCheckIcon() { - String prefix = getPropertyPrefix(); if (checkIcon == null || checkIcon instanceof UIResource) { @@ -1155,8 +1147,6 @@ public class BasicMenuItemUI extends MenuItemUI BasicHTML.updateRenderer(lbl, text); } else if (name == "iconTextGap") { defaultTextIconGap = ((Number)e.getNewValue()).intValue(); - } else if (name == "horizontalTextPosition") { - updateCheckIcon(); } } } diff --git a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsMenuItemUI.java b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsMenuItemUI.java index 578615829ec..3b895ba4d4f 100644 --- a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsMenuItemUI.java +++ b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsMenuItemUI.java @@ -26,10 +26,14 @@ package com.sun.java.swing.plaf.windows; import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import javax.swing.*; import javax.swing.plaf.*; import javax.swing.plaf.basic.*; +import sun.swing.MenuItemCheckIconFactory; +import sun.swing.MenuItemLayoutHelper; import sun.swing.SwingUtilities2; import com.sun.java.swing.plaf.windows.TMSchema.*; @@ -49,6 +53,11 @@ import com.sun.java.swing.plaf.windows.XPStyle.*; */ public class WindowsMenuItemUI extends BasicMenuItemUI { + /** + * The instance of {@code PropertyChangeListener}. + */ + private PropertyChangeListener changeListener; + final WindowsMenuItemUIAccessor accessor = new WindowsMenuItemUIAccessor() { @@ -68,6 +77,60 @@ public class WindowsMenuItemUI extends BasicMenuItemUI { return new WindowsMenuItemUI(); } + private void updateCheckIcon() { + String prefix = getPropertyPrefix(); + + if (checkIcon == null || + checkIcon instanceof UIResource) { + checkIcon = UIManager.getIcon(prefix + ".checkIcon"); + //In case of column layout, .checkIconFactory is defined for this UI, + //the icon is compatible with it and useCheckAndArrow() is true, + //then the icon is handled by the checkIcon. + boolean isColumnLayout = MenuItemLayoutHelper.isColumnLayout( + menuItem.getComponentOrientation().isLeftToRight(), menuItem); + if (isColumnLayout) { + MenuItemCheckIconFactory iconFactory = + (MenuItemCheckIconFactory) UIManager.get(prefix + + ".checkIconFactory"); + if (iconFactory != null + && MenuItemLayoutHelper.useCheckAndArrow(menuItem) + && iconFactory.isCompatible(checkIcon, prefix)) { + checkIcon = iconFactory.getIcon(menuItem); + } + } + } + } + + /** + * {@inheritDoc} + */ + @Override + protected void installListeners() { + super.installListeners(); + changeListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent e) { + String name = e.getPropertyName(); + if (name == "horizontalTextPosition") { + updateCheckIcon(); + } + } + }; + menuItem.addPropertyChangeListener(changeListener); + } + + /** + * {@inheritDoc} + */ + @Override + protected void uninstallListeners() { + super.uninstallListeners(); + if (changeListener != null) { + menuItem.removePropertyChangeListener(changeListener); + } + changeListener = null; + } + /** * Method which renders the text of the current menu item. * diff --git a/test/jdk/javax/swing/plaf/synth/SynthCheckBoxMenuItem/Check_Icon.png b/test/jdk/javax/swing/plaf/synth/SynthCheckBoxMenuItem/Check_Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..84e3fd28dbe7a97eec005bd658930aef3596d17a GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EwA3&JVX^qJYpkR@w zi(`nz>7|!<^ExPUum&isFJL%cY;(Mr!8$IrN$^ASRJD29Dotm2CVuVpUH4aO<v`-M>nkGGIyA}7`_~xW**cwTOSfED^n`@=vtoV^ mF1s5sA4}N7BkXqkC;OTvU3tlm%UyxCGkCiCxvX!lvI6;>1s;*b3=BdgAk26#O}+vsDC_Cs7-Hd{Y~jNwan(l&jw@&J%d;``HBGX6 TvMa" + + "" + + "" + + "" + + "" + + ""; + public static void main(String[] args) throws Exception { + countDownLatch = new CountDownLatch(1); + + SwingUtilities.invokeAndWait(TestJCheckBoxMenuItem::createInstructionUI); + + SynthLookAndFeel lookAndFeel = new SynthLookAndFeel(); + lookAndFeel.load( + new ByteArrayInputStream(synthStyleXML.getBytes("UTF8")), + TestJCheckBoxMenuItem.class); + try { + UIManager.setLookAndFeel(lookAndFeel); + } catch (final UnsupportedLookAndFeelException ignored) { + System.out.println("Synth L&F could not be set, so this test can" + + "not be run in this scenario "); + return; + } + SwingUtilities.invokeAndWait(TestJCheckBoxMenuItem::createTestUI); + + countDownLatch.await(15, TimeUnit.MINUTES); + + disposeUI(); + if (!testResult) { + throw new RuntimeException("Test failed!"); + } + } + + private static void createInstructionUI() { + GridBagLayout layout = new GridBagLayout(); + JPanel mainControlPanel = new JPanel(layout); + JPanel resultButtonPanel = new JPanel(layout); + + GridBagConstraints gbc = new GridBagConstraints(); + + gbc.gridx = 0; + gbc.gridy = 0; + gbc.insets = new Insets(5, 15, 5, 15); + gbc.fill = GridBagConstraints.HORIZONTAL; + + JTextArea instructionTextArea = new JTextArea(); + instructionTextArea.setText(INSTRUCTIONS); + instructionTextArea.setEditable(false); + instructionTextArea.setBackground(Color.white); + mainControlPanel.add(instructionTextArea, gbc); + + JButton passButton = new JButton("Pass"); + passButton.setActionCommand("Pass"); + passButton.addActionListener((ActionEvent e) -> { + testResult = true; + countDownLatch.countDown(); + + }); + + JButton failButton = new JButton("Fail"); + failButton.setActionCommand("Fail"); + failButton.addActionListener(e -> { + countDownLatch.countDown(); + }); + + gbc.gridx = 0; + gbc.gridy = 0; + + resultButtonPanel.add(passButton, gbc); + + gbc.gridx = 1; + gbc.gridy = 0; + resultButtonPanel.add(failButton, gbc); + + gbc.gridx = 0; + gbc.gridy = 2; + mainControlPanel.add(resultButtonPanel, gbc); + + instructionFrame.pack(); + instructionFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + instructionFrame.add(mainControlPanel); + instructionFrame.pack(); + + instructionFrame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + disposeUI(); + countDownLatch.countDown(); + } + }); + instructionFrame.setVisible(true); + } + + private static void createTestUI() { + JMenuBar menuBar = new JMenuBar(); + JMenu menu = new JMenu("Menu"); + + JCheckBoxMenuItem checkBoxMenuItem = new JCheckBoxMenuItem(); + checkBoxMenuItem.setSelected(false); + checkBoxMenuItem.setMnemonic(KeyEvent.VK_K); + checkBoxMenuItem.setText("JCheckBoxMenuItem Sample Text"); + checkBoxMenuItem.setHorizontalTextPosition(JCheckBoxMenuItem.LEADING); + checkBoxMenuItem.setVerticalTextPosition(JCheckBoxMenuItem.CENTER); + + menu.add(checkBoxMenuItem); + menuBar.add(menu); + + testFrame.setJMenuBar(menuBar); + testFrame.setLocation( + instructionFrame.getX() + instructionFrame.getWidth(), + instructionFrame.getY()); + testFrame.setPreferredSize(new Dimension(instructionFrame.getWidth(), + instructionFrame.getHeight())); + testFrame.pack(); + testFrame.setTitle("Test"); + testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + testFrame.setVisible(true); + } + + private static void disposeUI() { + instructionFrame.dispose(); + testFrame.dispose(); + } +}