Window decorations: added client property to mark components in embedded menu bar as "caption" (issue #569)

This commit is contained in:
Karl Tauber
2022-08-20 19:42:38 +02:00
parent fee7cf6265
commit 16f3f9e6ff
5 changed files with 73 additions and 23 deletions

View File

@@ -7,6 +7,9 @@ FlatLaf Change Log
- TabbedPane: New option to disable tab run rotation in wrap layout. Set UI - TabbedPane: New option to disable tab run rotation in wrap layout. Set UI
value `TabbedPane.rotateTabRuns` to `false`. (issue #574) value `TabbedPane.rotateTabRuns` to `false`. (issue #574)
- Native window decorations (Windows 10/11 only): Added client property to mark
components in embedded menu bar as "caption" (allow moving window). (issue
#569)
#### Fixed bugs #### Fixed bugs

View File

@@ -253,6 +253,19 @@ public interface FlatClientProperties
*/ */
String COMPONENT_FOCUS_OWNER = "JComponent.focusOwner"; String COMPONENT_FOCUS_OWNER = "JComponent.focusOwner";
/**
* Specifies whether a component in a embedded menu bar should behave as caption
* (left-click allows moving window, right-click shows window system menu).
* The component does not receive mouse pressed/released/clicked/dragged events,
* but it gets mouse entered/exited/moved events.
* <p>
* <strong>Component</strong> {@link javax.swing.JComponent}<br>
* <strong>Value type</strong> {@link java.lang.Boolean}
*
* @since 2.5
*/
String COMPONENT_TITLE_BAR_CAPTION = "JComponent.titleBarCaption";
//---- Popup -------------------------------------------------------------- //---- Popup --------------------------------------------------------------
/** /**

View File

@@ -861,14 +861,18 @@ debug*/
r.height -= resizeHeight; r.height -= resizeHeight;
} }
Component horizontalGlue = findHorizontalGlue( menuBar ); int count = menuBar.getComponentCount();
if( horizontalGlue != null ) { for( int i = count - 1; i >= 0; i-- ) {
// If menu bar is embedded and contains a horizontal glue component, Component c = menuBar.getComponent( i );
// then split the hit test spot into two spots so that if( c instanceof Box.Filler ||
// the glue component area can be used to move the window. (c instanceof JComponent && clientPropertyBoolean( (JComponent) c, COMPONENT_TITLE_BAR_CAPTION, false ) ) )
{
// If menu bar is embedded and contains a horizontal glue or caption component,
// then split the hit test spot so that
// the glue/caption component area can be used to move the window.
Point glueLocation = SwingUtilities.convertPoint( horizontalGlue, 0, 0, window ); Point glueLocation = SwingUtilities.convertPoint( c, 0, 0, window );
int x2 = glueLocation.x + horizontalGlue.getWidth(); int x2 = glueLocation.x + c.getWidth();
Rectangle r2; Rectangle r2;
if( getComponentOrientation().isLeftToRight() ) { if( getComponentOrientation().isLeftToRight() ) {
r2 = new Rectangle( x2, r.y, (r.x + r.width) - x2, r.height ); r2 = new Rectangle( x2, r.y, (r.x + r.width) - x2, r.height );
@@ -880,8 +884,10 @@ debug*/
r.width = (r.x + r.width) - x2; r.width = (r.x + r.width) - x2;
r.x = x2; r.x = x2;
} }
if( r2.width > 0 )
hitTestSpots.add( r2 ); hitTestSpots.add( r2 );
} }
}
hitTestSpots.add( r ); hitTestSpots.add( r );
} }

View File

@@ -262,6 +262,16 @@ debug*/
menuBar.revalidate(); menuBar.revalidate();
} }
private void addCaption() {
JLabel caption = new JLabel( "Caption" );
caption.setBackground( Color.green );
caption.setOpaque( true );
caption.putClientProperty( FlatClientProperties.COMPONENT_TITLE_BAR_CAPTION, true );
menuBar.add( caption );
menuBar.revalidate();
}
private void removeMenu() { private void removeMenu() {
int menuCount = menuBar.getMenuCount(); int menuCount = menuBar.getMenuCount();
if( menuCount <= 0 ) if( menuCount <= 0 )
@@ -445,6 +455,7 @@ debug*/
JPanel panel3 = new JPanel(); JPanel panel3 = new JPanel();
addMenuButton = new JButton(); addMenuButton = new JButton();
addGlueButton = new JButton(); addGlueButton = new JButton();
addCaptionButton = new JButton();
removeMenuButton = new JButton(); removeMenuButton = new JButton();
changeMenuButton = new JButton(); changeMenuButton = new JButton();
changeTitleButton = new JButton(); changeTitleButton = new JButton();
@@ -547,6 +558,7 @@ debug*/
"[]" + "[]" +
"[]" + "[]" +
"[]" + "[]" +
"[]" +
"[]unrel" + "[]unrel" +
"[]")); "[]"));
@@ -560,20 +572,25 @@ debug*/
addGlueButton.addActionListener(e -> addGlue()); addGlueButton.addActionListener(e -> addGlue());
panel3.add(addGlueButton, "cell 0 1"); panel3.add(addGlueButton, "cell 0 1");
//---- addCaptionButton ----
addCaptionButton.setText("Add caption");
addCaptionButton.addActionListener(e -> addCaption());
panel3.add(addCaptionButton, "cell 0 2");
//---- removeMenuButton ---- //---- removeMenuButton ----
removeMenuButton.setText("Remove menu"); removeMenuButton.setText("Remove menu");
removeMenuButton.addActionListener(e -> removeMenu()); removeMenuButton.addActionListener(e -> removeMenu());
panel3.add(removeMenuButton, "cell 0 2"); panel3.add(removeMenuButton, "cell 0 3");
//---- changeMenuButton ---- //---- changeMenuButton ----
changeMenuButton.setText("Change menu"); changeMenuButton.setText("Change menu");
changeMenuButton.addActionListener(e -> changeMenu()); changeMenuButton.addActionListener(e -> changeMenu());
panel3.add(changeMenuButton, "cell 0 3"); panel3.add(changeMenuButton, "cell 0 4");
//---- changeTitleButton ---- //---- changeTitleButton ----
changeTitleButton.setText("Change title"); changeTitleButton.setText("Change title");
changeTitleButton.addActionListener(e -> changeTitle()); changeTitleButton.addActionListener(e -> changeTitle());
panel3.add(changeTitleButton, "cell 0 4"); panel3.add(changeTitleButton, "cell 0 5");
} }
add(panel3, "cell 2 0 1 8,aligny top,growy 0"); add(panel3, "cell 2 0 1 8,aligny top,growy 0");
@@ -961,6 +978,7 @@ debug*/
private JCheckBox rightCompCheckBox; private JCheckBox rightCompCheckBox;
private JButton addMenuButton; private JButton addMenuButton;
private JButton addGlueButton; private JButton addGlueButton;
private JButton addCaptionButton;
private JButton removeMenuButton; private JButton removeMenuButton;
private JButton changeMenuButton; private JButton changeMenuButton;
private JButton changeTitleButton; private JButton changeTitleButton;

View File

@@ -36,7 +36,7 @@ new FormModel {
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3" "$layoutConstraints": "hidemode 3"
"$columnConstraints": "[fill]" "$columnConstraints": "[fill]"
"$rowConstraints": "[][][][]unrel[]" "$rowConstraints": "[][][][][]unrel[]"
} ) { } ) {
name: "panel3" name: "panel3"
add( new FormComponent( "javax.swing.JButton" ) { add( new FormComponent( "javax.swing.JButton" ) {
@@ -59,6 +59,16 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1" "value": "cell 0 1"
} ) } )
add( new FormComponent( "javax.swing.JButton" ) {
name: "addCaptionButton"
"text": "Add caption"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "addCaption", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2"
} )
add( new FormComponent( "javax.swing.JButton" ) { add( new FormComponent( "javax.swing.JButton" ) {
name: "removeMenuButton" name: "removeMenuButton"
"text": "Remove menu" "text": "Remove menu"
@@ -67,7 +77,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "removeMenu", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "removeMenu", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2" "value": "cell 0 3"
} ) } )
add( new FormComponent( "javax.swing.JButton" ) { add( new FormComponent( "javax.swing.JButton" ) {
name: "changeMenuButton" name: "changeMenuButton"
@@ -77,7 +87,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "changeMenu", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "changeMenu", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3" "value": "cell 0 4"
} ) } )
add( new FormComponent( "javax.swing.JButton" ) { add( new FormComponent( "javax.swing.JButton" ) {
name: "changeTitleButton" name: "changeTitleButton"
@@ -87,7 +97,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "changeTitle", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "changeTitle", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4" "value": "cell 0 5"
} ) } )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 0 1 8,aligny top,growy 0" "value": "cell 2 0 1 8,aligny top,growy 0"