Skip to content

Commit

Permalink
Menu: show arrow icon for top-level JMenu if used in vertical JMenuBa…
Browse files Browse the repository at this point in the history
…r (issue #867)
  • Loading branch information
DevCharly committed Jul 16, 2024
1 parent 32b0f1b commit 14705a9
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.event.InputEvent;
Expand All @@ -35,6 +37,7 @@
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
Expand Down Expand Up @@ -222,7 +225,7 @@ protected Dimension getPreferredMenuItemSize() {
}

// arrow size
if( !isTopLevelMenu && arrowIcon != null ) {
if( arrowIcon != null && (!isTopLevelMenu || isInVerticalMenuBar( menuItem )) ) {
// gap between text and arrow
if( accelText == null )
width += scale( textNoAcceleratorGap );
Expand Down Expand Up @@ -254,7 +257,8 @@ private void layout( Rectangle viewRect, Rectangle iconRect, Rectangle textRect,
boolean isTopLevelMenu = isTopLevelMenu( menuItem );

// layout arrow
if( !isTopLevelMenu && arrowIcon != null ) {
boolean showArrowIcon = (arrowIcon != null && (!isTopLevelMenu || isInVerticalMenuBar( menuItem )));
if( showArrowIcon ) {
arrowRect.width = arrowIcon.getIconWidth();
arrowRect.height = arrowIcon.getIconHeight();
} else
Expand Down Expand Up @@ -288,7 +292,7 @@ private void layout( Rectangle viewRect, Rectangle iconRect, Rectangle textRect,
int accelArrowWidth = accelRect.width + arrowRect.width;
if( accelText != null )
accelArrowWidth += scale( !isTopLevelMenu ? textAcceleratorGap : menuItem.getIconTextGap() );
if( !isTopLevelMenu && arrowIcon != null ) {
if( showArrowIcon ) {
if( accelText == null )
accelArrowWidth += scale( textNoAcceleratorGap );
accelArrowWidth += scale( acceleratorArrowGap );
Expand Down Expand Up @@ -355,7 +359,7 @@ protected void paintMenuItem( Graphics g, Color selectionBackground, Color selec
paintIcon( g, iconRect, getIconForPainting(), underlineSelection ? underlineSelectionCheckBackground : checkBackground, selectionBackground );
paintText( g, textRect, menuItem.getText(), selectionForeground, disabledForeground );
paintAccelerator( g, accelRect, getAcceleratorText(), acceleratorForeground, acceleratorSelectionForeground, disabledForeground );
if( !isTopLevelMenu( menuItem ) )
if( arrowIcon != null && (!isTopLevelMenu( menuItem ) || isInVerticalMenuBar( menuItem )) )
paintArrowIcon( g, arrowRect, arrowIcon );
}

Expand Down Expand Up @@ -520,6 +524,15 @@ protected static boolean isTopLevelMenu( JMenuItem menuItem ) {
return menuItem instanceof JMenu && ((JMenu)menuItem).isTopLevelMenu();
}

/** @since 3.5 */
public static boolean isInVerticalMenuBar( JMenuItem menuItem ) {
if( !(menuItem instanceof JMenu) || !(menuItem.getParent() instanceof JMenuBar) )
return false;

LayoutManager layout = menuItem.getParent().getLayout();
return layout instanceof GridLayout && ((GridLayout)layout).getRows() != 1;
}

protected boolean isUnderlineSelection() {
return "underline".equals( UIManager.getString( "MenuItem.selectionType" ) );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.*;
import java.util.function.Supplier;
import javax.swing.*;
Expand Down Expand Up @@ -49,6 +50,7 @@ public static void main( String[] args ) {
initComponents();

largerCheckBox.setSelected( LargerMenuItem.useLargerSize );
verticalMenuBar.setLayout( new GridLayout( 0, 1 ) );
}

private void armedChanged() {
Expand Down Expand Up @@ -246,7 +248,15 @@ private void initComponents() {
JLabel popupMenuLabel = new JLabel();
JButton showPopupMenuButton = new JButton();
showScrollingPopupMenuButton = new JButton();
JLabel label1 = new JLabel();
armedCheckBox = new JCheckBox();
verticalMenuBar = new JMenuBar();
JMenu menu14 = new JMenu();
JMenuItem menuItem53 = new JMenuItem();
JMenu menu15 = new JMenu();
JMenuItem menuItem54 = new JMenuItem();
JMenu menu16 = new JMenu();
JMenuItem menuItem55 = new JMenuItem();
underlineCheckBox = new JCheckBox();
popupMenubackgroundCheckBox = new JCheckBox();

Expand Down Expand Up @@ -884,13 +894,53 @@ private void initComponents() {
showScrollingPopupMenuButton.addActionListener(e -> showScrollingPopupMenu(e));
add(showScrollingPopupMenuButton, "cell 2 2");

//---- label1 ----
label1.setText("Vertical JMenuBar:");
add(label1, "cell 4 2");

//---- armedCheckBox ----
armedCheckBox.setText("armed");
armedCheckBox.setMnemonic('A');
armedCheckBox.putClientProperty("FlatLaf.internal.testing.ignore", true);
armedCheckBox.addActionListener(e -> armedChanged());
add(armedCheckBox, "cell 0 3");

//======== verticalMenuBar ========
{

//======== menu14 ========
{
menu14.setText("menu");

//---- menuItem53 ----
menuItem53.setText("text");
menu14.add(menuItem53);
}
verticalMenuBar.add(menu14);

//======== menu15 ========
{
menu15.setText("another menu");

//---- menuItem54 ----
menuItem54.setText("text");
menu15.add(menuItem54);
}
verticalMenuBar.add(menu15);

//======== menu16 ========
{
menu16.setText("menu 3");
menu16.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/test16.png")));

//---- menuItem55 ----
menuItem55.setText("text");
menu16.add(menuItem55);
}
verticalMenuBar.add(menu16);
}
add(verticalMenuBar, "cell 4 3 1 3");

//---- underlineCheckBox ----
underlineCheckBox.setText("underline menu selection");
underlineCheckBox.putClientProperty("FlatLaf.internal.testing.ignore", true);
Expand Down Expand Up @@ -931,6 +981,7 @@ protected void paintIcon( Component c, Graphics2D g2 ) {
private JCheckBox accelCheckBox;
private JButton showScrollingPopupMenuButton;
private JCheckBox armedCheckBox;
private JMenuBar verticalMenuBar;
private JCheckBox underlineCheckBox;
private JCheckBox popupMenubackgroundCheckBox;
// JFormDesigner - End of variables declaration //GEN-END:variables
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.5.0.404" Java: "16" encoding: "UTF-8"
JFDML JFormDesigner: "8.2.3.0.386" Java: "21" encoding: "UTF-8"

new FormModel {
contentType: "form/swing"
Expand Down Expand Up @@ -662,6 +662,12 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 2"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label1"
"text": "Vertical JMenuBar:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 2"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "armedCheckBox"
"text": "armed"
Expand All @@ -674,6 +680,39 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3"
} )
add( new FormContainer( "javax.swing.JMenuBar", new FormLayoutManager( class javax.swing.JMenuBar ) ) {
name: "verticalMenuBar"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
name: "menu14"
"text": "menu"
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem53"
"text": "text"
} )
} )
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
name: "menu15"
"text": "another menu"
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem54"
"text": "text"
} )
} )
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
name: "menu16"
"text": "menu 3"
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/test16.png" )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem55"
"text": "text"
} )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 3 1 3"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "underlineCheckBox"
"text": "underline menu selection"
Expand Down

0 comments on commit 14705a9

Please sign in to comment.