From 9c96a2b07a90c42d4bfcb0a6d70117b6d3e2a257 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Sun, 1 Sep 2019 09:54:58 +0200 Subject: [PATCH] PopupMenuSeparator implementation --- .../flatlaf/ui/FlatPopupMenuSeparatorUI.java | 42 ++++++++++ .../formdev/flatlaf/ui/FlatSeparatorUI.java | 50 +++++++++--- .../com/formdev/flatlaf/FlatLaf.properties | 15 ++++ .../com/formdev/flatlaf/FlatMenusTest.java | 79 ++++++++++++++++++- .../com/formdev/flatlaf/FlatMenusTest.jfd | 69 +++++++++++++++- .../formdev/flatlaf/FlatTestLaf.properties | 10 +++ 6 files changed, 251 insertions(+), 14 deletions(-) create mode 100644 flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuSeparatorUI.java diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuSeparatorUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuSeparatorUI.java new file mode 100644 index 00000000..827fac53 --- /dev/null +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuSeparatorUI.java @@ -0,0 +1,42 @@ +/* + * Copyright 2019 FormDev Software GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.formdev.flatlaf.ui; + +import javax.swing.JComponent; +import javax.swing.plaf.ComponentUI; + +/** + * Provides the Flat LaF UI delegate for {@link javax.swing.JPopupMenu.Separator}. + * + * @author Karl Tauber + */ +public class FlatPopupMenuSeparatorUI + extends FlatSeparatorUI +{ + private static ComponentUI instance; + + public static ComponentUI createUI( JComponent c ) { + if( instance == null ) + instance = new FlatPopupMenuSeparatorUI(); + return instance; + } + + @Override + protected String getPropertyPrefix() { + return "PopupMenuSeparator"; + } +} diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSeparatorUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSeparatorUI.java index 8b5fac81..bcf89870 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSeparatorUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSeparatorUI.java @@ -23,18 +23,27 @@ import java.awt.Graphics2D; import java.awt.geom.Rectangle2D; import javax.swing.JComponent; import javax.swing.JSeparator; +import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicSeparatorUI; /** * Provides the Flat LaF UI delegate for {@link javax.swing.JSeparator}. * + * @uiDefault Separator.background Color unused + * @uiDefault Separator.foreground Color + * @uiDefault Separator.height int height (or width) of the component; may be larger than stripe + * @uiDefault Separator.stripeWidth int width of the stripe + * @uiDefault Separator.stripeIndent int indent of stripe from top (or left); allows positioning of stripe within component + * * @author Karl Tauber */ public class FlatSeparatorUI extends BasicSeparatorUI { - private static final int WIDTH = 2; + protected int height; + protected int stripeWidth; + protected int stripeIndent; private static ComponentUI instance; @@ -45,20 +54,43 @@ public class FlatSeparatorUI } @Override - public void paint( Graphics g, JComponent c ) { - g.setColor( c.getForeground() ); + protected void installDefaults( JSeparator s ) { + super.installDefaults( s ); - if( ((JSeparator)c).getOrientation() == JSeparator.VERTICAL ) - ((Graphics2D)g).fill( new Rectangle2D.Float( 0, 0, scale( (float) WIDTH ), c.getHeight() ) ); - else - ((Graphics2D)g).fill( new Rectangle2D.Float( 0, 0, c.getWidth(), scale( (float) WIDTH ) ) ); + String prefix = getPropertyPrefix(); + height = UIManager.getInt( prefix + ".height" ); + stripeWidth = UIManager.getInt( prefix + ".stripeWidth" ); + stripeIndent = UIManager.getInt( prefix + ".stripeIndent" ); + } + + protected String getPropertyPrefix() { + return "Separator"; + } + + @Override + public void paint( Graphics g, JComponent c ) { + Graphics2D g2 = (Graphics2D) g.create(); + try { + FlatUIUtils.setRenderingHints( g2 ); + g2.setColor( c.getForeground() ); + + float width = scale( (float) stripeWidth ); + float indent = scale( (float) stripeIndent ); + + if( ((JSeparator)c).getOrientation() == JSeparator.VERTICAL ) + g2.fill( new Rectangle2D.Float( indent, 0, width, c.getHeight() ) ); + else + g2.fill( new Rectangle2D.Float( 0, indent, c.getWidth(), width ) ); + } finally { + g2.dispose(); + } } @Override public Dimension getPreferredSize( JComponent c ) { if( ((JSeparator) c).getOrientation() == JSeparator.VERTICAL ) - return new Dimension( scale( WIDTH ), 0 ); + return new Dimension( scale( height ), 0 ); else - return new Dimension( 0, scale( WIDTH ) ); + return new Dimension( 0, scale( height ) ); } } diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index 02970f88..94912de6 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -27,6 +27,7 @@ MenuUI=com.formdev.flatlaf.ui.FlatMenuUI MenuBarUI=com.formdev.flatlaf.ui.FlatMenuBarUI MenuItemUI=com.formdev.flatlaf.ui.FlatMenuItemUI PasswordFieldUI=com.formdev.flatlaf.ui.FlatPasswordFieldUI +PopupMenuSeparatorUI=com.formdev.flatlaf.ui.FlatPopupMenuSeparatorUI ProgressBarUI=com.formdev.flatlaf.ui.FlatProgressBarUI RadioButtonUI=com.formdev.flatlaf.ui.FlatRadioButtonUI RadioButtonMenuItemUI=com.formdev.flatlaf.ui.FlatRadioButtonMenuItemUI @@ -123,6 +124,13 @@ PasswordField.background=@textComponentBackground PasswordField.margin=@textComponentMargin +#---- PopupMenuSeparator ---- + +PopupMenuSeparator.height=9 +PopupMenuSeparator.stripeWidth=1 +PopupMenuSeparator.stripeIndent=4 + + #---- ProgressBar ---- ProgressBar.border=com.formdev.flatlaf.ui.FlatEmptyBorder @@ -154,6 +162,13 @@ ScrollPane.border=com.formdev.flatlaf.ui.FlatBorder ScrollPane.background=@@ScrollBar.track +#---- Separator ---- + +Separator.height=3 +Separator.stripeWidth=1 +Separator.stripeIndent=1 + + #---- Slider ---- Slider.focusInsets=0,0,0,0 diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/FlatMenusTest.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/FlatMenusTest.java index 2664755f..b34a328d 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/FlatMenusTest.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/FlatMenusTest.java @@ -52,6 +52,13 @@ public class FlatMenusTest } } + private void showPopupMenuButtonActionPerformed(ActionEvent e) { + Component invoker = (Component) e.getSource(); + PopupMenu popupMenu = new PopupMenu(); + popupMenu.applyComponentOrientation( getComponentOrientation() ); + popupMenu.show( invoker, 0, invoker.getHeight() ); + } + private void initComponents() { // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents JLabel menuBarLabel = new JLabel(); @@ -71,6 +78,8 @@ public class FlatMenusTest JCheckBoxMenuItem checkBoxMenuItem1 = new JCheckBoxMenuItem(); JLabel radioButtonMenuItemLabel = new JLabel(); JRadioButtonMenuItem radioButtonMenuItem1 = new JRadioButtonMenuItem(); + JLabel popupMenuSeparatorLabel = new JLabel(); + JPopupMenu.Separator separator1 = new JPopupMenu.Separator(); JPanel panel2 = new JPanel(); JMenu menu2 = new JMenu(); JMenuItem menuItem2 = new JMenuItem(); @@ -86,6 +95,8 @@ public class FlatMenusTest JMenuItem menuItem4 = new JMenuItem(); JCheckBoxMenuItem checkBoxMenuItem4 = new JCheckBoxMenuItem(); JRadioButtonMenuItem radioButtonMenuItem4 = new JRadioButtonMenuItem(); + JLabel popupMenuLabel = new JLabel(); + JButton showPopupMenuButton = new JButton(); armedCheckBox = new JCheckBox(); //======== this ======== @@ -151,6 +162,7 @@ public class FlatMenusTest "[]" + "[]" + "[]" + + "[]" + "[]")); //---- menuLabel ---- @@ -189,6 +201,11 @@ public class FlatMenusTest radioButtonMenuItem1.setText("enabled"); radioButtonMenuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0)); panel1.add(radioButtonMenuItem1, "cell 1 3"); + + //---- popupMenuSeparatorLabel ---- + popupMenuSeparatorLabel.setText("JPopupMenu.Separator:"); + panel1.add(popupMenuSeparatorLabel, "cell 0 4"); + panel1.add(separator1, "cell 1 4"); } add(panel1, "cell 0 1 2 1"); @@ -202,6 +219,7 @@ public class FlatMenusTest "[]" + "[]" + "[]" + + "[]" + "[]")); //======== menu2 ======== @@ -312,15 +330,74 @@ public class FlatMenusTest } add(panel4, "cell 4 1"); + //---- popupMenuLabel ---- + popupMenuLabel.setText("JPopupMenu:"); + add(popupMenuLabel, "cell 0 2"); + + //---- showPopupMenuButton ---- + showPopupMenuButton.setText("show JPopupMenu"); + showPopupMenuButton.addActionListener(e -> showPopupMenuButtonActionPerformed(e)); + add(showPopupMenuButton, "cell 1 2"); + //---- armedCheckBox ---- armedCheckBox.setText("armed"); armedCheckBox.setMnemonic('A'); armedCheckBox.addActionListener(e -> armedChanged()); - add(armedCheckBox, "cell 0 2 2 1"); + add(armedCheckBox, "cell 0 3"); // JFormDesigner - End of component initialization //GEN-END:initComponents } // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables private JCheckBox armedCheckBox; // JFormDesigner - End of variables declaration //GEN-END:variables + + private class PopupMenu extends JPopupMenu { + private PopupMenu() { + initComponents(); + } + + private void initComponents() { + // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents + JMenuItem menuItem9 = new JMenuItem(); + JMenuItem menuItem10 = new JMenuItem(); + JCheckBoxMenuItem checkBoxMenuItem5 = new JCheckBoxMenuItem(); + JMenu menu7 = new JMenu(); + JMenuItem menuItem11 = new JMenuItem(); + JMenuItem menuItem12 = new JMenuItem(); + + //======== this ======== + + //---- menuItem9 ---- + menuItem9.setText("text"); + add(menuItem9); + + //---- menuItem10 ---- + menuItem10.setText("text"); + add(menuItem10); + addSeparator(); + + //---- checkBoxMenuItem5 ---- + checkBoxMenuItem5.setText("text"); + checkBoxMenuItem5.setSelected(true); + add(checkBoxMenuItem5); + + //======== menu7 ======== + { + menu7.setText("text"); + + //---- menuItem11 ---- + menuItem11.setText("text"); + menu7.add(menuItem11); + + //---- menuItem12 ---- + menuItem12.setText("text"); + menu7.add(menuItem12); + } + add(menu7); + // JFormDesigner - End of component initialization //GEN-END:initComponents + } + + // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables + // JFormDesigner - End of variables declaration //GEN-END:variables + } } diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/FlatMenusTest.jfd b/flatlaf-core/src/test/java/com/formdev/flatlaf/FlatMenusTest.jfd index a0f3e16e..6115489a 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/FlatMenusTest.jfd +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/FlatMenusTest.jfd @@ -49,7 +49,7 @@ new FormModel { } ) add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { "$columnConstraints": "[125,left][fill]" - "$rowConstraints": "[][][][]" + "$rowConstraints": "[][][][][]" "$layoutConstraints": "insets 0,hidemode 3,gap 5 5,ltr" } ) { name: "panel1" @@ -104,12 +104,23 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 3" } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "popupMenuSeparatorLabel" + "text": "JPopupMenu.Separator:" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 4" + } ) + add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) { + name: "separator1" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 4" + } ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 1 2 1" } ) add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { "$columnConstraints": "[fill]" - "$rowConstraints": "[][][][]" + "$rowConstraints": "[][][][][]" "$layoutConstraints": "insets 0,gap 5 5" } ) { name: "panel2" @@ -230,6 +241,19 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 4 1" } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "popupMenuLabel" + "text": "JPopupMenu:" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 2" + } ) + add( new FormComponent( "javax.swing.JButton" ) { + name: "showPopupMenuButton" + "text": "show JPopupMenu" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showPopupMenuButtonActionPerformed", true ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 2" + } ) add( new FormComponent( "javax.swing.JCheckBox" ) { name: "armedCheckBox" "text": "armed" @@ -239,11 +263,48 @@ new FormModel { } addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "armedChanged", false ) ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 2 2 1" + "value": "cell 0 3" } ) }, new FormLayoutConstraints( null ) { "location": new java.awt.Point( 0, 0 ) - "size": new java.awt.Dimension( 790, 715 ) + "size": new java.awt.Dimension( 790, 380 ) + } ) + add( new FormContainer( "javax.swing.JPopupMenu", new FormLayoutManager( class javax.swing.JPopupMenu ) ) { + name: "popupMenu1" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + "JavaCodeGenerator.className": "PopupMenu" + } + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "menuItem9" + "text": "text" + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "menuItem10" + "text": "text" + } ) + add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) { + name: "separator2" + } ) + add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) { + name: "checkBoxMenuItem5" + "text": "text" + "selected": true + } ) + add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) { + name: "menu7" + "text": "text" + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "menuItem11" + "text": "text" + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "menuItem12" + "text": "text" + } ) + } ) + }, new FormLayoutConstraints( null ) { + "location": new java.awt.Point( 0, 430 ) } ) } } diff --git a/flatlaf-core/src/test/resources/com/formdev/flatlaf/FlatTestLaf.properties b/flatlaf-core/src/test/resources/com/formdev/flatlaf/FlatTestLaf.properties index 9b4519b3..710389f2 100644 --- a/flatlaf-core/src/test/resources/com/formdev/flatlaf/FlatTestLaf.properties +++ b/flatlaf-core/src/test/resources/com/formdev/flatlaf/FlatTestLaf.properties @@ -121,6 +121,13 @@ MenuItemCheckBox.icon.checkmarkColor=4D89C9 MenuItemCheckBox.icon.disabledCheckmarkColor=ABABAB +#---- PopupMenuSeparator ---- + +PopupMenuSeparator.height=30 +PopupMenuSeparator.stripeWidth=3 +PopupMenuSeparator.stripeIndent=1 + + #---- ProgressBar ---- ProgressBar.background=88ff88 @@ -139,6 +146,9 @@ ScrollBar.thumb=33737373 #---- Separator ---- Separator.foreground=00bb00 +Separator.height=20 +Separator.stripeWidth=10 +Separator.stripeIndent=5 #---- Slider ----