From ab1ce7fab16597c518dd00a4c4e86320d98410c1 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Fri, 9 Apr 2021 18:17:15 +0200 Subject: [PATCH] DesktopPane: avoid using two instances of `DefaultDesktopManager` if a custom desktop manager is used/wrapped (see PR #294) --- CHANGELOG.md | 5 ++ .../formdev/flatlaf/ui/FlatDesktopPaneUI.java | 88 +++++++++++-------- .../testing/FlatInternalFrameTest.java | 59 ++++++++++++- .../flatlaf/testing/FlatInternalFrameTest.jfd | 20 ++++- 4 files changed, 132 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b649dae..127debde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ FlatLaf Change Log - Fixed crash when running in Webswing. (issue #290) +#### Fixed bugs + +- DesktopPane: Fixed empty minimized icon when using a custom desktop manager. + (PR #294) + ## 1.1.1 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 3dcf2856..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 @@ -16,7 +16,10 @@ package com.formdev.flatlaf.ui; -import javax.swing.*; +import javax.swing.DefaultDesktopManager; +import javax.swing.DesktopManager; +import javax.swing.JComponent; +import javax.swing.JInternalFrame; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicDesktopPaneUI; @@ -40,26 +43,35 @@ public class FlatDesktopPaneUI @Override protected void installDesktopManager() { - // 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 old = desktop.getDesktopManager(); - if (old instanceof FlatDesktopManager) return; + // 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; - if( old == null ) { - // default version - desktopManager = new FlatDesktopManager(); + desktopManager = (dm != null) + ? new FlatWrapperDesktopManager( dm ) + : new FlatDesktopManager(); + desktop.setDesktopManager( desktopManager ); + } - } else { - // create the wrapper version of the desktop manager - desktopManager = new FlatWrapperDesktopManager(old); + @Override + protected void uninstallDesktopManager() { + // uninstall wrapper + DesktopManager dm = desktop.getDesktopManager(); + if( dm instanceof FlatWrapperDesktopManager ) + desktop.setDesktopManager( ((FlatWrapperDesktopManager)dm).parent ); - } - desktop.setDesktopManager(desktopManager); + super.uninstallDesktopManager(); + } + private static void updateDockIcon( JInternalFrame f ) { + ((FlatDesktopIconUI)f.getDesktopIcon().getUI()).updateDockIcon(); } //---- class FlatDesktopManager ------------------------------------------- + private class FlatDesktopManager extends DefaultDesktopManager implements UIResource @@ -68,96 +80,98 @@ public class FlatDesktopPaneUI public void iconifyFrame( JInternalFrame f ) { super.iconifyFrame( f ); - ((FlatDesktopIconUI)f.getDesktopIcon().getUI()).updateDockIcon(); + updateDockIcon( f ); } } - //---- class for already installed desktop manager to use the flat desktop manager features + //---- class FlatWrapperDesktopManager ------------------------------------ + + /** + * For already installed desktop manager to use the flat desktop manager features. + */ private class FlatWrapperDesktopManager - extends FlatDesktopManager - + implements DesktopManager { - private DesktopManager parent = null; + private final DesktopManager parent; - private FlatWrapperDesktopManager(DesktopManager parent) { - super(); + private FlatWrapperDesktopManager( DesktopManager parent ) { this.parent = parent; - } @Override - public void openFrame(JInternalFrame f) { + public void openFrame( JInternalFrame f ) { parent.openFrame( f ); } @Override - public void closeFrame(JInternalFrame f) { + public void closeFrame( JInternalFrame f ) { parent.closeFrame( f ); } @Override - public void maximizeFrame(JInternalFrame f) { + public void maximizeFrame( JInternalFrame f ) { parent.maximizeFrame( f ); } @Override - public void minimizeFrame(JInternalFrame f) { + public void minimizeFrame( JInternalFrame f ) { parent.minimizeFrame( f ); } @Override - public void activateFrame(JInternalFrame f) { + public void activateFrame( JInternalFrame f ) { parent.activateFrame( f ); } @Override - public void deactivateFrame(JInternalFrame f) { + public void deactivateFrame( JInternalFrame f ) { parent.deactivateFrame( f ); } @Override public void iconifyFrame( JInternalFrame f ) { - super.iconifyFrame( f ); + parent.iconifyFrame( f ); + updateDockIcon( f ); } @Override public void deiconifyFrame( JInternalFrame f ) { - super.deiconifyFrame( f ); + parent.deiconifyFrame( f ); } @Override - public void beginDraggingFrame(JComponent f) { + public void beginDraggingFrame( JComponent f ) { parent.beginDraggingFrame( f ); } @Override - public void dragFrame(JComponent f, int newX, int newY) { + public void dragFrame( JComponent f, int newX, int newY ) { parent.dragFrame( f, newX, newY ); } @Override - public void endDraggingFrame(JComponent f) { + public void endDraggingFrame( JComponent f ) { parent.endDraggingFrame( f ); } @Override - public void beginResizingFrame(JComponent f, int direction) { + 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) { + 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) { + public void endResizingFrame( JComponent f ) { parent.endResizingFrame( f ); } @Override - public void setBoundsForFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) { + 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 )