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 b2c200dc..bfe1f11a 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,20 +16,16 @@ package com.formdev.flatlaf.ui; +import java.awt.Component; import java.awt.Dimension; +import java.awt.EventQueue; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; -import java.awt.event.ComponentListener; -import java.util.ArrayList; -import java.util.List; -import javax.swing.DefaultDesktopManager; -import javax.swing.DesktopManager; +import java.awt.event.ContainerEvent; +import java.awt.event.ContainerListener; import javax.swing.JComponent; -import javax.swing.JInternalFrame; import javax.swing.JInternalFrame.JDesktopIcon; import javax.swing.plaf.ComponentUI; -import javax.swing.plaf.UIResource; -import javax.swing.plaf.basic.BasicDesktopIconUI; import javax.swing.plaf.basic.BasicDesktopPaneUI; /** @@ -45,79 +41,61 @@ import javax.swing.plaf.basic.BasicDesktopPaneUI; public class FlatDesktopPaneUI extends BasicDesktopPaneUI { - private ComponentListener componentListener; - - // list of iconified internal frames, which define the order of icons in dock - protected List iconifiedFrames; + private LayoutDockListener layoutDockListener; + private boolean layoutDockPending; public static ComponentUI createUI( JComponent c ) { return new FlatDesktopPaneUI(); } @Override - public void uninstallUI( JComponent c ) { - super.uninstallUI( c ); + public void installUI( JComponent c ) { + super.installUI( c ); - iconifiedFrames = null; + layoutDockLaterOnce(); } @Override protected void installListeners() { super.installListeners(); - componentListener = new ComponentAdapter() { - @Override - public void componentResized( ComponentEvent e ) { - layoutDock(); - } - }; - desktop.addComponentListener( componentListener ); + layoutDockListener = new LayoutDockListener(); + desktop.addContainerListener( layoutDockListener ); + desktop.addComponentListener( layoutDockListener ); } @Override protected void uninstallListeners() { super.uninstallListeners(); - desktop.removeComponentListener( componentListener ); - componentListener = null; + desktop.removeContainerListener( layoutDockListener ); + desktop.removeComponentListener( layoutDockListener ); + layoutDockListener = null; } - @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 dm = desktop.getDesktopManager(); - if( dm instanceof FlatDesktopManager || dm instanceof FlatWrapperDesktopManager ) + private void layoutDockLaterOnce() { + if( layoutDockPending ) return; + layoutDockPending = true; - 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(); + EventQueue.invokeLater( () -> { + layoutDockPending = false; + if( desktop != null ) + layoutDock(); + } ); } protected void layoutDock() { - if( iconifiedFrames == null || iconifiedFrames.isEmpty() ) - return; - Dimension desktopSize = desktop.getSize(); int x = 0; int y = desktopSize.height; int rowHeight = 0; - for( JInternalFrame f : iconifiedFrames ) { - JDesktopIcon icon = f.getDesktopIcon(); + for( Component c : desktop.getComponents() ) { + if( !(c instanceof JDesktopIcon) ) + continue; + + JDesktopIcon icon = (JDesktopIcon) c; Dimension iconSize = icon.getPreferredSize(); if( x + iconSize.width > desktopSize.width ) { @@ -134,150 +112,25 @@ public class FlatDesktopPaneUI } } - protected void addToDock( JInternalFrame f ) { - if( iconifiedFrames == null ) - iconifiedFrames = new ArrayList<>(); + //---- class LayoutDockListener ------------------------------------------- - if( !iconifiedFrames.contains( f ) ) - iconifiedFrames.add( f ); - layoutDock(); - } - - protected void removeFromDock( JInternalFrame f ) { - if( iconifiedFrames == null ) - return; - - iconifiedFrames.remove( f ); - layoutDock(); - } - - //---- class FlatDesktopManager ------------------------------------------- - - private class FlatDesktopManager - extends DefaultDesktopManager - implements UIResource + private class LayoutDockListener + extends ComponentAdapter + implements ContainerListener { @Override - public void iconifyFrame( JInternalFrame f ) { - super.iconifyFrame( f ); - addToDock( f ); + public void componentAdded( ContainerEvent e ) { + layoutDockLaterOnce(); } @Override - public void deiconifyFrame( JInternalFrame f ) { - super.deiconifyFrame( f ); - removeFromDock( f ); + public void componentRemoved( ContainerEvent e ) { + layoutDockLaterOnce(); } @Override - public void closeFrame( JInternalFrame f ) { - super.closeFrame( f ); - removeFromDock( f ); - } - } - - //---- class FlatWrapperDesktopManager ------------------------------------ - - /** - * For already installed desktop manager to use the flat desktop manager features. - *

- * Although this class extends {@link DefaultDesktopManager}, it does not invoke - * any method of the superclass. - * All methods are delegated to parent desktop manager. - *

- * This class extends {@link DefaultDesktopManager} - * (instead of implementing {@link DesktopManager}), - * because otherwise {@link DesktopManager#iconifyFrame(JInternalFrame)} - * and {@link DesktopManager#deiconifyFrame(JInternalFrame)} are not invoked - * from {@link BasicDesktopIconUI#installUI(JComponent)} - * and {@link BasicDesktopIconUI#uninstallUI(JComponent)} - * when switching Laf. - */ - private class FlatWrapperDesktopManager - extends DefaultDesktopManager - { - 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 ); - removeFromDock( 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 ); - addToDock( f ); - } - - @Override - public void deiconifyFrame( JInternalFrame f ) { - parent.deiconifyFrame( f ); - removeFromDock( 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 ); + public void componentResized( ComponentEvent e ) { + layoutDockLaterOnce(); } } }