Window decorations: made most classes/methods public/protected for extending/subclassing

This commit is contained in:
Karl Tauber
2020-06-29 15:45:26 +02:00
parent e8d5210606
commit a31a8a03c1
4 changed files with 87 additions and 50 deletions

View File

@@ -121,7 +121,7 @@ public class FlatRootPaneUI
} }
} }
private void installClientDecorations() { protected void installClientDecorations() {
boolean isJBRSupported = canUseJBRCustomDecorations && JBRCustomDecorations.isSupported(); boolean isJBRSupported = canUseJBRCustomDecorations && JBRCustomDecorations.isSupported();
// install border // install border
@@ -131,18 +131,18 @@ public class FlatRootPaneUI
LookAndFeel.uninstallBorder( rootPane ); LookAndFeel.uninstallBorder( rootPane );
// install title pane // install title pane
setTitlePane( new FlatTitlePane( rootPane ) ); setTitlePane( createTitlePane() );
// install layout // install layout
oldLayout = rootPane.getLayout(); oldLayout = rootPane.getLayout();
rootPane.setLayout( new FlatRootLayout() ); rootPane.setLayout( createRootLayout() );
// install window resizer // install window resizer
if( !isJBRSupported ) if( !isJBRSupported )
windowResizer = new FlatWindowResizer( rootPane ); windowResizer = createWindowResizer();
} }
private void uninstallClientDecorations() { protected void uninstallClientDecorations() {
LookAndFeel.uninstallBorder( rootPane ); LookAndFeel.uninstallBorder( rootPane );
setTitlePane( null ); setTitlePane( null );
@@ -162,10 +162,22 @@ public class FlatRootPaneUI
} }
} }
// layer title pane under frame content layer to allow placing menu bar over title pane protected FlatRootLayout createRootLayout() {
private final static Integer TITLE_PANE_LAYER = JLayeredPane.FRAME_CONTENT_LAYER - 1; return new FlatRootLayout();
}
private void setTitlePane( FlatTitlePane newTitlePane ) { protected FlatWindowResizer createWindowResizer() {
return new FlatWindowResizer( rootPane );
}
protected FlatTitlePane createTitlePane() {
return new FlatTitlePane( rootPane );
}
// layer title pane under frame content layer to allow placing menu bar over title pane
protected final static Integer TITLE_PANE_LAYER = JLayeredPane.FRAME_CONTENT_LAYER - 1;
protected void setTitlePane( FlatTitlePane newTitlePane ) {
JLayeredPane layeredPane = rootPane.getLayeredPane(); JLayeredPane layeredPane = rootPane.getLayeredPane();
if( titlePane != null ) if( titlePane != null )
@@ -200,7 +212,7 @@ public class FlatRootPaneUI
//---- class FlatRootLayout ----------------------------------------------- //---- class FlatRootLayout -----------------------------------------------
private class FlatRootLayout protected class FlatRootLayout
implements LayoutManager2 implements LayoutManager2
{ {
@Override public void addLayoutComponent( String name, Component comp ) {} @Override public void addLayoutComponent( String name, Component comp ) {}

View File

@@ -87,7 +87,7 @@ import com.formdev.flatlaf.util.UIScale;
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
class FlatTitlePane public class FlatTitlePane
extends JComponent extends JComponent
{ {
private final Color activeBackground = UIManager.getColor( "TitlePane.background" ); private final Color activeBackground = UIManager.getColor( "TitlePane.background" );
@@ -112,13 +112,14 @@ class FlatTitlePane
private JButton restoreButton; private JButton restoreButton;
private JButton closeButton; private JButton closeButton;
private final Handler handler = new Handler(); private final Handler handler;
private Window window; private Window window;
FlatTitlePane( JRootPane rootPane ) { public FlatTitlePane( JRootPane rootPane ) {
this.rootPane = rootPane; this.rootPane = rootPane;
setBorder( new TitlePaneBorder() ); handler = createHandler();
setBorder( createTitlePaneBorder() );
addSubComponents(); addSubComponents();
activeChanged( true ); activeChanged( true );
@@ -130,7 +131,15 @@ class FlatTitlePane
iconLabel.addMouseListener( handler ); iconLabel.addMouseListener( handler );
} }
private void addSubComponents() { protected FlatTitlePaneBorder createTitlePaneBorder() {
return new FlatTitlePaneBorder();
}
protected Handler createHandler() {
return new Handler();
}
protected void addSubComponents() {
leftPanel = new JPanel(); leftPanel = new JPanel();
iconLabel = new JLabel(); iconLabel = new JLabel();
titleLabel = new JLabel(); titleLabel = new JLabel();
@@ -160,7 +169,7 @@ class FlatTitlePane
add( buttonPanel, BorderLayout.LINE_END ); add( buttonPanel, BorderLayout.LINE_END );
} }
private void createButtons() { protected void createButtons() {
iconifyButton = createButton( "TitlePane.iconifyIcon", "Iconify", e -> iconify() ); iconifyButton = createButton( "TitlePane.iconifyIcon", "Iconify", e -> iconify() );
maximizeButton = createButton( "TitlePane.maximizeIcon", "Maximize", e -> maximize() ); maximizeButton = createButton( "TitlePane.maximizeIcon", "Maximize", e -> maximize() );
restoreButton = createButton( "TitlePane.restoreIcon", "Restore", e -> restore() ); restoreButton = createButton( "TitlePane.restoreIcon", "Restore", e -> restore() );
@@ -197,7 +206,7 @@ class FlatTitlePane
buttonPanel.add( closeButton ); buttonPanel.add( closeButton );
} }
private JButton createButton( String iconKey, String accessibleName, ActionListener action ) { protected JButton createButton( String iconKey, String accessibleName, ActionListener action ) {
JButton button = new JButton( UIManager.getIcon( iconKey ) ); JButton button = new JButton( UIManager.getIcon( iconKey ) );
button.setFocusable( false ); button.setFocusable( false );
button.setContentAreaFilled( false ); button.setContentAreaFilled( false );
@@ -207,7 +216,7 @@ class FlatTitlePane
return button; return button;
} }
private void activeChanged( boolean active ) { protected void activeChanged( boolean active ) {
Color background = FlatUIUtils.nonUIResource( active ? activeBackground : inactiveBackground ); Color background = FlatUIUtils.nonUIResource( active ? activeBackground : inactiveBackground );
Color foreground = FlatUIUtils.nonUIResource( active Color foreground = FlatUIUtils.nonUIResource( active
? (rootPane.getJMenuBar() != null && isMenuBarEmbedded() ? embeddedForeground : activeForeground) ? (rootPane.getJMenuBar() != null && isMenuBarEmbedded() ? embeddedForeground : activeForeground)
@@ -223,7 +232,7 @@ class FlatTitlePane
closeButton.setBackground( background ); closeButton.setBackground( background );
} }
private void frameStateChanged() { protected void frameStateChanged() {
if( window == null || rootPane.getWindowDecorationStyle() != JRootPane.FRAME ) if( window == null || rootPane.getWindowDecorationStyle() != JRootPane.FRAME )
return; return;
@@ -246,7 +255,7 @@ class FlatTitlePane
} }
} }
private void updateIcon() { protected void updateIcon() {
// get window images // get window images
List<Image> images = window.getIconImages(); List<Image> images = window.getIconImages();
if( images.isEmpty() ) { if( images.isEmpty() ) {
@@ -306,7 +315,7 @@ class FlatTitlePane
window = null; window = null;
} }
private String getWindowTitle() { protected String getWindowTitle() {
if( window instanceof Frame ) if( window instanceof Frame )
return ((Frame)window).getTitle(); return ((Frame)window).getTitle();
if( window instanceof Dialog ) if( window instanceof Dialog )
@@ -314,7 +323,7 @@ class FlatTitlePane
return null; return null;
} }
private void installWindowListeners() { protected void installWindowListeners() {
if( window == null ) if( window == null )
return; return;
@@ -324,7 +333,7 @@ class FlatTitlePane
window.addComponentListener( handler ); window.addComponentListener( handler );
} }
private void uninstallWindowListeners() { protected void uninstallWindowListeners() {
if( window == null ) if( window == null )
return; return;
@@ -334,14 +343,14 @@ class FlatTitlePane
window.removeComponentListener( handler ); window.removeComponentListener( handler );
} }
boolean isMenuBarEmbedded() { protected boolean isMenuBarEmbedded() {
// not storing value of "TitlePane.menuBarEmbedded" in class to allow changing at runtime // not storing value of "TitlePane.menuBarEmbedded" in class to allow changing at runtime
return UIManager.getBoolean( "TitlePane.menuBarEmbedded" ) && return UIManager.getBoolean( "TitlePane.menuBarEmbedded" ) &&
FlatClientProperties.clientPropertyBoolean( rootPane, FlatClientProperties.MENU_BAR_EMBEDDED, true ) && FlatClientProperties.clientPropertyBoolean( rootPane, FlatClientProperties.MENU_BAR_EMBEDDED, true ) &&
FlatSystemProperties.getBoolean( FlatSystemProperties.MENUBAR_EMBEDDED, true ); FlatSystemProperties.getBoolean( FlatSystemProperties.MENUBAR_EMBEDDED, true );
} }
Rectangle getMenuBarBounds() { protected Rectangle getMenuBarBounds() {
Insets insets = rootPane.getInsets(); Insets insets = rootPane.getInsets();
Rectangle bounds = new Rectangle( Rectangle bounds = new Rectangle(
SwingUtilities.convertPoint( menuBarPlaceholder, -insets.left, -insets.top, rootPane ), SwingUtilities.convertPoint( menuBarPlaceholder, -insets.left, -insets.top, rootPane ),
@@ -355,7 +364,7 @@ class FlatTitlePane
return FlatUIUtils.subtractInsets( bounds, UIScale.scale( getMenuBarMargins() ) ); return FlatUIUtils.subtractInsets( bounds, UIScale.scale( getMenuBarMargins() ) );
} }
void menuBarChanged() { protected void menuBarChanged() {
menuBarPlaceholder.invalidate(); menuBarPlaceholder.invalidate();
// update title foreground color // update title foreground color
@@ -364,7 +373,7 @@ class FlatTitlePane
} ); } );
} }
private Insets getMenuBarMargins() { protected Insets getMenuBarMargins() {
return getComponentOrientation().isLeftToRight() return getComponentOrientation().isLeftToRight()
? menuBarMargins ? menuBarMargins
: new Insets( menuBarMargins.top, menuBarMargins.right, menuBarMargins.bottom, menuBarMargins.left ); : new Insets( menuBarMargins.top, menuBarMargins.right, menuBarMargins.bottom, menuBarMargins.left );
@@ -376,14 +385,20 @@ class FlatTitlePane
g.fillRect( 0, 0, getWidth(), getHeight() ); g.fillRect( 0, 0, getWidth(), getHeight() );
} }
private void iconify() { /**
* Iconifies the window.
*/
protected void iconify() {
if( window instanceof Frame ) { if( window instanceof Frame ) {
Frame frame = (Frame) window; Frame frame = (Frame) window;
frame.setExtendedState( frame.getExtendedState() | Frame.ICONIFIED ); frame.setExtendedState( frame.getExtendedState() | Frame.ICONIFIED );
} }
} }
private void maximize() { /**
* Maximizes the window.
*/
protected void maximize() {
if( !(window instanceof Frame) ) if( !(window instanceof Frame) )
return; return;
@@ -452,7 +467,10 @@ class FlatTitlePane
frame.setExtendedState( frame.getExtendedState() | Frame.MAXIMIZED_BOTH ); frame.setExtendedState( frame.getExtendedState() | Frame.MAXIMIZED_BOTH );
} }
private void restore() { /**
* Restores the window size.
*/
protected void restore() {
if( window instanceof Frame ) { if( window instanceof Frame ) {
Frame frame = (Frame) window; Frame frame = (Frame) window;
int state = frame.getExtendedState(); int state = frame.getExtendedState();
@@ -462,24 +480,27 @@ class FlatTitlePane
} }
} }
private void close() { /**
* Closes the window.
*/
protected void close() {
if( window != null ) if( window != null )
window.dispatchEvent( new WindowEvent( window, WindowEvent.WINDOW_CLOSING ) ); window.dispatchEvent( new WindowEvent( window, WindowEvent.WINDOW_CLOSING ) );
} }
private boolean hasJBRCustomDecoration() { protected boolean hasJBRCustomDecoration() {
return FlatRootPaneUI.canUseJBRCustomDecorations && return FlatRootPaneUI.canUseJBRCustomDecorations &&
window != null && window != null &&
JBRCustomDecorations.hasCustomDecoration( window ); JBRCustomDecorations.hasCustomDecoration( window );
} }
private void updateJBRHitTestSpotsAndTitleBarHeightLater() { protected void updateJBRHitTestSpotsAndTitleBarHeightLater() {
EventQueue.invokeLater( () -> { EventQueue.invokeLater( () -> {
updateJBRHitTestSpotsAndTitleBarHeight(); updateJBRHitTestSpotsAndTitleBarHeight();
} ); } );
} }
private void updateJBRHitTestSpotsAndTitleBarHeight() { protected void updateJBRHitTestSpotsAndTitleBarHeight() {
if( !isDisplayable() ) if( !isDisplayable() )
return; return;
@@ -500,7 +521,7 @@ class FlatTitlePane
JBRCustomDecorations.setHitTestSpotsAndTitleBarHeight( window, hitTestSpots, titleBarHeight ); JBRCustomDecorations.setHitTestSpotsAndTitleBarHeight( window, hitTestSpots, titleBarHeight );
} }
private void addJBRHitTestSpot( JComponent c, boolean subtractMenuBarMargins, List<Rectangle> hitTestSpots ) { protected void addJBRHitTestSpot( JComponent c, boolean subtractMenuBarMargins, List<Rectangle> hitTestSpots ) {
Dimension size = c.getSize(); Dimension size = c.getSize();
if( size.width <= 0 || size.height <= 0 ) if( size.width <= 0 || size.height <= 0 )
return; return;
@@ -516,7 +537,7 @@ class FlatTitlePane
//---- class TitlePaneBorder ---------------------------------------------- //---- class TitlePaneBorder ----------------------------------------------
private class TitlePaneBorder protected class FlatTitlePaneBorder
extends AbstractBorder extends AbstractBorder
{ {
@Override @Override
@@ -547,7 +568,7 @@ class FlatTitlePane
JBRWindowTopBorder.getInstance().paintBorder( c, g, x, y, width, height ); JBRWindowTopBorder.getInstance().paintBorder( c, g, x, y, width, height );
} }
private Border getMenuBarBorder() { protected Border getMenuBarBorder() {
JMenuBar menuBar = rootPane.getJMenuBar(); JMenuBar menuBar = rootPane.getJMenuBar();
return (menuBar != null && isMenuBarEmbedded()) ? menuBar.getBorder() : null; return (menuBar != null && isMenuBarEmbedded()) ? menuBar.getBorder() : null;
} }
@@ -555,7 +576,7 @@ class FlatTitlePane
//---- class Handler ------------------------------------------------------ //---- class Handler ------------------------------------------------------
private class Handler protected class Handler
extends WindowAdapter extends WindowAdapter
implements PropertyChangeListener, MouseListener, MouseMotionListener, ComponentListener implements PropertyChangeListener, MouseListener, MouseMotionListener, ComponentListener
{ {

View File

@@ -28,10 +28,10 @@ import com.formdev.flatlaf.util.ScaledImageIcon;
/** /**
* @author Karl Tauber * @author Karl Tauber
*/ */
class FlatTitlePaneIcon public class FlatTitlePaneIcon
extends ScaledImageIcon extends ScaledImageIcon
{ {
static Icon create( List<Image> images, Dimension size ) { public static Icon create( List<Image> images, Dimension size ) {
// collect all images including multi-resolution variants // collect all images including multi-resolution variants
List<Image> allImages = new ArrayList<>(); List<Image> allImages = new ArrayList<>();
for( Image image : images ) { for( Image image : images ) {
@@ -52,7 +52,7 @@ class FlatTitlePaneIcon
private final List<Image> images; private final List<Image> images;
FlatTitlePaneIcon( List<Image> images, Dimension size ) { private FlatTitlePaneIcon( List<Image> images, Dimension size ) {
super( new ImageIcon( images.get( 0 ) ), size.width, size.height ); super( new ImageIcon( images.get( 0 ) ), size.width, size.height );
this.images = images; this.images = images;
} }

View File

@@ -47,7 +47,7 @@ import com.formdev.flatlaf.util.UIScale;
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
class FlatWindowResizer public class FlatWindowResizer
extends JComponent extends JComponent
implements PropertyChangeListener, WindowStateListener, ComponentListener implements PropertyChangeListener, WindowStateListener, ComponentListener
{ {
@@ -61,14 +61,14 @@ class FlatWindowResizer
private Window window; private Window window;
FlatWindowResizer( JRootPane rootPane ) { public FlatWindowResizer( JRootPane rootPane ) {
this.rootPane = rootPane; this.rootPane = rootPane;
setLayout( new BorderLayout() ); setLayout( new BorderLayout() );
add( new DragBorderComponent( NW_RESIZE_CURSOR, N_RESIZE_CURSOR, NE_RESIZE_CURSOR ), BorderLayout.NORTH ); add( createDragBorderComponent( NW_RESIZE_CURSOR, N_RESIZE_CURSOR, NE_RESIZE_CURSOR ), BorderLayout.NORTH );
add( new DragBorderComponent( SW_RESIZE_CURSOR, S_RESIZE_CURSOR, SE_RESIZE_CURSOR ), BorderLayout.SOUTH ); add( createDragBorderComponent( SW_RESIZE_CURSOR, S_RESIZE_CURSOR, SE_RESIZE_CURSOR ), BorderLayout.SOUTH );
add( new DragBorderComponent( NW_RESIZE_CURSOR, W_RESIZE_CURSOR, SW_RESIZE_CURSOR ), BorderLayout.WEST ); add( createDragBorderComponent( NW_RESIZE_CURSOR, W_RESIZE_CURSOR, SW_RESIZE_CURSOR ), BorderLayout.WEST );
add( new DragBorderComponent( NE_RESIZE_CURSOR, E_RESIZE_CURSOR, SE_RESIZE_CURSOR ), BorderLayout.EAST ); add( createDragBorderComponent( NE_RESIZE_CURSOR, E_RESIZE_CURSOR, SE_RESIZE_CURSOR ), BorderLayout.EAST );
rootPane.addComponentListener( this ); rootPane.addComponentListener( this );
rootPane.getLayeredPane().add( this, WINDOW_RESIZER_LAYER ); rootPane.getLayeredPane().add( this, WINDOW_RESIZER_LAYER );
@@ -77,7 +77,11 @@ class FlatWindowResizer
setBounds( 0, 0, rootPane.getWidth(), rootPane.getHeight() ); setBounds( 0, 0, rootPane.getWidth(), rootPane.getHeight() );
} }
void uninstall() { protected DragBorderComponent createDragBorderComponent( int leadingResizeDir, int centerResizeDir, int trailingResizeDir ) {
return new DragBorderComponent( leadingResizeDir, centerResizeDir, trailingResizeDir );
}
public void uninstall() {
rootPane.removeComponentListener( this ); rootPane.removeComponentListener( this );
rootPane.getLayeredPane().remove( this ); rootPane.getLayeredPane().remove( this );
} }
@@ -157,7 +161,7 @@ class FlatWindowResizer
//---- class DragBorderComponent ------------------------------------------ //---- class DragBorderComponent ------------------------------------------
private class DragBorderComponent protected class DragBorderComponent
extends JComponent extends JComponent
implements MouseListener, MouseMotionListener implements MouseListener, MouseMotionListener
{ {
@@ -170,7 +174,7 @@ class FlatWindowResizer
private int dragStartMouseY; private int dragStartMouseY;
private Rectangle dragStartWindowBounds; private Rectangle dragStartWindowBounds;
DragBorderComponent( int leadingResizeDir, int centerResizeDir, int trailingResizeDir ) { protected DragBorderComponent( int leadingResizeDir, int centerResizeDir, int trailingResizeDir ) {
this.leadingResizeDir = leadingResizeDir; this.leadingResizeDir = leadingResizeDir;
this.centerResizeDir = centerResizeDir; this.centerResizeDir = centerResizeDir;
this.trailingResizeDir = trailingResizeDir; this.trailingResizeDir = trailingResizeDir;
@@ -182,7 +186,7 @@ class FlatWindowResizer
addMouseMotionListener( this ); addMouseMotionListener( this );
} }
private void setResizeDir( int resizeDir ) { protected void setResizeDir( int resizeDir ) {
if( this.resizeDir == resizeDir ) if( this.resizeDir == resizeDir )
return; return;
this.resizeDir = resizeDir; this.resizeDir = resizeDir;