From 38eb91442067757e056975ebc48754d5d840cb12 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Sat, 2 May 2020 14:29:20 +0200 Subject: [PATCH] Mnemonics: scale underline; added mnemonic test app FlatTestFrame: Metal Laf is now at F12 so that F10 is unused because F10 is a standard key to move focus to menu bar --- .../com/formdev/flatlaf/ui/FlatUIUtils.java | 18 + .../flatlaf/testing/FlatMnemonicsTest.java | 439 ++++++++++++++++++ .../flatlaf/testing/FlatMnemonicsTest.jfd | 342 ++++++++++++++ .../flatlaf/testing/FlatTestFrame.java | 48 +- 4 files changed, 829 insertions(+), 18 deletions(-) create mode 100644 flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatMnemonicsTest.java create mode 100644 flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatMnemonicsTest.jfd diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java index 35c5b888..3bcdbf32 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java @@ -42,6 +42,7 @@ import javax.swing.UIManager; import javax.swing.plaf.UIResource; import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.util.DerivedColor; +import com.formdev.flatlaf.util.Graphics2DProxy; import com.formdev.flatlaf.util.HiDPIUtils; import com.formdev.flatlaf.util.JavaCompatibility; import com.formdev.flatlaf.util.UIScale; @@ -427,6 +428,23 @@ public class FlatUIUtils public static void drawStringUnderlineCharAt( JComponent c, Graphics g, String text, int underlinedIndex, int x, int y ) { + // scale underline height if necessary + if( underlinedIndex >= 0 && UIScale.getUserScaleFactor() > 1 ) { + g = new Graphics2DProxy( (Graphics2D) g ) { + @Override + public void fillRect( int x, int y, int width, int height ) { + if( height == 1 ) { + // scale height and correct y position + // (using 0.9f so that underline height is 1 at scale factor 1.5x) + height = Math.round( UIScale.scale( 0.9f ) ); + y += height - 1; + } + + super.fillRect( x, y, width, height ); + } + }; + } + JavaCompatibility.drawStringUnderlineCharAt( c, g, text, underlinedIndex, x, y ); } diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatMnemonicsTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatMnemonicsTest.java new file mode 100644 index 00000000..19665adb --- /dev/null +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatMnemonicsTest.java @@ -0,0 +1,439 @@ +/* + * Copyright 2020 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 + * + * https://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.testing; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import net.miginfocom.swing.*; + +/** + * @author Karl Tauber + */ +public class FlatMnemonicsTest + extends FlatTestPanel +{ + public static void main( String[] args ) { + SwingUtilities.invokeLater( () -> { + FlatTestFrame frame = FlatTestFrame.create( args, "FlatMnemonicsTest" ); + frame.showFrame( FlatMnemonicsTest::new, panel -> ((FlatMnemonicsTest)panel).menuBar ); + } ); + } + + FlatMnemonicsTest() { + initComponents(); + } + + private void menuItemActionPerformed(ActionEvent e) { + SwingUtilities.invokeLater( () -> { + JOptionPane.showMessageDialog( this, e.getActionCommand(), "Menu Item", JOptionPane.PLAIN_MESSAGE ); + } ); + } + + private void textArea1KeyReleased(KeyEvent e) { + if( e.getKeyCode() == KeyEvent.VK_ALT ) { + System.out.println( "++++ consume Alt key on release +++++++++++++++++++++++++++++++++++++++++++++++++++++" ); + e.consume(); + } + } + + private void alwaysShowMnemonicsChanged() { + UIManager.put( "Component.hideMnemonics", !alwaysShowMnemonicsCheckBox.isSelected() ); + SwingUtilities.windowForComponent( this ).repaint(); + } + + private void initComponents() { + // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents + JLabel label1 = new JLabel(); + JTextField textField1 = new JTextField(); + JLabel label2 = new JLabel(); + JTextField textField2 = new JTextField(); + JLabel label3 = new JLabel(); + JComboBox comboBox1 = new JComboBox<>(); + JCheckBox checkBox1 = new JCheckBox(); + JButton button1 = new JButton(); + JLabel label4 = new JLabel(); + JScrollPane scrollPane1 = new JScrollPane(); + JTextArea textArea1 = new JTextArea(); + JTabbedPane tabbedPane1 = new JTabbedPane(); + JPanel panel1 = new JPanel(); + JLabel label7 = new JLabel(); + JPanel panel2 = new JPanel(); + JLabel label6 = new JLabel(); + JPanel panel3 = new JPanel(); + JLabel label5 = new JLabel(); + alwaysShowMnemonicsCheckBox = new JCheckBox(); + menuBar = new JMenuBar(); + JMenu fileMenu = new JMenu(); + JMenuItem newMenuItem = new JMenuItem(); + JMenuItem openMenuItem = new JMenuItem(); + JMenuItem closeMenuItem = new JMenuItem(); + JMenuItem closeMenuItem2 = new JMenuItem(); + JMenuItem exitMenuItem = new JMenuItem(); + JMenu editMenu = new JMenu(); + JMenuItem undoMenuItem = new JMenuItem(); + JMenuItem redoMenuItem = new JMenuItem(); + JMenuItem cutMenuItem = new JMenuItem(); + JMenuItem copyMenuItem = new JMenuItem(); + JMenuItem pasteMenuItem = new JMenuItem(); + JMenuItem deleteMenuItem = new JMenuItem(); + JMenu viewMenu = new JMenu(); + JCheckBoxMenuItem checkBoxMenuItem1 = new JCheckBoxMenuItem(); + JMenu menu1 = new JMenu(); + JMenu subViewsMenu = new JMenu(); + JMenu subSubViewsMenu = new JMenu(); + JMenuItem errorLogViewMenuItem = new JMenuItem(); + JMenuItem searchViewMenuItem = new JMenuItem(); + JMenuItem projectViewMenuItem = new JMenuItem(); + JMenuItem structureViewMenuItem = new JMenuItem(); + JMenuItem propertiesViewMenuItem = new JMenuItem(); + JMenu helpMenu = new JMenu(); + JMenuItem aboutMenuItem = new JMenuItem(); + JPopupMenu popupMenu1 = new JPopupMenu(); + JMenuItem cutMenuItem2 = new JMenuItem(); + JMenuItem copyMenuItem2 = new JMenuItem(); + JMenuItem pasteMenuItem2 = new JMenuItem(); + + //======== this ======== + setLayout(new MigLayout( + "ltr,insets dialog,hidemode 3", + // columns + "[fill]" + + "[150,fill]para" + + "[grow,fill]", + // rows + "[]" + + "[]" + + "[]" + + "[]" + + "[]para" + + "[]" + + "[]para" + + "[]")); + + //---- label1 ---- + label1.setText("Name"); + label1.setLabelFor(textField1); + label1.setDisplayedMnemonic('N'); + add(label1, "cell 0 0,alignx left,growx 0"); + + //---- textField1 ---- + textField1.setComponentPopupMenu(popupMenu1); + add(textField1, "cell 1 0"); + + //---- label2 ---- + label2.setText("Phone"); + label2.setLabelFor(textField2); + label2.setDisplayedMnemonic('P'); + add(label2, "cell 0 1"); + + //---- textField2 ---- + textField2.setComponentPopupMenu(popupMenu1); + add(textField2, "cell 1 1"); + + //---- label3 ---- + label3.setText("Planet"); + label3.setDisplayedMnemonic('A'); + label3.setLabelFor(comboBox1); + add(label3, "cell 0 2"); + + //---- comboBox1 ---- + comboBox1.setModel(new DefaultComboBoxModel<>(new String[] { + "Earth", + "Moon", + "Mars" + })); + comboBox1.setComponentPopupMenu(popupMenu1); + add(comboBox1, "cell 1 2"); + + //---- checkBox1 ---- + checkBox1.setText("Astronaut"); + checkBox1.setMnemonic('S'); + checkBox1.setComponentPopupMenu(popupMenu1); + add(checkBox1, "cell 1 3"); + + //---- button1 ---- + button1.setText("Lift off"); + button1.setMnemonic('L'); + button1.setComponentPopupMenu(popupMenu1); + add(button1, "cell 1 4,alignx left,growx 0"); + + //---- label4 ---- + label4.setText("Text area that consumes Alt key:"); + label4.setLabelFor(textArea1); + label4.setDisplayedMnemonic('T'); + add(label4, "cell 1 5"); + + //======== scrollPane1 ======== + { + + //---- textArea1 ---- + textArea1.setRows(4); + textArea1.setComponentPopupMenu(popupMenu1); + textArea1.addKeyListener(new KeyAdapter() { + @Override + public void keyReleased(KeyEvent e) { + textArea1KeyReleased(e); + } + }); + scrollPane1.setViewportView(textArea1); + } + add(scrollPane1, "cell 1 6,grow"); + + //======== tabbedPane1 ======== + { + + //======== panel1 ======== + { + panel1.setLayout(new FlowLayout()); + + //---- label7 ---- + label7.setText("Guitar"); + panel1.add(label7); + } + tabbedPane1.addTab("Guitar", panel1); + tabbedPane1.setMnemonicAt(0, 'G'); + + //======== panel2 ======== + { + panel2.setLayout(new FlowLayout()); + + //---- label6 ---- + label6.setText("Drums"); + panel2.add(label6); + } + tabbedPane1.addTab("Drums", panel2); + tabbedPane1.setMnemonicAt(1, 'D'); + + //======== panel3 ======== + { + panel3.setLayout(new FlowLayout()); + + //---- label5 ---- + label5.setText("Keyboard"); + panel3.add(label5); + } + tabbedPane1.addTab("Keyboard", panel3); + tabbedPane1.setMnemonicAt(2, 'K'); + } + add(tabbedPane1, "cell 2 6,aligny top,growy 0"); + + //---- alwaysShowMnemonicsCheckBox ---- + alwaysShowMnemonicsCheckBox.setText("Always show mnemonics"); + alwaysShowMnemonicsCheckBox.setMnemonic('M'); + alwaysShowMnemonicsCheckBox.addActionListener(e -> alwaysShowMnemonicsChanged()); + add(alwaysShowMnemonicsCheckBox, "cell 0 7 2 1,alignx left,growx 0"); + + //======== menuBar ======== + { + + //======== fileMenu ======== + { + fileMenu.setText("File"); + fileMenu.setMnemonic('F'); + + //---- newMenuItem ---- + newMenuItem.setText("New"); + newMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_J, KeyEvent.CTRL_MASK)); + newMenuItem.setMnemonic('N'); + newMenuItem.addActionListener(e -> menuItemActionPerformed(e)); + fileMenu.add(newMenuItem); + + //---- openMenuItem ---- + openMenuItem.setText("Open"); + openMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_J, KeyEvent.ALT_MASK)); + openMenuItem.setMnemonic('O'); + openMenuItem.addActionListener(e -> menuItemActionPerformed(e)); + fileMenu.add(openMenuItem); + fileMenu.addSeparator(); + + //---- closeMenuItem ---- + closeMenuItem.setText("Close"); + closeMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_J, KeyEvent.CTRL_MASK|KeyEvent.ALT_MASK)); + closeMenuItem.setMnemonic('C'); + closeMenuItem.addActionListener(e -> menuItemActionPerformed(e)); + fileMenu.add(closeMenuItem); + + //---- closeMenuItem2 ---- + closeMenuItem2.setText("Close All"); + closeMenuItem2.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_J, KeyEvent.ALT_MASK|KeyEvent.SHIFT_MASK)); + closeMenuItem2.addActionListener(e -> menuItemActionPerformed(e)); + fileMenu.add(closeMenuItem2); + fileMenu.addSeparator(); + + //---- exitMenuItem ---- + exitMenuItem.setText("Exit"); + exitMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_J, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()|KeyEvent.ALT_MASK|KeyEvent.SHIFT_MASK)); + exitMenuItem.setMnemonic('X'); + exitMenuItem.addActionListener(e -> menuItemActionPerformed(e)); + fileMenu.add(exitMenuItem); + } + menuBar.add(fileMenu); + + //======== editMenu ======== + { + editMenu.setText("Edit"); + editMenu.setMnemonic('E'); + + //---- undoMenuItem ---- + undoMenuItem.setText("Undo"); + undoMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + undoMenuItem.setMnemonic('U'); + undoMenuItem.addActionListener(e -> menuItemActionPerformed(e)); + editMenu.add(undoMenuItem); + + //---- redoMenuItem ---- + redoMenuItem.setText("Redo"); + redoMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + redoMenuItem.setMnemonic('R'); + redoMenuItem.addActionListener(e -> menuItemActionPerformed(e)); + editMenu.add(redoMenuItem); + editMenu.addSeparator(); + + //---- cutMenuItem ---- + cutMenuItem.setText("Cut"); + cutMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + cutMenuItem.setMnemonic('C'); + editMenu.add(cutMenuItem); + + //---- copyMenuItem ---- + copyMenuItem.setText("Copy"); + copyMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + copyMenuItem.setMnemonic('O'); + editMenu.add(copyMenuItem); + + //---- pasteMenuItem ---- + pasteMenuItem.setText("Paste"); + pasteMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + pasteMenuItem.setMnemonic('P'); + editMenu.add(pasteMenuItem); + editMenu.addSeparator(); + + //---- deleteMenuItem ---- + deleteMenuItem.setText("Delete"); + deleteMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0)); + deleteMenuItem.setMnemonic('D'); + deleteMenuItem.addActionListener(e -> menuItemActionPerformed(e)); + editMenu.add(deleteMenuItem); + } + menuBar.add(editMenu); + + //======== viewMenu ======== + { + viewMenu.setText("View"); + viewMenu.setMnemonic('V'); + + //---- checkBoxMenuItem1 ---- + checkBoxMenuItem1.setText("Show Toolbar"); + checkBoxMenuItem1.setSelected(true); + checkBoxMenuItem1.setMnemonic('T'); + checkBoxMenuItem1.addActionListener(e -> menuItemActionPerformed(e)); + viewMenu.add(checkBoxMenuItem1); + + //======== menu1 ======== + { + menu1.setText("Show View"); + menu1.setMnemonic('V'); + + //======== subViewsMenu ======== + { + subViewsMenu.setText("Sub Views"); + subViewsMenu.setMnemonic('S'); + + //======== subSubViewsMenu ======== + { + subSubViewsMenu.setText("Sub sub Views"); + subSubViewsMenu.setMnemonic('U'); + + //---- errorLogViewMenuItem ---- + errorLogViewMenuItem.setText("Error Log"); + errorLogViewMenuItem.setMnemonic('E'); + errorLogViewMenuItem.addActionListener(e -> menuItemActionPerformed(e)); + subSubViewsMenu.add(errorLogViewMenuItem); + } + subViewsMenu.add(subSubViewsMenu); + + //---- searchViewMenuItem ---- + searchViewMenuItem.setText("Search"); + searchViewMenuItem.setMnemonic('S'); + searchViewMenuItem.addActionListener(e -> menuItemActionPerformed(e)); + subViewsMenu.add(searchViewMenuItem); + } + menu1.add(subViewsMenu); + + //---- projectViewMenuItem ---- + projectViewMenuItem.setText("Project"); + projectViewMenuItem.setMnemonic('P'); + projectViewMenuItem.addActionListener(e -> menuItemActionPerformed(e)); + menu1.add(projectViewMenuItem); + + //---- structureViewMenuItem ---- + structureViewMenuItem.setText("Structure"); + structureViewMenuItem.setMnemonic('T'); + structureViewMenuItem.addActionListener(e -> menuItemActionPerformed(e)); + menu1.add(structureViewMenuItem); + + //---- propertiesViewMenuItem ---- + propertiesViewMenuItem.setText("Properties"); + propertiesViewMenuItem.setMnemonic('O'); + propertiesViewMenuItem.addActionListener(e -> menuItemActionPerformed(e)); + menu1.add(propertiesViewMenuItem); + } + viewMenu.add(menu1); + } + menuBar.add(viewMenu); + + //======== helpMenu ======== + { + helpMenu.setText("Help"); + helpMenu.setMnemonic('H'); + + //---- aboutMenuItem ---- + aboutMenuItem.setText("About"); + aboutMenuItem.setMnemonic('A'); + aboutMenuItem.addActionListener(e -> menuItemActionPerformed(e)); + helpMenu.add(aboutMenuItem); + } + menuBar.add(helpMenu); + } + + //======== popupMenu1 ======== + { + + //---- cutMenuItem2 ---- + cutMenuItem2.setText("Cut"); + cutMenuItem2.setMnemonic('C'); + popupMenu1.add(cutMenuItem2); + + //---- copyMenuItem2 ---- + copyMenuItem2.setText("Copy"); + copyMenuItem2.setMnemonic('O'); + popupMenu1.add(copyMenuItem2); + + //---- pasteMenuItem2 ---- + pasteMenuItem2.setText("Paste"); + pasteMenuItem2.setMnemonic('P'); + popupMenu1.add(pasteMenuItem2); + } + // JFormDesigner - End of component initialization //GEN-END:initComponents + } + + // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables + private JCheckBox alwaysShowMnemonicsCheckBox; + private JMenuBar menuBar; + // JFormDesigner - End of variables declaration //GEN-END:variables +} diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatMnemonicsTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatMnemonicsTest.jfd new file mode 100644 index 00000000..8558674d --- /dev/null +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatMnemonicsTest.jfd @@ -0,0 +1,342 @@ +JFDML JFormDesigner: "7.0.1.0.272" Java: "13.0.2" encoding: "UTF-8" + +new FormModel { + contentType: "form/swing" + root: new FormRoot { + auxiliary() { + "JavaCodeGenerator.defaultVariableLocal": true + } + add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { + "$layoutConstraints": "ltr,insets dialog,hidemode 3" + "$columnConstraints": "[fill][150,fill]para[grow,fill]" + "$rowConstraints": "[][][][][]para[][]para[]" + } ) { + name: "this" + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label1" + "text": "Name" + "labelFor": new FormReference( "textField1" ) + "displayedMnemonic": 78 + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 0,alignx left,growx 0" + } ) + add( new FormComponent( "javax.swing.JTextField" ) { + name: "textField1" + "componentPopupMenu": &FormReference0 new FormReference( "popupMenu1" ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label2" + "text": "Phone" + "labelFor": new FormReference( "textField2" ) + "displayedMnemonic": 80 + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 1" + } ) + add( new FormComponent( "javax.swing.JTextField" ) { + name: "textField2" + "componentPopupMenu": #FormReference0 + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 1" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label3" + "text": "Planet" + "displayedMnemonic": 65 + "labelFor": new FormReference( "comboBox1" ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 2" + } ) + add( new FormComponent( "javax.swing.JComboBox" ) { + name: "comboBox1" + "model": new javax.swing.DefaultComboBoxModel { + selectedItem: "Earth" + addElement( "Earth" ) + addElement( "Moon" ) + addElement( "Mars" ) + } + "componentPopupMenu": #FormReference0 + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 2" + } ) + add( new FormComponent( "javax.swing.JCheckBox" ) { + name: "checkBox1" + "text": "Astronaut" + "mnemonic": 83 + "componentPopupMenu": #FormReference0 + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 3" + } ) + add( new FormComponent( "javax.swing.JButton" ) { + name: "button1" + "text": "Lift off" + "mnemonic": 76 + "componentPopupMenu": #FormReference0 + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 4,alignx left,growx 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label4" + "text": "Text area that consumes Alt key:" + "labelFor": new FormReference( "textArea1" ) + "displayedMnemonic": 84 + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 5" + } ) + add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) { + name: "scrollPane1" + add( new FormComponent( "javax.swing.JTextArea" ) { + name: "textArea1" + "rows": 4 + "componentPopupMenu": #FormReference0 + addEvent( new FormEvent( "java.awt.event.KeyListener", "keyReleased", "textArea1KeyReleased", true ) ) + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 6,grow" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "tabbedPane1" + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) { + name: "panel1" + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label7" + "text": "Guitar" + } ) + }, new FormLayoutConstraints( null ) { + "title": "Guitar" + "mnemonic": 71 + } ) + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) { + name: "panel2" + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label6" + "text": "Drums" + } ) + }, new FormLayoutConstraints( null ) { + "title": "Drums" + "mnemonic": 68 + } ) + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) { + name: "panel3" + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label5" + "text": "Keyboard" + } ) + }, new FormLayoutConstraints( null ) { + "title": "Keyboard" + "mnemonic": 75 + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 6,aligny top,growy 0" + } ) + add( new FormComponent( "javax.swing.JCheckBox" ) { + name: "alwaysShowMnemonicsCheckBox" + "text": "Always show mnemonics" + "mnemonic": 77 + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "alwaysShowMnemonicsChanged", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 7 2 1,alignx left,growx 0" + } ) + }, new FormLayoutConstraints( null ) { + "location": new java.awt.Point( 0, 0 ) + "size": new java.awt.Dimension( 790, 380 ) + } ) + add( new FormContainer( "javax.swing.JMenuBar", new FormLayoutManager( class javax.swing.JMenuBar ) ) { + name: "menuBar" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) { + name: "fileMenu" + "text": "File" + "mnemonic": 70 + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "newMenuItem" + "text": "New" + "accelerator": static javax.swing.KeyStroke getKeyStroke( 74, 130, false ) + "mnemonic": 78 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "openMenuItem" + "text": "Open" + "accelerator": static javax.swing.KeyStroke getKeyStroke( 74, 520, false ) + "mnemonic": 79 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) { + name: "separator2" + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "closeMenuItem" + "text": "Close" + "accelerator": static javax.swing.KeyStroke getKeyStroke( 74, 650, false ) + "mnemonic": 67 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "closeMenuItem2" + "text": "Close All" + "accelerator": static javax.swing.KeyStroke getKeyStroke( 74, 585, false ) + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) { + name: "separator1" + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "exitMenuItem" + "text": "Exit" + "accelerator": static javax.swing.KeyStroke getKeyStroke( 74, 4811, false ) + "mnemonic": 88 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + } ) + add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) { + name: "editMenu" + "text": "Edit" + "mnemonic": 69 + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "undoMenuItem" + "text": "Undo" + "accelerator": static javax.swing.KeyStroke getKeyStroke( 90, 4226, false ) + "mnemonic": 85 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "redoMenuItem" + "text": "Redo" + "accelerator": static javax.swing.KeyStroke getKeyStroke( 89, 4226, false ) + "mnemonic": 82 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) { + name: "separator4" + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "cutMenuItem" + "text": "Cut" + "accelerator": static javax.swing.KeyStroke getKeyStroke( 88, 4226, false ) + "mnemonic": 67 + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "copyMenuItem" + "text": "Copy" + "accelerator": static javax.swing.KeyStroke getKeyStroke( 67, 4226, false ) + "mnemonic": 79 + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "pasteMenuItem" + "text": "Paste" + "accelerator": static javax.swing.KeyStroke getKeyStroke( 86, 4226, false ) + "mnemonic": 80 + } ) + add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) { + name: "separator3" + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "deleteMenuItem" + "text": "Delete" + "accelerator": static javax.swing.KeyStroke getKeyStroke( 127, 0, false ) + "mnemonic": 68 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + } ) + add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) { + name: "viewMenu" + "text": "View" + "mnemonic": 86 + add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) { + name: "checkBoxMenuItem1" + "text": "Show Toolbar" + "selected": true + "mnemonic": 84 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) { + name: "menu1" + "text": "Show View" + "mnemonic": 86 + add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) { + name: "subViewsMenu" + "text": "Sub Views" + "mnemonic": 83 + add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) { + name: "subSubViewsMenu" + "text": "Sub sub Views" + "mnemonic": 85 + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "errorLogViewMenuItem" + "text": "Error Log" + "mnemonic": 69 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "searchViewMenuItem" + "text": "Search" + "mnemonic": 83 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "projectViewMenuItem" + "text": "Project" + "mnemonic": 80 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "structureViewMenuItem" + "text": "Structure" + "mnemonic": 84 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "propertiesViewMenuItem" + "text": "Properties" + "mnemonic": 79 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + } ) + } ) + add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) { + name: "helpMenu" + "text": "Help" + "mnemonic": 72 + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "aboutMenuItem" + "text": "About" + "mnemonic": 65 + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) + } ) + } ) + }, new FormLayoutConstraints( null ) { + "location": new java.awt.Point( 0, 410 ) + "size": new java.awt.Dimension( 255, 30 ) + } ) + add( new FormContainer( "javax.swing.JPopupMenu", new FormLayoutManager( class javax.swing.JPopupMenu ) ) { + name: "popupMenu1" + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "cutMenuItem2" + "text": "Cut" + "mnemonic": 67 + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "copyMenuItem2" + "text": "Copy" + "mnemonic": 79 + } ) + add( new FormComponent( "javax.swing.JMenuItem" ) { + name: "pasteMenuItem2" + "text": "Paste" + "mnemonic": 80 + } ) + }, new FormLayoutConstraints( null ) { + "location": new java.awt.Point( 300, 415 ) + "size": new java.awt.Dimension( 91, 87 ) + } ) + } +} diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java index ab9f1051..2b153310 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java @@ -23,6 +23,7 @@ import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.function.BiConsumer; +import java.util.function.Function; import java.util.function.Supplier; import javax.swing.*; import javax.swing.UIManager.LookAndFeelInfo; @@ -104,7 +105,7 @@ public class FlatTestFrame (SystemInfo.IS_LINUX && className.equals( "com.sun.java.swing.plaf.gtk.GTKLookAndFeel") ) ) name += " (F9)"; else if( className.equals( MetalLookAndFeel.class.getName() ) ) - name += " (F10)"; + name += " (F12)"; else if( className.equals( NimbusLookAndFeel.class.getName() ) ) name += " (F11)"; @@ -114,25 +115,25 @@ public class FlatTestFrame String substanceClassName = "org.pushingpixels.substance.api.skin.SubstanceGraphiteAquaLookAndFeel"; if( SystemInfo.IS_JAVA_9_OR_LATER && isClassAvailable( substanceClassName ) ) { lafModel.addElement( new LookAndFeelInfo( "Substance (F5)", substanceClassName ) ); - registerSwitchToLookAndFeel( KeyEvent.VK_F5, substanceClassName ); + registerSwitchToLookAndFeel( "F5", substanceClassName ); } String webLafClassName = "com.alee.laf.WebLookAndFeel"; if( isClassAvailable( webLafClassName ) ) { - lafModel.addElement( new LookAndFeelInfo( "WebLaf (F12)", webLafClassName ) ); - registerSwitchToLookAndFeel( KeyEvent.VK_F12, webLafClassName ); + lafModel.addElement( new LookAndFeelInfo( "WebLaf (Ctrl+F12)", webLafClassName ) ); + registerSwitchToLookAndFeel( "ctrl F12", webLafClassName ); } String looksPlasticClassName = "com.jgoodies.looks.plastic.PlasticLookAndFeel"; if( isClassAvailable( looksPlasticClassName ) ) { lafModel.addElement( new LookAndFeelInfo( "JGoodies Looks Plastic (F6)", looksPlasticClassName ) ); - registerSwitchToLookAndFeel( KeyEvent.VK_F6, looksPlasticClassName ); + registerSwitchToLookAndFeel( "F6", looksPlasticClassName ); } String looksWindowsClassName = "com.jgoodies.looks.windows.WindowsLookAndFeel"; if( SystemInfo.IS_WINDOWS && isClassAvailable( looksWindowsClassName ) ) { lafModel.addElement( new LookAndFeelInfo( "JGoodies Looks Windows (F7)", looksWindowsClassName ) ); - registerSwitchToLookAndFeel( KeyEvent.VK_F7, looksWindowsClassName ); + registerSwitchToLookAndFeel( "F7", looksWindowsClassName ); } lookAndFeelComboBox.setModel( lafModel ); @@ -145,21 +146,21 @@ public class FlatTestFrame updateSizeVariantComboBox(); // register F1, F2, ... keys to switch to Light, Dark or other LaFs - registerSwitchToLookAndFeel( KeyEvent.VK_F1, FlatLightLaf.class.getName() ); - registerSwitchToLookAndFeel( KeyEvent.VK_F2, FlatDarkLaf.class.getName() ); - registerSwitchToLookAndFeel( KeyEvent.VK_F3, FlatIntelliJLaf.class.getName() ); - registerSwitchToLookAndFeel( KeyEvent.VK_F4, FlatDarculaLaf.class.getName() ); + registerSwitchToLookAndFeel( "F1", FlatLightLaf.class.getName() ); + registerSwitchToLookAndFeel( "F2", FlatDarkLaf.class.getName() ); + registerSwitchToLookAndFeel( "F3", FlatIntelliJLaf.class.getName() ); + registerSwitchToLookAndFeel( "F4", FlatDarculaLaf.class.getName() ); - registerSwitchToLookAndFeel( KeyEvent.VK_F8, FlatTestLaf.class.getName() ); + registerSwitchToLookAndFeel( "F8", FlatTestLaf.class.getName() ); if( SystemInfo.IS_WINDOWS ) - registerSwitchToLookAndFeel( KeyEvent.VK_F9, "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" ); + registerSwitchToLookAndFeel( "F9", "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" ); else if( SystemInfo.IS_MAC ) - registerSwitchToLookAndFeel( KeyEvent.VK_F9, "com.apple.laf.AquaLookAndFeel" ); + registerSwitchToLookAndFeel( "F9", "com.apple.laf.AquaLookAndFeel" ); else if( SystemInfo.IS_LINUX ) - registerSwitchToLookAndFeel( KeyEvent.VK_F9, "com.sun.java.swing.plaf.gtk.GTKLookAndFeel" ); - registerSwitchToLookAndFeel( KeyEvent.VK_F10, MetalLookAndFeel.class.getName() ); - registerSwitchToLookAndFeel( KeyEvent.VK_F11, NimbusLookAndFeel.class.getName() ); + registerSwitchToLookAndFeel( "F9", "com.sun.java.swing.plaf.gtk.GTKLookAndFeel" ); + registerSwitchToLookAndFeel( "F12", MetalLookAndFeel.class.getName() ); + registerSwitchToLookAndFeel( "F11", NimbusLookAndFeel.class.getName() ); // register ESC key to close frame ((JComponent)getContentPane()).registerKeyboardAction( @@ -228,12 +229,16 @@ public class FlatTestFrame setTitle( newTitle ); } - private void registerSwitchToLookAndFeel( int keyCode, String lafClassName ) { + private void registerSwitchToLookAndFeel( String keyStrokeStr, String lafClassName ) { + KeyStroke keyStroke = KeyStroke.getKeyStroke( keyStrokeStr ); + if( keyStroke == null ) + throw new IllegalArgumentException( "Invalid key stroke '" + keyStrokeStr + "'" ); + ((JComponent)getContentPane()).registerKeyboardAction( e -> { selectLookAndFeel( lafClassName ); }, - KeyStroke.getKeyStroke( keyCode, 0, false ), + keyStroke, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); } @@ -247,9 +252,16 @@ public class FlatTestFrame } public void showFrame( Supplier contentFactory ) { + showFrame( contentFactory, null ); + } + + public void showFrame( Supplier contentFactory, Function menuBarFactory ) { this.contentFactory = contentFactory; this.content = contentFactory.get(); + if( menuBarFactory != null ) + setJMenuBar( menuBarFactory.apply( content ) ); + contentPanel.getContentPane().add( content ); pack(); setLocationRelativeTo( null );