diff --git a/CHANGELOG.md b/CHANGELOG.md index 814e9d98..49495b45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ FlatLaf Change Log - Button and ToggleButton: Support borderless button style (set client property `JButton.buttonType` to `borderless`). (PR #276) +#### Fixed bugs + +- DesktopPane: Fixed empty minimized icon when using a custom desktop manager. + (PR #294) + ## 1.1.2 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatDesktopPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatDesktopPaneUI.java index eb5b72e9..2d45d655 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatDesktopPaneUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatDesktopPaneUI.java @@ -17,6 +17,7 @@ package com.formdev.flatlaf.ui; import javax.swing.DefaultDesktopManager; +import javax.swing.DesktopManager; import javax.swing.JComponent; import javax.swing.JInternalFrame; import javax.swing.plaf.ComponentUI; @@ -42,11 +43,31 @@ public class FlatDesktopPaneUI @Override protected void installDesktopManager() { - desktopManager = desktop.getDesktopManager(); - if( desktopManager == null ) { - desktopManager = new FlatDesktopManager(); - desktop.setDesktopManager( desktopManager ); - } + // Check current installed desktop manager to avoid recursive call + // with property change event (will fire a stack overflow). + // Do not handle install if already installed. + DesktopManager dm = desktop.getDesktopManager(); + if( dm instanceof FlatDesktopManager || dm instanceof FlatWrapperDesktopManager ) + return; + + desktopManager = (dm != null) + ? new FlatWrapperDesktopManager( dm ) + : new FlatDesktopManager(); + desktop.setDesktopManager( desktopManager ); + } + + @Override + protected void uninstallDesktopManager() { + // uninstall wrapper + DesktopManager dm = desktop.getDesktopManager(); + if( dm instanceof FlatWrapperDesktopManager ) + desktop.setDesktopManager( ((FlatWrapperDesktopManager)dm).parent ); + + super.uninstallDesktopManager(); + } + + private static void updateDockIcon( JInternalFrame f ) { + ((FlatDesktopIconUI)f.getDesktopIcon().getUI()).updateDockIcon(); } //---- class FlatDesktopManager ------------------------------------------- @@ -59,7 +80,99 @@ public class FlatDesktopPaneUI public void iconifyFrame( JInternalFrame f ) { super.iconifyFrame( f ); - ((FlatDesktopIconUI)f.getDesktopIcon().getUI()).updateDockIcon(); + updateDockIcon( f ); + } + } + + //---- class FlatWrapperDesktopManager ------------------------------------ + + /** + * For already installed desktop manager to use the flat desktop manager features. + */ + private class FlatWrapperDesktopManager + implements DesktopManager + { + private final DesktopManager parent; + + private FlatWrapperDesktopManager( DesktopManager parent ) { + this.parent = parent; + } + + @Override + public void openFrame( JInternalFrame f ) { + parent.openFrame( f ); + } + + @Override + public void closeFrame( JInternalFrame f ) { + parent.closeFrame( f ); + } + + @Override + public void maximizeFrame( JInternalFrame f ) { + parent.maximizeFrame( f ); + } + + @Override + public void minimizeFrame( JInternalFrame f ) { + parent.minimizeFrame( f ); + } + + @Override + public void activateFrame( JInternalFrame f ) { + parent.activateFrame( f ); + } + + @Override + public void deactivateFrame( JInternalFrame f ) { + parent.deactivateFrame( f ); + } + + @Override + public void iconifyFrame( JInternalFrame f ) { + parent.iconifyFrame( f ); + + updateDockIcon( f ); + } + + @Override + public void deiconifyFrame( JInternalFrame f ) { + parent.deiconifyFrame( f ); + } + + @Override + public void beginDraggingFrame( JComponent f ) { + parent.beginDraggingFrame( f ); + } + + @Override + public void dragFrame( JComponent f, int newX, int newY ) { + parent.dragFrame( f, newX, newY ); + } + + @Override + public void endDraggingFrame( JComponent f ) { + parent.endDraggingFrame( f ); + } + + @Override + public void beginResizingFrame( JComponent f, int direction ) { + parent.beginResizingFrame( f, direction ); + } + + @Override + public void resizeFrame( JComponent f, int newX, int newY, int newWidth, int newHeight ) { + parent.resizeFrame( f, newX, newY, newWidth, newHeight ); + } + + @Override + public void endResizingFrame( JComponent f ) { + parent.endResizingFrame( f ); + } + + @Override + public void setBoundsForFrame( JComponent f, int newX, int newY, int newWidth, int newHeight ) { + parent.setBoundsForFrame( f, newX, newY, newWidth, newHeight ); } } } diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.java index c7cefe9d..5ebe5c84 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.java @@ -107,6 +107,12 @@ public class FlatInternalFrameTest frameCount++; } + private void customDesktopManagerChanged() { + desktopPane.setDesktopManager( customDesktopManagerCheckBox.isSelected() + ? new CustomDesktopManager() + : null ); + } + private void initComponents() { // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents desktopPane = new JDesktopPane(); @@ -120,6 +126,8 @@ public class FlatInternalFrameTest titleLabel = new JLabel(); titleField = new JTextField(); createFrameButton = new JButton(); + panel1 = new JPanel(); + customDesktopManagerCheckBox = new JCheckBox(); //======== this ======== setLayout(new MigLayout( @@ -127,7 +135,8 @@ public class FlatInternalFrameTest // columns "[grow,fill]", // rows - "[grow,fill]")); + "[grow,fill]" + + "[]")); //======== desktopPane ======== { @@ -194,6 +203,22 @@ public class FlatInternalFrameTest palette.setBounds(15, 25, 275, 185); } add(desktopPane, "cell 0 0,width 600,height 600"); + + //======== panel1 ======== + { + panel1.setLayout(new MigLayout( + "insets 0,hidemode 3", + // columns + "[fill]", + // rows + "[]")); + + //---- customDesktopManagerCheckBox ---- + customDesktopManagerCheckBox.setText("custom desktop manager"); + customDesktopManagerCheckBox.addActionListener(e -> customDesktopManagerChanged()); + panel1.add(customDesktopManagerCheckBox, "cell 0 0"); + } + add(panel1, "cell 0 1"); // JFormDesigner - End of component initialization //GEN-END:initComponents if( UIScale.getUserScaleFactor() > 1 ) @@ -212,5 +237,37 @@ public class FlatInternalFrameTest private JLabel titleLabel; private JTextField titleField; private JButton createFrameButton; + private JPanel panel1; + private JCheckBox customDesktopManagerCheckBox; // JFormDesigner - End of variables declaration //GEN-END:variables + + //---- class CustomDesktopManager ----------------------------------------- + + private static class CustomDesktopManager + extends DefaultDesktopManager + { + @Override + public void activateFrame( JInternalFrame f ) { + System.out.println( "activateFrame: " + f.getTitle() ); + super.activateFrame( f ); + } + + @Override + public void deactivateFrame( JInternalFrame f ) { + System.out.println( "deactivateFrame: " + f.getTitle() ); + super.deactivateFrame( f ); + } + + @Override + public void iconifyFrame( JInternalFrame f ) { + System.out.println( "iconifyFrame: " + f.getTitle() ); + super.iconifyFrame( f ); + } + + @Override + public void deiconifyFrame( JInternalFrame f ) { + System.out.println( "deiconifyFrame: " + f.getTitle() ); + super.deiconifyFrame( f ); + } + } } diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.jfd index 69f42896..34cb827d 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.jfd @@ -1,4 +1,4 @@ -JFDML JFormDesigner: "7.0.2.0.298" Java: "14" encoding: "UTF-8" +JFDML JFormDesigner: "7.0.3.1.342" Java: "16" encoding: "UTF-8" new FormModel { contentType: "form/swing" @@ -6,7 +6,7 @@ new FormModel { add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { "$layoutConstraints": "insets dialog,hidemode 3" "$columnConstraints": "[grow,fill]" - "$rowConstraints": "[grow,fill]" + "$rowConstraints": "[grow,fill][]" } ) { name: "this" add( new FormContainer( "javax.swing.JDesktopPane", new FormLayoutManager( class javax.swing.JDesktopPane ) ) { @@ -90,6 +90,22 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 0,width 600,height 600" } ) + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { + "$layoutConstraints": "insets 0,hidemode 3" + "$columnConstraints": "[fill]" + "$rowConstraints": "[]" + } ) { + name: "panel1" + add( new FormComponent( "javax.swing.JCheckBox" ) { + name: "customDesktopManagerCheckBox" + "text": "custom desktop manager" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "customDesktopManagerChanged", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 0" + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 1" + } ) }, new FormLayoutConstraints( null ) { "location": new java.awt.Point( 0, 0 ) "size": new java.awt.Dimension( 500, 515 )