Merge branch 'origin/custom-window-decorations' into master
# Conflicts: # flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.java
@@ -183,6 +183,15 @@ public interface FlatClientProperties
|
||||
*/
|
||||
String PROGRESS_BAR_SQUARE = "JProgressBar.square";
|
||||
|
||||
/**
|
||||
* Specifies whether the menu bar is embedded into the title pane if custom
|
||||
* window decorations are enabled. Default is {@code true}.
|
||||
* <p>
|
||||
* <strong>Component</strong> {@link javax.swing.JRootPane}<br>
|
||||
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||
*/
|
||||
String MENU_BAR_EMBEDDED = "JRootPane.menuBarEmbedded";
|
||||
|
||||
/**
|
||||
* Specifies whether the decrease/increase arrow buttons of a scrollbar are shown.
|
||||
* <p>
|
||||
|
||||
@@ -43,6 +43,8 @@ import javax.swing.BorderFactory;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.PopupFactory;
|
||||
import javax.swing.SwingUtilities;
|
||||
@@ -57,6 +59,7 @@ import javax.swing.plaf.basic.BasicLookAndFeel;
|
||||
import javax.swing.text.StyleContext;
|
||||
import javax.swing.text.html.HTMLEditorKit;
|
||||
import com.formdev.flatlaf.ui.FlatPopupFactory;
|
||||
import com.formdev.flatlaf.ui.JBRCustomDecorations;
|
||||
import com.formdev.flatlaf.util.GrayFilter;
|
||||
import com.formdev.flatlaf.util.MultiResolutionImageSupport;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
@@ -85,6 +88,9 @@ public abstract class FlatLaf
|
||||
|
||||
private Consumer<UIDefaults> postInitialization;
|
||||
|
||||
private Boolean oldFrameWindowDecorated;
|
||||
private Boolean oldDialogWindowDecorated;
|
||||
|
||||
public static boolean install( LookAndFeel newLookAndFeel ) {
|
||||
try {
|
||||
UIManager.setLookAndFeel( newLookAndFeel );
|
||||
@@ -110,6 +116,45 @@ public abstract class FlatLaf
|
||||
|
||||
public abstract boolean isDark();
|
||||
|
||||
/**
|
||||
* Checks whether the current look and feel is dark.
|
||||
*/
|
||||
public static boolean isLafDark() {
|
||||
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
|
||||
return lookAndFeel instanceof FlatLaf && ((FlatLaf)lookAndFeel).isDark();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether FlatLaf supports custom window decorations.
|
||||
* This depends on the operating system and on the used Java runtime.
|
||||
* <p>
|
||||
* To use custom window decorations in your application, enable them with
|
||||
* following code (before creating any frames or dialogs). Then custom window
|
||||
* decorations are only enabled if this method returns {@code true}.
|
||||
* <pre>
|
||||
* JFrame.setDefaultLookAndFeelDecorated( true );
|
||||
* JDialog.setDefaultLookAndFeelDecorated( true );
|
||||
* </pre>
|
||||
* <p>
|
||||
* Returns {@code true} on Windows 10, {@code false} otherwise.
|
||||
* <p>
|
||||
* Return also {@code false} if running on Windows 10 in
|
||||
* <a href="https://confluence.jetbrains.com/display/JBR/JetBrains+Runtime">JetBrains Runtime 11 (or later)</a>
|
||||
* (<a href="https://github.com/JetBrains/JetBrainsRuntime">source code on github</a>)
|
||||
* and JBR supports custom window decorations. In this case, JBR custom decorations
|
||||
* are enabled if {@link JFrame#isDefaultLookAndFeelDecorated()} or
|
||||
* {@link JDialog#isDefaultLookAndFeelDecorated()} return {@code true}.
|
||||
*/
|
||||
@Override
|
||||
public boolean getSupportsWindowDecorations() {
|
||||
if( SystemInfo.IS_JETBRAINS_JVM_11_OR_LATER &&
|
||||
SystemInfo.IS_WINDOWS_10_OR_LATER &&
|
||||
JBRCustomDecorations.isSupported() )
|
||||
return false;
|
||||
|
||||
return SystemInfo.IS_WINDOWS_10_OR_LATER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNativeLookAndFeel() {
|
||||
return false;
|
||||
@@ -200,6 +245,16 @@ public abstract class FlatLaf
|
||||
String.format( "a { color: #%06x; }", linkColor.getRGB() & 0xffffff ) );
|
||||
}
|
||||
};
|
||||
|
||||
// enable/disable window decorations, but only if system property is either
|
||||
// "true" or "false"; in other cases it is not changed
|
||||
Boolean useWindowDecorations = FlatSystemProperties.getBooleanStrict( FlatSystemProperties.USE_WINDOW_DECORATIONS, null );
|
||||
if( useWindowDecorations != null ) {
|
||||
oldFrameWindowDecorated = JFrame.isDefaultLookAndFeelDecorated();
|
||||
oldDialogWindowDecorated = JDialog.isDefaultLookAndFeelDecorated();
|
||||
JFrame.setDefaultLookAndFeelDecorated( useWindowDecorations );
|
||||
JDialog.setDefaultLookAndFeelDecorated( useWindowDecorations );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -232,6 +287,14 @@ public abstract class FlatLaf
|
||||
new HTMLEditorKit().getStyleSheet().addRule( "a { color: blue; }" );
|
||||
postInitialization = null;
|
||||
|
||||
// restore enable/disable window decorations
|
||||
if( oldFrameWindowDecorated != null ) {
|
||||
JFrame.setDefaultLookAndFeelDecorated( oldFrameWindowDecorated );
|
||||
JDialog.setDefaultLookAndFeelDecorated( oldDialogWindowDecorated );
|
||||
oldFrameWindowDecorated = null;
|
||||
oldDialogWindowDecorated = null;
|
||||
}
|
||||
|
||||
super.uninitialize();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
|
||||
/**
|
||||
* Defines/documents own system properties used in FlatLaf.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public interface FlatSystemProperties
|
||||
{
|
||||
/**
|
||||
* Specifies a custom scale factor used to scale the UI.
|
||||
* <p>
|
||||
* If Java runtime scales (Java 9 or later), this scale factor is applied on top
|
||||
* of the Java system scale factor. Java 8 does not scale and this scale factor
|
||||
* replaces the user scale factor that FlatLaf computes based on the font.
|
||||
* To replace the Java 9+ system scale factor, use system property "sun.java2d.uiScale",
|
||||
* which has the same syntax as this one.
|
||||
* <p>
|
||||
* <strong>Allowed Values</strong> e.g. {@code 1.5}, {@code 1.5x}, {@code 150%} or {@code 144dpi} (96dpi is 100%)<br>
|
||||
*/
|
||||
String UI_SCALE = "flatlaf.uiScale";
|
||||
|
||||
/**
|
||||
* Specifies whether Ubuntu font should be used on Ubuntu Linux.
|
||||
* By default, if not running in a JetBrains Runtime, the Liberation Sans font
|
||||
* is used because there are rendering issues (in Java) with Ubuntu fonts.
|
||||
* <p>
|
||||
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||
* <strong>Default</strong> {@code false}
|
||||
*/
|
||||
String USE_UBUNTU_FONT = "flatlaf.useUbuntuFont";
|
||||
|
||||
/**
|
||||
* Specifies whether custom look and feel window decorations should be used
|
||||
* when creating {@code JFrame} or {@code JDialog}.
|
||||
* <p>
|
||||
* If this system property is set, FlatLaf invokes {@link JFrame#setDefaultLookAndFeelDecorated(boolean)}
|
||||
* and {@link JDialog#setDefaultLookAndFeelDecorated(boolean)} on LaF initialization.
|
||||
* <p>
|
||||
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||
* <strong>Default</strong> none
|
||||
*/
|
||||
String USE_WINDOW_DECORATIONS = "flatlaf.useWindowDecorations";
|
||||
|
||||
/**
|
||||
* Specifies whether JetBrains Runtime custom window decorations should be used
|
||||
* when creating {@code JFrame} or {@code JDialog}.
|
||||
* Requires that the application runs in a
|
||||
* <a href="https://confluence.jetbrains.com/display/JBR/JetBrains+Runtime">JetBrains Runtime</a>
|
||||
* (based on OpenJDK).
|
||||
* <p>
|
||||
* Setting this to {@code true} forces using JetBrains Runtime custom window decorations
|
||||
* even if they are not enabled by the application.
|
||||
* <p>
|
||||
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||
* <strong>Default</strong> {@code true}
|
||||
*/
|
||||
String USE_JETBRAINS_CUSTOM_DECORATIONS = "flatlaf.useJetBrainsCustomDecorations";
|
||||
|
||||
/**
|
||||
* Specifies whether menubar is embedded into custom window decorations.
|
||||
* <p>
|
||||
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||
* <strong>Default</strong> {@code true}
|
||||
*/
|
||||
String MENUBAR_EMBEDDED = "flatlaf.menuBarEmbedded";
|
||||
|
||||
/**
|
||||
* Specifies whether vertical text position is corrected when UI is scaled on HiDPI screens.
|
||||
* <p>
|
||||
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||
* <strong>Default</strong> {@code true}
|
||||
*/
|
||||
String USE_TEXT_Y_CORRECTION = "flatlaf.useTextYCorrection";
|
||||
|
||||
/**
|
||||
* Checks whether a system property is set and returns {@code true} if its value
|
||||
* is {@code "true"} (case-insensitive), otherwise it returns {@code false}.
|
||||
* If the system property is not set, {@code defaultValue} is returned.
|
||||
*/
|
||||
static boolean getBoolean( String key, boolean defaultValue ) {
|
||||
String value = System.getProperty( key );
|
||||
return (value != null) ? Boolean.parseBoolean( value ) : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a system property is set and returns {@code Boolean.TRUE} if its value
|
||||
* is {@code "true"} (case-insensitive) or returns {@code Boolean.FALSE} if its value
|
||||
* is {@code "false"} (case-insensitive). Otherwise {@code defaultValue} is returned.
|
||||
*/
|
||||
static Boolean getBooleanStrict( String key, Boolean defaultValue ) {
|
||||
String value = System.getProperty( key );
|
||||
if( "true".equalsIgnoreCase( value ) )
|
||||
return Boolean.TRUE;
|
||||
if( "false".equalsIgnoreCase( value ) )
|
||||
return Boolean.FALSE;
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
@@ -510,6 +510,10 @@ public class IntelliJTheme
|
||||
// Slider
|
||||
uiKeyMapping.put( "Slider.trackWidth", "" ); // ignore (used in Material Theme UI Lite)
|
||||
|
||||
// TitlePane
|
||||
uiKeyMapping.put( "TitlePane.infoForeground", "TitlePane.foreground" );
|
||||
uiKeyMapping.put( "TitlePane.inactiveInfoForeground", "TitlePane.inactiveForeground" );
|
||||
|
||||
for( Map.Entry<String, String> e : uiKeyMapping.entrySet() )
|
||||
uiKeyInverseMapping.put( e.getValue(), e.getKey() );
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ class LinuxFontPolicy
|
||||
// --> use Liberation Sans font
|
||||
if( family.startsWith( "Ubuntu" ) &&
|
||||
!SystemInfo.IS_JETBRAINS_JVM &&
|
||||
!Boolean.parseBoolean( System.getProperty( "flatlaf.useUbuntuFont" ) ) )
|
||||
!FlatSystemProperties.getBoolean( FlatSystemProperties.USE_UBUNTU_FONT, false ) )
|
||||
family = "Liberation Sans";
|
||||
|
||||
// scale font size
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||
|
||||
/**
|
||||
* Base class for window icons.
|
||||
*
|
||||
* @uiDefault TitlePane.buttonSize Dimension
|
||||
* @uiDefault TitlePane.buttonHoverBackground Color
|
||||
* @uiDefault TitlePane.buttonPressedBackground Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public abstract class FlatWindowAbstractIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
private final Color hoverBackground;
|
||||
private final Color pressedBackground;
|
||||
|
||||
public FlatWindowAbstractIcon() {
|
||||
this( UIManager.getDimension( "TitlePane.buttonSize" ),
|
||||
UIManager.getColor( "TitlePane.buttonHoverBackground" ),
|
||||
UIManager.getColor( "TitlePane.buttonPressedBackground" ) );
|
||||
}
|
||||
|
||||
public FlatWindowAbstractIcon( Dimension size, Color hoverBackground, Color pressedBackground ) {
|
||||
super( size.width, size.height, null );
|
||||
this.hoverBackground = hoverBackground;
|
||||
this.pressedBackground = pressedBackground;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
paintBackground( c, g );
|
||||
|
||||
g.setColor( getForeground( c ) );
|
||||
HiDPIUtils.paintAtScale1x( g, 0, 0, width, height, this::paintIconAt1x );
|
||||
}
|
||||
|
||||
protected abstract void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor );
|
||||
|
||||
protected void paintBackground( Component c, Graphics2D g ) {
|
||||
Color background = FlatButtonUI.buttonStateColor( c, null, null, null, hoverBackground, pressedBackground );
|
||||
if( background != null ) {
|
||||
g.setColor( FlatUIUtils.deriveColor( background, c.getBackground() ) );
|
||||
g.fillRect( 0, 0, width, height );
|
||||
}
|
||||
}
|
||||
|
||||
protected Color getForeground( Component c ) {
|
||||
return c.getForeground();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||
|
||||
/**
|
||||
* "close" icon for windows (frames and dialogs).
|
||||
*
|
||||
* @uiDefault TitlePane.closeHoverBackground Color
|
||||
* @uiDefault TitlePane.closePressedBackground Color
|
||||
* @uiDefault TitlePane.closeHoverForeground Color
|
||||
* @uiDefault TitlePane.closePressedForeground Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatWindowCloseIcon
|
||||
extends FlatWindowAbstractIcon
|
||||
{
|
||||
private final Color hoverForeground = UIManager.getColor( "TitlePane.closeHoverForeground" );
|
||||
private final Color pressedForeground = UIManager.getColor( "TitlePane.closePressedForeground" );
|
||||
|
||||
public FlatWindowCloseIcon() {
|
||||
super( UIManager.getDimension( "TitlePane.buttonSize" ),
|
||||
UIManager.getColor( "TitlePane.closeHoverBackground" ),
|
||||
UIManager.getColor( "TitlePane.closePressedBackground" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||
int iwh = (int) (10 * scaleFactor);
|
||||
int ix = x + ((width - iwh) / 2);
|
||||
int iy = y + ((height - iwh) / 2);
|
||||
int ix2 = ix + iwh - 1;
|
||||
int iy2 = iy + iwh - 1;
|
||||
int thickness = (int) scaleFactor;
|
||||
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
path.append( new Line2D.Float( ix, iy, ix2, iy2 ), false );
|
||||
path.append( new Line2D.Float( ix, iy2, ix2, iy ), false );
|
||||
g.setStroke( new BasicStroke( thickness ) );
|
||||
g.draw( path );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Color getForeground( Component c ) {
|
||||
return FlatButtonUI.buttonStateColor( c, c.getForeground(), null, null, hoverForeground, pressedForeground );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
/**
|
||||
* "iconify" icon for windows (frames and dialogs).
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatWindowIconifyIcon
|
||||
extends FlatWindowAbstractIcon
|
||||
{
|
||||
public FlatWindowIconifyIcon() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||
int iw = (int) (10 * scaleFactor);
|
||||
int ih = (int) scaleFactor;
|
||||
int ix = x + ((width - iw) / 2);
|
||||
int iy = y + ((height - ih) / 2);
|
||||
|
||||
g.fillRect( ix, iy, iw, ih );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "maximize" icon for windows (frames and dialogs).
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatWindowMaximizeIcon
|
||||
extends FlatWindowAbstractIcon
|
||||
{
|
||||
public FlatWindowMaximizeIcon() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||
int iwh = (int) (10 * scaleFactor);
|
||||
int ix = x + ((width - iwh) / 2);
|
||||
int iy = y + ((height - iwh) / 2);
|
||||
int thickness = (int) scaleFactor;
|
||||
|
||||
g.fill( FlatUIUtils.createRectangle( ix, iy, iwh, iwh, thickness ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "restore" icon for windows (frames and dialogs).
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatWindowRestoreIcon
|
||||
extends FlatWindowAbstractIcon
|
||||
{
|
||||
public FlatWindowRestoreIcon() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||
int iwh = (int) (10 * scaleFactor);
|
||||
int ix = x + ((width - iwh) / 2);
|
||||
int iy = y + ((height - iwh) / 2);
|
||||
int thickness = (int) scaleFactor;
|
||||
|
||||
int rwh = (int) (8 * scaleFactor);
|
||||
int ro2 = iwh - rwh;
|
||||
|
||||
Path2D r1 = FlatUIUtils.createRectangle( ix + ro2, iy, rwh, rwh, thickness );
|
||||
Path2D r2 = FlatUIUtils.createRectangle( ix, iy + ro2, rwh, rwh, thickness );
|
||||
|
||||
Area area = new Area( r1 );
|
||||
area.subtract( new Area( new Rectangle2D.Float( ix, iy + ro2, rwh, rwh ) ) );
|
||||
g.fill( area );
|
||||
|
||||
g.fill( r2 );
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ public class FlatMenuItemBorder
|
||||
if( c.getParent() instanceof JMenuBar ) {
|
||||
insets.top = scale( menuBarItemMargins.top );
|
||||
insets.left = scale( menuBarItemMargins.left );
|
||||
insets.bottom = scale( menuBarItemMargins.bottom + 1 );
|
||||
insets.bottom = scale( menuBarItemMargins.bottom );
|
||||
insets.right = scale( menuBarItemMargins.right );
|
||||
return insets;
|
||||
} else
|
||||
|
||||
@@ -17,30 +17,84 @@
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.LayoutManager;
|
||||
import java.awt.LayoutManager2;
|
||||
import java.awt.Toolkit;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.util.function.Function;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLayeredPane;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.BorderUIResource;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicRootPaneUI;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JRootPane}.
|
||||
*
|
||||
* <!-- FlatRootPaneUI -->
|
||||
*
|
||||
* @uiDefault RootPane.border Border
|
||||
*
|
||||
* <!-- FlatWindowResizer -->
|
||||
*
|
||||
* @uiDefault RootPane.borderDragThickness int
|
||||
* @uiDefault RootPane.cornerDragWidth int
|
||||
* @uiDefault RootPane.honorMinimumSizeOnResize boolean
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatRootPaneUI
|
||||
extends BasicRootPaneUI
|
||||
{
|
||||
private static ComponentUI instance;
|
||||
// check this field before using class JBRCustomDecorations to avoid unnecessary loading of that class
|
||||
static final boolean canUseJBRCustomDecorations
|
||||
= SystemInfo.IS_JETBRAINS_JVM_11_OR_LATER && SystemInfo.IS_WINDOWS_10_OR_LATER;
|
||||
|
||||
private JRootPane rootPane;
|
||||
private FlatTitlePane titlePane;
|
||||
private LayoutManager oldLayout;
|
||||
private FlatWindowResizer windowResizer;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
if( instance == null )
|
||||
instance = new FlatRootPaneUI();
|
||||
return instance;
|
||||
return new FlatRootPaneUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installUI( JComponent c ) {
|
||||
super.installUI( c );
|
||||
|
||||
rootPane = (JRootPane) c;
|
||||
|
||||
if( rootPane.getWindowDecorationStyle() != JRootPane.NONE )
|
||||
installClientDecorations();
|
||||
|
||||
if( canUseJBRCustomDecorations )
|
||||
JBRCustomDecorations.install( rootPane );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninstallUI( JComponent c ) {
|
||||
super.uninstallUI( c );
|
||||
|
||||
uninstallClientDecorations();
|
||||
rootPane = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,5 +112,235 @@ public class FlatRootPaneUI
|
||||
if( background == null || background instanceof UIResource )
|
||||
parent.setBackground( UIManager.getColor( "control" ) );
|
||||
}
|
||||
|
||||
// enable dark window appearance on macOS when running in JetBrains Runtime
|
||||
if( SystemInfo.IS_JETBRAINS_JVM && SystemInfo.IS_MAC_OS_10_14_MOJAVE ) {
|
||||
LookAndFeel laf = UIManager.getLookAndFeel();
|
||||
boolean isDark = laf instanceof FlatLaf && ((FlatLaf)laf).isDark();
|
||||
c.putClientProperty( "jetbrains.awt.windowDarkAppearance", isDark );
|
||||
}
|
||||
}
|
||||
|
||||
protected void installClientDecorations() {
|
||||
boolean isJBRSupported = canUseJBRCustomDecorations && JBRCustomDecorations.isSupported();
|
||||
|
||||
// install border
|
||||
if( rootPane.getWindowDecorationStyle() != JRootPane.NONE && !isJBRSupported )
|
||||
LookAndFeel.installBorder( rootPane, "RootPane.border" );
|
||||
else
|
||||
LookAndFeel.uninstallBorder( rootPane );
|
||||
|
||||
// install title pane
|
||||
setTitlePane( createTitlePane() );
|
||||
|
||||
// install layout
|
||||
oldLayout = rootPane.getLayout();
|
||||
rootPane.setLayout( createRootLayout() );
|
||||
|
||||
// install window resizer
|
||||
if( !isJBRSupported )
|
||||
windowResizer = createWindowResizer();
|
||||
}
|
||||
|
||||
protected void uninstallClientDecorations() {
|
||||
LookAndFeel.uninstallBorder( rootPane );
|
||||
setTitlePane( null );
|
||||
|
||||
if( windowResizer != null ) {
|
||||
windowResizer.uninstall();
|
||||
windowResizer = null;
|
||||
}
|
||||
|
||||
if( oldLayout != null ) {
|
||||
rootPane.setLayout( oldLayout );
|
||||
oldLayout = null;
|
||||
}
|
||||
|
||||
if( rootPane.getWindowDecorationStyle() == JRootPane.NONE ) {
|
||||
rootPane.revalidate();
|
||||
rootPane.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
protected FlatRootLayout createRootLayout() {
|
||||
return new FlatRootLayout();
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
if( titlePane != null )
|
||||
layeredPane.remove( titlePane );
|
||||
|
||||
if( newTitlePane != null )
|
||||
layeredPane.add( newTitlePane, TITLE_PANE_LAYER );
|
||||
|
||||
titlePane = newTitlePane;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange( PropertyChangeEvent e ) {
|
||||
super.propertyChange( e );
|
||||
|
||||
switch( e.getPropertyName() ) {
|
||||
case "windowDecorationStyle":
|
||||
uninstallClientDecorations();
|
||||
if( rootPane.getWindowDecorationStyle() != JRootPane.NONE )
|
||||
installClientDecorations();
|
||||
break;
|
||||
|
||||
case FlatClientProperties.MENU_BAR_EMBEDDED:
|
||||
if( titlePane != null ) {
|
||||
titlePane.menuBarChanged();
|
||||
rootPane.revalidate();
|
||||
rootPane.repaint();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//---- class FlatRootLayout -----------------------------------------------
|
||||
|
||||
protected class FlatRootLayout
|
||||
implements LayoutManager2
|
||||
{
|
||||
@Override public void addLayoutComponent( String name, Component comp ) {}
|
||||
@Override public void addLayoutComponent( Component comp, Object constraints ) {}
|
||||
@Override public void removeLayoutComponent( Component comp ) {}
|
||||
|
||||
@Override
|
||||
public Dimension preferredLayoutSize( Container parent ) {
|
||||
return computeLayoutSize( parent, c -> c.getPreferredSize() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension minimumLayoutSize( Container parent ) {
|
||||
return computeLayoutSize( parent, c -> c.getMinimumSize() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension maximumLayoutSize( Container parent ) {
|
||||
return new Dimension( Integer.MAX_VALUE, Integer.MAX_VALUE );
|
||||
}
|
||||
|
||||
private Dimension computeLayoutSize( Container parent, Function<Component, Dimension> getSizeFunc ) {
|
||||
JRootPane rootPane = (JRootPane) parent;
|
||||
|
||||
Dimension titlePaneSize = (titlePane != null)
|
||||
? getSizeFunc.apply( titlePane )
|
||||
: new Dimension();
|
||||
Dimension contentSize = (rootPane.getContentPane() != null)
|
||||
? getSizeFunc.apply( rootPane.getContentPane() )
|
||||
: rootPane.getSize();
|
||||
|
||||
int width = Math.max( titlePaneSize.width, contentSize.width );
|
||||
int height = titlePaneSize.height + contentSize.height;
|
||||
if( titlePane == null || !titlePane.isMenuBarEmbedded() ) {
|
||||
Dimension menuBarSize = (rootPane.getJMenuBar() != null)
|
||||
? getSizeFunc.apply( rootPane.getJMenuBar() )
|
||||
: new Dimension();
|
||||
|
||||
width = Math.max( width, menuBarSize.width );
|
||||
height += menuBarSize.height;
|
||||
}
|
||||
|
||||
Insets insets = rootPane.getInsets();
|
||||
|
||||
return new Dimension(
|
||||
width + insets.left + insets.right,
|
||||
height + insets.top + insets.bottom );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutContainer( Container parent ) {
|
||||
JRootPane rootPane = (JRootPane) parent;
|
||||
|
||||
Insets insets = rootPane.getInsets();
|
||||
int x = insets.left;
|
||||
int y = insets.top;
|
||||
int width = rootPane.getWidth() - insets.left - insets.right;
|
||||
int height = rootPane.getHeight() - insets.top - insets.bottom;
|
||||
|
||||
if( rootPane.getLayeredPane() != null )
|
||||
rootPane.getLayeredPane().setBounds( x, y, width, height );
|
||||
if( rootPane.getGlassPane() != null )
|
||||
rootPane.getGlassPane().setBounds( x, y, width, height );
|
||||
|
||||
int nextY = 0;
|
||||
if( titlePane != null ) {
|
||||
Dimension prefSize = titlePane.getPreferredSize();
|
||||
titlePane.setBounds( 0, 0, width, prefSize.height );
|
||||
nextY += prefSize.height;
|
||||
}
|
||||
|
||||
JMenuBar menuBar = rootPane.getJMenuBar();
|
||||
if( menuBar != null ) {
|
||||
if( titlePane != null && titlePane.isMenuBarEmbedded() ) {
|
||||
titlePane.validate();
|
||||
menuBar.setBounds( titlePane.getMenuBarBounds() );
|
||||
} else {
|
||||
Dimension prefSize = menuBar.getPreferredSize();
|
||||
menuBar.setBounds( 0, nextY, width, prefSize.height );
|
||||
nextY += prefSize.height;
|
||||
}
|
||||
}
|
||||
|
||||
Container contentPane = rootPane.getContentPane();
|
||||
if( contentPane != null )
|
||||
contentPane.setBounds( 0, nextY, width, Math.max( height - nextY, 0 ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateLayout( Container parent ) {
|
||||
if( titlePane != null )
|
||||
titlePane.menuBarChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getLayoutAlignmentX( Container target ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getLayoutAlignmentY( Container target ) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//---- class FlatWindowBorder ---------------------------------------------
|
||||
|
||||
public static class FlatWindowBorder
|
||||
extends BorderUIResource.EmptyBorderUIResource
|
||||
{
|
||||
public FlatWindowBorder() {
|
||||
super( 1, 1, 1, 1 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||
Object borderColorObj = Toolkit.getDefaultToolkit().getDesktopProperty(
|
||||
"win.frame.activeBorderColor" );
|
||||
Color borderColor = (borderColorObj instanceof Color)
|
||||
? (Color) borderColorObj
|
||||
: UIManager.getColor( "windowBorder" );
|
||||
|
||||
g.setColor( borderColor );
|
||||
HiDPIUtils.paintAtScale1x( (Graphics2D) g, x, y, width, height, this::paintImpl );
|
||||
}
|
||||
|
||||
private void paintImpl( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||
g.drawRect( x, y, width - 1, height - 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,727 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Image;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import javax.accessibility.AccessibleContext;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.AbstractBorder;
|
||||
import javax.swing.border.Border;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.FlatSystemProperties;
|
||||
import com.formdev.flatlaf.ui.JBRCustomDecorations.JBRWindowTopBorder;
|
||||
import com.formdev.flatlaf.util.ScaledImageIcon;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF title bar.
|
||||
*
|
||||
* @uiDefault TitlePane.background Color
|
||||
* @uiDefault TitlePane.inactiveBackground Color
|
||||
* @uiDefault TitlePane.foreground Color
|
||||
* @uiDefault TitlePane.inactiveForeground Color
|
||||
* @uiDefault TitlePane.embeddedForeground Color
|
||||
* @uiDefault TitlePane.iconSize Dimension
|
||||
* @uiDefault TitlePane.iconMargins Insets
|
||||
* @uiDefault TitlePane.titleMargins Insets
|
||||
* @uiDefault TitlePane.menuBarMargins Insets
|
||||
* @uiDefault TitlePane.menuBarEmbedded boolean
|
||||
* @uiDefault TitlePane.buttonMaximizedHeight int
|
||||
* @uiDefault TitlePane.closeIcon Icon
|
||||
* @uiDefault TitlePane.iconifyIcon Icon
|
||||
* @uiDefault TitlePane.maximizeIcon Icon
|
||||
* @uiDefault TitlePane.restoreIcon Icon
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatTitlePane
|
||||
extends JComponent
|
||||
{
|
||||
private final Color activeBackground = UIManager.getColor( "TitlePane.background" );
|
||||
private final Color inactiveBackground = UIManager.getColor( "TitlePane.inactiveBackground" );
|
||||
private final Color activeForeground = UIManager.getColor( "TitlePane.foreground" );
|
||||
private final Color inactiveForeground = UIManager.getColor( "TitlePane.inactiveForeground" );
|
||||
private final Color embeddedForeground = UIManager.getColor( "TitlePane.embeddedForeground" );
|
||||
|
||||
private final Insets menuBarMargins = UIManager.getInsets( "TitlePane.menuBarMargins" );
|
||||
private final Dimension iconSize = UIManager.getDimension( "TitlePane.iconSize" );
|
||||
private final int buttonMaximizedHeight = UIManager.getInt( "TitlePane.buttonMaximizedHeight" );
|
||||
|
||||
private final JRootPane rootPane;
|
||||
|
||||
private JPanel leftPanel;
|
||||
private JLabel iconLabel;
|
||||
private JComponent menuBarPlaceholder;
|
||||
private JLabel titleLabel;
|
||||
private JPanel buttonPanel;
|
||||
private JButton iconifyButton;
|
||||
private JButton maximizeButton;
|
||||
private JButton restoreButton;
|
||||
private JButton closeButton;
|
||||
|
||||
private final Handler handler;
|
||||
private Window window;
|
||||
|
||||
public FlatTitlePane( JRootPane rootPane ) {
|
||||
this.rootPane = rootPane;
|
||||
|
||||
handler = createHandler();
|
||||
setBorder( createTitlePaneBorder() );
|
||||
|
||||
addSubComponents();
|
||||
activeChanged( true );
|
||||
|
||||
addMouseListener( handler );
|
||||
addMouseMotionListener( handler );
|
||||
|
||||
// necessary for closing window with double-click on icon
|
||||
iconLabel.addMouseListener( handler );
|
||||
}
|
||||
|
||||
protected FlatTitlePaneBorder createTitlePaneBorder() {
|
||||
return new FlatTitlePaneBorder();
|
||||
}
|
||||
|
||||
protected Handler createHandler() {
|
||||
return new Handler();
|
||||
}
|
||||
|
||||
protected void addSubComponents() {
|
||||
leftPanel = new JPanel();
|
||||
iconLabel = new JLabel();
|
||||
titleLabel = new JLabel();
|
||||
iconLabel.setBorder( new FlatEmptyBorder( UIManager.getInsets( "TitlePane.iconMargins" ) ) );
|
||||
titleLabel.setBorder( new FlatEmptyBorder( UIManager.getInsets( "TitlePane.titleMargins" ) ) );
|
||||
|
||||
leftPanel.setLayout( new BoxLayout( leftPanel, BoxLayout.LINE_AXIS ) );
|
||||
leftPanel.setOpaque( false );
|
||||
leftPanel.add( iconLabel );
|
||||
|
||||
menuBarPlaceholder = new JComponent() {
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
JMenuBar menuBar = rootPane.getJMenuBar();
|
||||
return (menuBar != null && isMenuBarEmbedded())
|
||||
? FlatUIUtils.addInsets( menuBar.getPreferredSize(), UIScale.scale( menuBarMargins ) )
|
||||
: new Dimension();
|
||||
}
|
||||
};
|
||||
leftPanel.add( menuBarPlaceholder );
|
||||
|
||||
createButtons();
|
||||
|
||||
setLayout( new BorderLayout() );
|
||||
add( leftPanel, BorderLayout.LINE_START );
|
||||
add( titleLabel, BorderLayout.CENTER );
|
||||
add( buttonPanel, BorderLayout.LINE_END );
|
||||
}
|
||||
|
||||
protected void createButtons() {
|
||||
iconifyButton = createButton( "TitlePane.iconifyIcon", "Iconify", e -> iconify() );
|
||||
maximizeButton = createButton( "TitlePane.maximizeIcon", "Maximize", e -> maximize() );
|
||||
restoreButton = createButton( "TitlePane.restoreIcon", "Restore", e -> restore() );
|
||||
closeButton = createButton( "TitlePane.closeIcon", "Close", e -> close() );
|
||||
|
||||
buttonPanel = new JPanel() {
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
Dimension size = super.getPreferredSize();
|
||||
if( buttonMaximizedHeight > 0 &&
|
||||
window instanceof Frame &&
|
||||
(((Frame)window).getExtendedState() & Frame.MAXIMIZED_BOTH) != 0 )
|
||||
{
|
||||
// make title pane height smaller when frame is maximized
|
||||
size = new Dimension( size.width, Math.min( size.height, UIScale.scale( buttonMaximizedHeight ) ) );
|
||||
}
|
||||
return size;
|
||||
}
|
||||
};
|
||||
buttonPanel.setOpaque( false );
|
||||
buttonPanel.setLayout( new BoxLayout( buttonPanel, BoxLayout.LINE_AXIS ) );
|
||||
if( rootPane.getWindowDecorationStyle() == JRootPane.FRAME ) {
|
||||
// JRootPane.FRAME works only for frames (and not for dialogs)
|
||||
// but at this time the owner window type is unknown (not yet added)
|
||||
// so we add the iconify/maximize/restore buttons and they are hidden
|
||||
// later in frameStateChanged(), which is invoked from addNotify()
|
||||
|
||||
restoreButton.setVisible( false );
|
||||
|
||||
buttonPanel.add( iconifyButton );
|
||||
buttonPanel.add( maximizeButton );
|
||||
buttonPanel.add( restoreButton );
|
||||
}
|
||||
buttonPanel.add( closeButton );
|
||||
}
|
||||
|
||||
protected JButton createButton( String iconKey, String accessibleName, ActionListener action ) {
|
||||
JButton button = new JButton( UIManager.getIcon( iconKey ) );
|
||||
button.setFocusable( false );
|
||||
button.setContentAreaFilled( false );
|
||||
button.setBorder( BorderFactory.createEmptyBorder() );
|
||||
button.putClientProperty( AccessibleContext.ACCESSIBLE_NAME_PROPERTY, accessibleName );
|
||||
button.addActionListener( action );
|
||||
return button;
|
||||
}
|
||||
|
||||
protected void activeChanged( boolean active ) {
|
||||
Color background = FlatUIUtils.nonUIResource( active ? activeBackground : inactiveBackground );
|
||||
Color foreground = FlatUIUtils.nonUIResource( active
|
||||
? (rootPane.getJMenuBar() != null && isMenuBarEmbedded() ? embeddedForeground : activeForeground)
|
||||
: inactiveForeground );
|
||||
|
||||
setBackground( background );
|
||||
titleLabel.setForeground( foreground );
|
||||
|
||||
// this is necessary because hover/pressed colors are derived from background color
|
||||
iconifyButton.setBackground( background );
|
||||
maximizeButton.setBackground( background );
|
||||
restoreButton.setBackground( background );
|
||||
closeButton.setBackground( background );
|
||||
}
|
||||
|
||||
protected void frameStateChanged() {
|
||||
if( window == null || rootPane.getWindowDecorationStyle() != JRootPane.FRAME )
|
||||
return;
|
||||
|
||||
if( window instanceof Frame ) {
|
||||
Frame frame = (Frame) window;
|
||||
boolean resizable = frame.isResizable();
|
||||
boolean maximized = ((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0);
|
||||
|
||||
iconifyButton.setVisible( true );
|
||||
maximizeButton.setVisible( resizable && !maximized );
|
||||
restoreButton.setVisible( resizable && maximized );
|
||||
} else {
|
||||
// hide buttons because they are only supported in frames
|
||||
iconifyButton.setVisible( false );
|
||||
maximizeButton.setVisible( false );
|
||||
restoreButton.setVisible( false );
|
||||
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateIcon() {
|
||||
// get window images
|
||||
List<Image> images = window.getIconImages();
|
||||
if( images.isEmpty() ) {
|
||||
// search in owners
|
||||
for( Window owner = window.getOwner(); owner != null; owner = owner.getOwner() ) {
|
||||
images = owner.getIconImages();
|
||||
if( !images.isEmpty() )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasIcon = true;
|
||||
|
||||
// set icon
|
||||
if( !images.isEmpty() )
|
||||
iconLabel.setIcon( FlatTitlePaneIcon.create( images, iconSize ) );
|
||||
else {
|
||||
// no icon set on window --> use default icon
|
||||
Icon defaultIcon = UIManager.getIcon( "InternalFrame.icon" );
|
||||
if( defaultIcon != null ) {
|
||||
if( defaultIcon instanceof ImageIcon )
|
||||
defaultIcon = new ScaledImageIcon( (ImageIcon) defaultIcon, iconSize.width, iconSize.height );
|
||||
iconLabel.setIcon( defaultIcon );
|
||||
} else
|
||||
hasIcon = false;
|
||||
}
|
||||
|
||||
// show/hide icon
|
||||
iconLabel.setVisible( hasIcon );
|
||||
|
||||
updateJBRHitTestSpotsAndTitleBarHeightLater();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNotify() {
|
||||
super.addNotify();
|
||||
|
||||
uninstallWindowListeners();
|
||||
|
||||
window = SwingUtilities.getWindowAncestor( this );
|
||||
if( window != null ) {
|
||||
frameStateChanged();
|
||||
activeChanged( window.isActive() );
|
||||
updateIcon();
|
||||
titleLabel.setText( getWindowTitle() );
|
||||
installWindowListeners();
|
||||
}
|
||||
|
||||
updateJBRHitTestSpotsAndTitleBarHeightLater();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNotify() {
|
||||
super.removeNotify();
|
||||
|
||||
uninstallWindowListeners();
|
||||
window = null;
|
||||
}
|
||||
|
||||
protected String getWindowTitle() {
|
||||
if( window instanceof Frame )
|
||||
return ((Frame)window).getTitle();
|
||||
if( window instanceof Dialog )
|
||||
return ((Dialog)window).getTitle();
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void installWindowListeners() {
|
||||
if( window == null )
|
||||
return;
|
||||
|
||||
window.addPropertyChangeListener( handler );
|
||||
window.addWindowListener( handler );
|
||||
window.addWindowStateListener( handler );
|
||||
window.addComponentListener( handler );
|
||||
}
|
||||
|
||||
protected void uninstallWindowListeners() {
|
||||
if( window == null )
|
||||
return;
|
||||
|
||||
window.removePropertyChangeListener( handler );
|
||||
window.removeWindowListener( handler );
|
||||
window.removeWindowStateListener( handler );
|
||||
window.removeComponentListener( handler );
|
||||
}
|
||||
|
||||
protected boolean isMenuBarEmbedded() {
|
||||
// not storing value of "TitlePane.menuBarEmbedded" in class to allow changing at runtime
|
||||
return UIManager.getBoolean( "TitlePane.menuBarEmbedded" ) &&
|
||||
FlatClientProperties.clientPropertyBoolean( rootPane, FlatClientProperties.MENU_BAR_EMBEDDED, true ) &&
|
||||
FlatSystemProperties.getBoolean( FlatSystemProperties.MENUBAR_EMBEDDED, true );
|
||||
}
|
||||
|
||||
protected Rectangle getMenuBarBounds() {
|
||||
Insets insets = rootPane.getInsets();
|
||||
Rectangle bounds = new Rectangle(
|
||||
SwingUtilities.convertPoint( menuBarPlaceholder, -insets.left, -insets.top, rootPane ),
|
||||
menuBarPlaceholder.getSize() );
|
||||
|
||||
// add menu bar bottom border insets to bounds so that menu bar overlaps
|
||||
// title pane border (menu bar border is painted over title pane border)
|
||||
Insets borderInsets = getBorder().getBorderInsets( this );
|
||||
bounds.height += borderInsets.bottom;
|
||||
|
||||
return FlatUIUtils.subtractInsets( bounds, UIScale.scale( getMenuBarMargins() ) );
|
||||
}
|
||||
|
||||
protected void menuBarChanged() {
|
||||
menuBarPlaceholder.invalidate();
|
||||
|
||||
// update title foreground color
|
||||
EventQueue.invokeLater( () -> {
|
||||
activeChanged( window == null || window.isActive() );
|
||||
} );
|
||||
}
|
||||
|
||||
protected Insets getMenuBarMargins() {
|
||||
return getComponentOrientation().isLeftToRight()
|
||||
? menuBarMargins
|
||||
: new Insets( menuBarMargins.top, menuBarMargins.right, menuBarMargins.bottom, menuBarMargins.left );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent( Graphics g ) {
|
||||
g.setColor( getBackground() );
|
||||
g.fillRect( 0, 0, getWidth(), getHeight() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Iconifies the window.
|
||||
*/
|
||||
protected void iconify() {
|
||||
if( window instanceof Frame ) {
|
||||
Frame frame = (Frame) window;
|
||||
frame.setExtendedState( frame.getExtendedState() | Frame.ICONIFIED );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximizes the window.
|
||||
*/
|
||||
protected void maximize() {
|
||||
if( !(window instanceof Frame) )
|
||||
return;
|
||||
|
||||
Frame frame = (Frame) window;
|
||||
|
||||
// set maximized bounds to avoid that maximized window overlaps Windows task bar
|
||||
// (if not running in JBR and if not modified from the application)
|
||||
if( !hasJBRCustomDecoration() &&
|
||||
(frame.getMaximizedBounds() == null ||
|
||||
Objects.equals( frame.getMaximizedBounds(), rootPane.getClientProperty( "_flatlaf.maximizedBounds" ) )) )
|
||||
{
|
||||
GraphicsConfiguration gc = window.getGraphicsConfiguration();
|
||||
|
||||
// Screen bounds, which may be smaller than physical size on Java 9+.
|
||||
// E.g. if running a 3840x2160 screen at 200%, screenBounds.size is 1920x1080.
|
||||
// In Java 9+, each screen can have its own scale factor.
|
||||
//
|
||||
// On Java 8, which does not scale, screenBounds.size of the primary screen
|
||||
// is identical to its physical size. But when the primary screen is scaled,
|
||||
// then screenBounds.size of secondary screens is scaled with the scale factor
|
||||
// of the primary screen.
|
||||
// E.g. primary 3840x2160 screen at 150%, secondary 1920x1080 screen at 100%,
|
||||
// then screenBounds.size is 3840x2160 on primary and 2880x1560 on secondary.
|
||||
Rectangle screenBounds = gc.getBounds();
|
||||
|
||||
int maximizedX = screenBounds.x;
|
||||
int maximizedY = screenBounds.y;
|
||||
int maximizedWidth = screenBounds.width;
|
||||
int maximizedHeight = screenBounds.height;
|
||||
|
||||
if( !SystemInfo.IS_JAVA_15_OR_LATER ) {
|
||||
// on Java 8 to 14, maximized x,y are 0,0 based on all screens in a multi-screen environment
|
||||
maximizedX = 0;
|
||||
maximizedY = 0;
|
||||
|
||||
// scale maximized screen size to get physical screen size for Java 9 to 14
|
||||
AffineTransform defaultTransform = gc.getDefaultTransform();
|
||||
maximizedWidth = (int) (maximizedWidth * defaultTransform.getScaleX());
|
||||
maximizedHeight = (int) (maximizedHeight * defaultTransform.getScaleY());
|
||||
}
|
||||
|
||||
// screen insets are in physical size, except for Java 15+
|
||||
// (see https://bugs.openjdk.java.net/browse/JDK-8243925)
|
||||
// and except for Java 8 on secondary screens where primary screen is scaled
|
||||
Insets screenInsets = window.getToolkit().getScreenInsets( gc );
|
||||
|
||||
// maximized bounds are required in physical size, except for Java 15+
|
||||
// (see https://bugs.openjdk.java.net/browse/JDK-8231564 and
|
||||
// https://bugs.openjdk.java.net/browse/JDK-8176359)
|
||||
// and except for Java 8 on secondary screens where primary screen is scaled
|
||||
Rectangle maximizedBounds = new Rectangle(
|
||||
maximizedX + screenInsets.left,
|
||||
maximizedY + screenInsets.top,
|
||||
maximizedWidth - screenInsets.left - screenInsets.right,
|
||||
maximizedHeight - screenInsets.top - screenInsets.bottom );
|
||||
|
||||
// change maximized bounds
|
||||
frame.setMaximizedBounds( maximizedBounds );
|
||||
|
||||
// remember maximized bounds in client property to be able to detect
|
||||
// whether maximized bounds are modified from the application
|
||||
rootPane.putClientProperty( "_flatlaf.maximizedBounds", maximizedBounds );
|
||||
}
|
||||
|
||||
// maximize window
|
||||
frame.setExtendedState( frame.getExtendedState() | Frame.MAXIMIZED_BOTH );
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the window size.
|
||||
*/
|
||||
protected void restore() {
|
||||
if( window instanceof Frame ) {
|
||||
Frame frame = (Frame) window;
|
||||
int state = frame.getExtendedState();
|
||||
frame.setExtendedState( ((state & Frame.ICONIFIED) != 0)
|
||||
? (state & ~Frame.ICONIFIED)
|
||||
: (state & ~Frame.MAXIMIZED_BOTH) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the window.
|
||||
*/
|
||||
protected void close() {
|
||||
if( window != null )
|
||||
window.dispatchEvent( new WindowEvent( window, WindowEvent.WINDOW_CLOSING ) );
|
||||
}
|
||||
|
||||
protected boolean hasJBRCustomDecoration() {
|
||||
return FlatRootPaneUI.canUseJBRCustomDecorations &&
|
||||
window != null &&
|
||||
JBRCustomDecorations.hasCustomDecoration( window );
|
||||
}
|
||||
|
||||
protected void updateJBRHitTestSpotsAndTitleBarHeightLater() {
|
||||
EventQueue.invokeLater( () -> {
|
||||
updateJBRHitTestSpotsAndTitleBarHeight();
|
||||
} );
|
||||
}
|
||||
|
||||
protected void updateJBRHitTestSpotsAndTitleBarHeight() {
|
||||
if( !isDisplayable() )
|
||||
return;
|
||||
|
||||
if( !hasJBRCustomDecoration() )
|
||||
return;
|
||||
|
||||
List<Rectangle> hitTestSpots = new ArrayList<>();
|
||||
if( iconLabel.isVisible() )
|
||||
addJBRHitTestSpot( iconLabel, false, hitTestSpots );
|
||||
addJBRHitTestSpot( buttonPanel, false, hitTestSpots );
|
||||
addJBRHitTestSpot( menuBarPlaceholder, true, hitTestSpots );
|
||||
|
||||
int titleBarHeight = getHeight();
|
||||
// slightly reduce height so that component receives mouseExit events
|
||||
if( titleBarHeight > 0 )
|
||||
titleBarHeight--;
|
||||
|
||||
JBRCustomDecorations.setHitTestSpotsAndTitleBarHeight( window, hitTestSpots, titleBarHeight );
|
||||
}
|
||||
|
||||
protected void addJBRHitTestSpot( JComponent c, boolean subtractMenuBarMargins, List<Rectangle> hitTestSpots ) {
|
||||
Dimension size = c.getSize();
|
||||
if( size.width <= 0 || size.height <= 0 )
|
||||
return;
|
||||
|
||||
Point location = SwingUtilities.convertPoint( c, 0, 0, window );
|
||||
Rectangle r = new Rectangle( location, size );
|
||||
if( subtractMenuBarMargins )
|
||||
r = FlatUIUtils.subtractInsets( r, UIScale.scale( getMenuBarMargins() ) );
|
||||
// slightly increase rectangle so that component receives mouseExit events
|
||||
r.grow( 2, 2 );
|
||||
hitTestSpots.add( r );
|
||||
}
|
||||
|
||||
//---- class TitlePaneBorder ----------------------------------------------
|
||||
|
||||
protected class FlatTitlePaneBorder
|
||||
extends AbstractBorder
|
||||
{
|
||||
@Override
|
||||
public Insets getBorderInsets( Component c, Insets insets ) {
|
||||
super.getBorderInsets( c, insets );
|
||||
|
||||
// if menu bar is embedded, add bottom insets of menu bar border
|
||||
Border menuBarBorder = getMenuBarBorder();
|
||||
if( menuBarBorder != null ) {
|
||||
Insets menuBarInsets = menuBarBorder.getBorderInsets( c );
|
||||
insets.bottom += menuBarInsets.bottom;
|
||||
}
|
||||
|
||||
if( hasJBRCustomDecoration() )
|
||||
insets = FlatUIUtils.addInsets( insets, JBRWindowTopBorder.getInstance().getBorderInsets() );
|
||||
|
||||
return insets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||
// if menu bar is embedded, paint menu bar border
|
||||
Border menuBarBorder = getMenuBarBorder();
|
||||
if( menuBarBorder != null )
|
||||
menuBarBorder.paintBorder( c, g, x, y, width, height );
|
||||
|
||||
if( hasJBRCustomDecoration() )
|
||||
JBRWindowTopBorder.getInstance().paintBorder( c, g, x, y, width, height );
|
||||
}
|
||||
|
||||
protected Border getMenuBarBorder() {
|
||||
JMenuBar menuBar = rootPane.getJMenuBar();
|
||||
return (menuBar != null && isMenuBarEmbedded()) ? menuBar.getBorder() : null;
|
||||
}
|
||||
}
|
||||
|
||||
//---- class Handler ------------------------------------------------------
|
||||
|
||||
protected class Handler
|
||||
extends WindowAdapter
|
||||
implements PropertyChangeListener, MouseListener, MouseMotionListener, ComponentListener
|
||||
{
|
||||
//---- interface PropertyChangeListener ----
|
||||
|
||||
@Override
|
||||
public void propertyChange( PropertyChangeEvent e ) {
|
||||
switch( e.getPropertyName() ) {
|
||||
case "title":
|
||||
titleLabel.setText( getWindowTitle() );
|
||||
break;
|
||||
|
||||
case "resizable":
|
||||
if( window instanceof Frame )
|
||||
frameStateChanged();
|
||||
break;
|
||||
|
||||
case "iconImage":
|
||||
updateIcon();
|
||||
break;
|
||||
|
||||
case "componentOrientation":
|
||||
updateJBRHitTestSpotsAndTitleBarHeightLater();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//---- interface WindowListener ----
|
||||
|
||||
@Override
|
||||
public void windowActivated( WindowEvent e ) {
|
||||
activeChanged( true );
|
||||
updateJBRHitTestSpotsAndTitleBarHeight();
|
||||
|
||||
if( hasJBRCustomDecoration() )
|
||||
JBRWindowTopBorder.getInstance().repaintBorder( FlatTitlePane.this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowDeactivated( WindowEvent e ) {
|
||||
activeChanged( false );
|
||||
updateJBRHitTestSpotsAndTitleBarHeight();
|
||||
|
||||
if( hasJBRCustomDecoration() )
|
||||
JBRWindowTopBorder.getInstance().repaintBorder( FlatTitlePane.this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowStateChanged( WindowEvent e ) {
|
||||
frameStateChanged();
|
||||
updateJBRHitTestSpotsAndTitleBarHeight();
|
||||
}
|
||||
|
||||
//---- interface MouseListener ----
|
||||
|
||||
private int lastXOnScreen;
|
||||
private int lastYOnScreen;
|
||||
|
||||
@Override
|
||||
public void mouseClicked( MouseEvent e ) {
|
||||
if( e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton( e ) ) {
|
||||
if( e.getSource() == iconLabel ) {
|
||||
// double-click on icon closes window
|
||||
close();
|
||||
} else if( !hasJBRCustomDecoration() &&
|
||||
window instanceof Frame &&
|
||||
((Frame)window).isResizable() )
|
||||
{
|
||||
// maximize/restore on double-click
|
||||
Frame frame = (Frame) window;
|
||||
if( (frame.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0 )
|
||||
restore();
|
||||
else
|
||||
maximize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed( MouseEvent e ) {
|
||||
lastXOnScreen = e.getXOnScreen();
|
||||
lastYOnScreen = e.getYOnScreen();
|
||||
}
|
||||
|
||||
@Override public void mouseReleased( MouseEvent e ) {}
|
||||
@Override public void mouseEntered( MouseEvent e ) {}
|
||||
@Override public void mouseExited( MouseEvent e ) {}
|
||||
|
||||
//---- interface MouseMotionListener ----
|
||||
|
||||
@Override
|
||||
public void mouseDragged( MouseEvent e ) {
|
||||
if( hasJBRCustomDecoration() )
|
||||
return; // do nothing if running in JBR
|
||||
|
||||
int xOnScreen = e.getXOnScreen();
|
||||
int yOnScreen = e.getYOnScreen();
|
||||
if( lastXOnScreen == xOnScreen && lastYOnScreen == yOnScreen )
|
||||
return;
|
||||
|
||||
// restore window if it is maximized
|
||||
if( window instanceof Frame ) {
|
||||
Frame frame = (Frame) window;
|
||||
int state = frame.getExtendedState();
|
||||
if( (state & Frame.MAXIMIZED_BOTH) != 0 ) {
|
||||
int maximizedX = window.getX();
|
||||
int maximizedY = window.getY();
|
||||
|
||||
// restore window size, which also moves window to pre-maximized location
|
||||
frame.setExtendedState( state & ~Frame.MAXIMIZED_BOTH );
|
||||
|
||||
int restoredWidth = window.getWidth();
|
||||
int newX = maximizedX;
|
||||
JComponent rightComp = getComponentOrientation().isLeftToRight() ? buttonPanel : leftPanel;
|
||||
if( xOnScreen >= maximizedX + restoredWidth - rightComp.getWidth() - 10 )
|
||||
newX = xOnScreen + rightComp.getWidth() + 10 - restoredWidth;
|
||||
|
||||
// move window near mouse
|
||||
window.setLocation( newX, maximizedY );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// compute new window location
|
||||
int newX = window.getX() + (xOnScreen - lastXOnScreen);
|
||||
int newY = window.getY() + (yOnScreen - lastYOnScreen);
|
||||
|
||||
// move window
|
||||
window.setLocation( newX, newY );
|
||||
|
||||
lastXOnScreen = xOnScreen;
|
||||
lastYOnScreen = yOnScreen;
|
||||
}
|
||||
|
||||
@Override public void mouseMoved( MouseEvent e ) {}
|
||||
|
||||
//---- interface ComponentListener ----
|
||||
|
||||
@Override
|
||||
public void componentResized( ComponentEvent e ) {
|
||||
updateJBRHitTestSpotsAndTitleBarHeightLater();
|
||||
}
|
||||
|
||||
@Override public void componentMoved( ComponentEvent e ) {}
|
||||
@Override public void componentShown( ComponentEvent e ) {}
|
||||
@Override public void componentHidden( ComponentEvent e ) {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Image;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import com.formdev.flatlaf.util.MultiResolutionImageSupport;
|
||||
import com.formdev.flatlaf.util.ScaledImageIcon;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatTitlePaneIcon
|
||||
extends ScaledImageIcon
|
||||
{
|
||||
public static Icon create( List<Image> images, Dimension size ) {
|
||||
// collect all images including multi-resolution variants
|
||||
List<Image> allImages = new ArrayList<>();
|
||||
for( Image image : images ) {
|
||||
if( MultiResolutionImageSupport.isMultiResolutionImage( image ) )
|
||||
allImages.addAll( MultiResolutionImageSupport.getResolutionVariants( image ) );
|
||||
else
|
||||
allImages.add( image );
|
||||
}
|
||||
|
||||
// sort images by size
|
||||
allImages.sort( (image1, image2) -> {
|
||||
return image1.getWidth( null ) - image2.getWidth( null );
|
||||
} );
|
||||
|
||||
// create icon
|
||||
return new FlatTitlePaneIcon( allImages, size );
|
||||
}
|
||||
|
||||
private final List<Image> images;
|
||||
|
||||
private FlatTitlePaneIcon( List<Image> images, Dimension size ) {
|
||||
super( new ImageIcon( images.get( 0 ) ), size.width, size.height );
|
||||
this.images = images;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Image getResolutionVariant( int destImageWidth, int destImageHeight ) {
|
||||
for( Image image : images ) {
|
||||
if( destImageWidth <= image.getWidth( null ) &&
|
||||
destImageHeight <= image.getHeight( null ) )
|
||||
return image;
|
||||
}
|
||||
|
||||
return images.get( images.size() - 1 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import static java.awt.Cursor.*;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowStateListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLayeredPane;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* Resizes frames and dialogs.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatWindowResizer
|
||||
extends JComponent
|
||||
implements PropertyChangeListener, WindowStateListener, ComponentListener
|
||||
{
|
||||
private final static Integer WINDOW_RESIZER_LAYER = JLayeredPane.DRAG_LAYER + 1;
|
||||
|
||||
private final JRootPane rootPane;
|
||||
|
||||
private final int borderDragThickness = FlatUIUtils.getUIInt( "RootPane.borderDragThickness", 5 );
|
||||
private final int cornerDragWidth = FlatUIUtils.getUIInt( "RootPane.cornerDragWidth", 16 );
|
||||
private final boolean honorMinimumSizeOnResize = UIManager.getBoolean( "RootPane.honorMinimumSizeOnResize" );
|
||||
|
||||
private Window window;
|
||||
|
||||
public FlatWindowResizer( JRootPane rootPane ) {
|
||||
this.rootPane = rootPane;
|
||||
|
||||
setLayout( new BorderLayout() );
|
||||
add( createDragBorderComponent( NW_RESIZE_CURSOR, N_RESIZE_CURSOR, NE_RESIZE_CURSOR ), BorderLayout.NORTH );
|
||||
add( createDragBorderComponent( SW_RESIZE_CURSOR, S_RESIZE_CURSOR, SE_RESIZE_CURSOR ), BorderLayout.SOUTH );
|
||||
add( createDragBorderComponent( NW_RESIZE_CURSOR, W_RESIZE_CURSOR, SW_RESIZE_CURSOR ), BorderLayout.WEST );
|
||||
add( createDragBorderComponent( NE_RESIZE_CURSOR, E_RESIZE_CURSOR, SE_RESIZE_CURSOR ), BorderLayout.EAST );
|
||||
|
||||
rootPane.addComponentListener( this );
|
||||
rootPane.getLayeredPane().add( this, WINDOW_RESIZER_LAYER );
|
||||
|
||||
if( rootPane.isDisplayable() )
|
||||
setBounds( 0, 0, rootPane.getWidth(), rootPane.getHeight() );
|
||||
}
|
||||
|
||||
protected DragBorderComponent createDragBorderComponent( int leadingResizeDir, int centerResizeDir, int trailingResizeDir ) {
|
||||
return new DragBorderComponent( leadingResizeDir, centerResizeDir, trailingResizeDir );
|
||||
}
|
||||
|
||||
public void uninstall() {
|
||||
rootPane.removeComponentListener( this );
|
||||
rootPane.getLayeredPane().remove( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNotify() {
|
||||
super.addNotify();
|
||||
|
||||
Container parent = rootPane.getParent();
|
||||
window = (parent instanceof Window) ? (Window) parent : null;
|
||||
if( window instanceof Frame ) {
|
||||
window.addPropertyChangeListener( "resizable", this );
|
||||
window.addWindowStateListener( this );
|
||||
}
|
||||
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNotify() {
|
||||
super.removeNotify();
|
||||
|
||||
if( window instanceof Frame ) {
|
||||
window.removePropertyChangeListener( "resizable", this );
|
||||
window.removeWindowStateListener( this );
|
||||
}
|
||||
window = null;
|
||||
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintChildren( Graphics g ) {
|
||||
super.paintChildren( g );
|
||||
|
||||
// this is necessary because Dialog.setResizable() does not fire events
|
||||
if( window instanceof Dialog )
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
private void updateVisibility() {
|
||||
boolean visible = isWindowResizable();
|
||||
if( visible == getComponent( 0 ).isVisible() )
|
||||
return;
|
||||
|
||||
for( Component c : getComponents() )
|
||||
c.setVisible( visible );
|
||||
}
|
||||
|
||||
private boolean isWindowResizable() {
|
||||
if( window instanceof Frame )
|
||||
return ((Frame)window).isResizable() && (((Frame)window).getExtendedState() & Frame.MAXIMIZED_BOTH) == 0;
|
||||
if( window instanceof Dialog )
|
||||
return ((Dialog)window).isResizable();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange( PropertyChangeEvent e ) {
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowStateChanged( WindowEvent e ) {
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentResized( ComponentEvent e ) {
|
||||
setBounds( 0, 0, rootPane.getWidth(), rootPane.getHeight() );
|
||||
validate();
|
||||
}
|
||||
|
||||
@Override public void componentMoved( ComponentEvent e ) {}
|
||||
@Override public void componentShown( ComponentEvent e ) {}
|
||||
@Override public void componentHidden( ComponentEvent e ) {}
|
||||
|
||||
//---- class DragBorderComponent ------------------------------------------
|
||||
|
||||
protected class DragBorderComponent
|
||||
extends JComponent
|
||||
implements MouseListener, MouseMotionListener
|
||||
{
|
||||
private final int leadingResizeDir;
|
||||
private final int centerResizeDir;
|
||||
private final int trailingResizeDir;
|
||||
|
||||
private int resizeDir = -1;
|
||||
private int dragStartMouseX;
|
||||
private int dragStartMouseY;
|
||||
private Rectangle dragStartWindowBounds;
|
||||
|
||||
protected DragBorderComponent( int leadingResizeDir, int centerResizeDir, int trailingResizeDir ) {
|
||||
this.leadingResizeDir = leadingResizeDir;
|
||||
this.centerResizeDir = centerResizeDir;
|
||||
this.trailingResizeDir = trailingResizeDir;
|
||||
|
||||
setResizeDir( centerResizeDir );
|
||||
setVisible( false );
|
||||
|
||||
addMouseListener( this );
|
||||
addMouseMotionListener( this );
|
||||
}
|
||||
|
||||
protected void setResizeDir( int resizeDir ) {
|
||||
if( this.resizeDir == resizeDir )
|
||||
return;
|
||||
this.resizeDir = resizeDir;
|
||||
|
||||
setCursor( getPredefinedCursor( resizeDir ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
int thickness = UIScale.scale( borderDragThickness );
|
||||
return new Dimension( thickness, thickness );
|
||||
}
|
||||
|
||||
/*debug
|
||||
@Override
|
||||
protected void paintComponent( Graphics g ) {
|
||||
g.setColor( java.awt.Color.red );
|
||||
g.drawRect( 0, 0, getWidth() - 1, getHeight() - 1 );
|
||||
}
|
||||
debug*/
|
||||
|
||||
@Override
|
||||
public void mouseClicked( MouseEvent e ) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed( MouseEvent e ) {
|
||||
if( window == null )
|
||||
return;
|
||||
|
||||
dragStartMouseX = e.getXOnScreen();
|
||||
dragStartMouseY = e.getYOnScreen();
|
||||
dragStartWindowBounds = window.getBounds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased( MouseEvent e ) {
|
||||
dragStartWindowBounds = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered( MouseEvent e ) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited( MouseEvent e ) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMoved( MouseEvent e ) {
|
||||
boolean topBottom = (centerResizeDir == N_RESIZE_CURSOR || centerResizeDir == S_RESIZE_CURSOR);
|
||||
int xy = topBottom ? e.getX() : e.getY();
|
||||
int wh = topBottom ? getWidth() : getHeight();
|
||||
int cornerWH = UIScale.scale( cornerDragWidth - (topBottom ? 0 : borderDragThickness) );
|
||||
|
||||
setResizeDir( xy <= cornerWH
|
||||
? leadingResizeDir
|
||||
: (xy >= wh - cornerWH
|
||||
? trailingResizeDir
|
||||
: centerResizeDir) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged( MouseEvent e ) {
|
||||
if( dragStartWindowBounds == null )
|
||||
return;
|
||||
|
||||
if( !isWindowResizable() )
|
||||
return;
|
||||
|
||||
int mouseDeltaX = e.getXOnScreen() - dragStartMouseX;
|
||||
int mouseDeltaY = e.getYOnScreen() - dragStartMouseY;
|
||||
|
||||
int deltaX = 0;
|
||||
int deltaY = 0;
|
||||
int deltaWidth = 0;
|
||||
int deltaHeight = 0;
|
||||
|
||||
// north
|
||||
if( resizeDir == N_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR ) {
|
||||
deltaY = mouseDeltaY;
|
||||
deltaHeight = -mouseDeltaY;
|
||||
}
|
||||
|
||||
// south
|
||||
if( resizeDir == S_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR )
|
||||
deltaHeight = mouseDeltaY;
|
||||
|
||||
// west
|
||||
if( resizeDir == W_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR ) {
|
||||
deltaX = mouseDeltaX;
|
||||
deltaWidth = -mouseDeltaX;
|
||||
}
|
||||
|
||||
// east
|
||||
if( resizeDir == E_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR )
|
||||
deltaWidth = mouseDeltaX;
|
||||
|
||||
// compute new window bounds
|
||||
Rectangle newBounds = new Rectangle( dragStartWindowBounds );
|
||||
newBounds.x += deltaX;
|
||||
newBounds.y += deltaY;
|
||||
newBounds.width += deltaWidth;
|
||||
newBounds.height += deltaHeight;
|
||||
|
||||
// apply minimum window size
|
||||
Dimension minimumSize = honorMinimumSizeOnResize ? window.getMinimumSize() : null;
|
||||
if( minimumSize == null )
|
||||
minimumSize = UIScale.scale( new Dimension( 150, 50 ) );
|
||||
if( newBounds.width < minimumSize.width ) {
|
||||
if( deltaX != 0 )
|
||||
newBounds.x -= (minimumSize.width - newBounds.width);
|
||||
newBounds.width = minimumSize.width;
|
||||
}
|
||||
if( newBounds.height < minimumSize.height ) {
|
||||
if( deltaY != 0 )
|
||||
newBounds.y -= (minimumSize.height - newBounds.height);
|
||||
newBounds.height = minimumSize.height;
|
||||
}
|
||||
|
||||
// set window bounds
|
||||
if( !newBounds.equals( dragStartWindowBounds ) ) {
|
||||
window.setBounds( newBounds );
|
||||
|
||||
// immediately layout drag border components
|
||||
FlatWindowResizer.this.setBounds( 0, 0, newBounds.width, newBounds.height );
|
||||
FlatWindowResizer.this.validate();
|
||||
|
||||
if( Toolkit.getDefaultToolkit().isDynamicLayoutActive() ) {
|
||||
window.validate();
|
||||
rootPane.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.HierarchyEvent;
|
||||
import java.awt.event.HierarchyListener;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.BorderUIResource;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.FlatSystemProperties;
|
||||
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
|
||||
/**
|
||||
* Support for custom window decorations provided by JetBrains Runtime (based on OpenJDK).
|
||||
* Requires that the application runs on Windows 10 in a JetBrains Runtime 11 or later.
|
||||
* <ul>
|
||||
* <li><a href="https://confluence.jetbrains.com/display/JBR/JetBrains+Runtime">https://confluence.jetbrains.com/display/JBR/JetBrains+Runtime</a></li>
|
||||
* <li><a href="https://github.com/JetBrains/JetBrainsRuntime">https://github.com/JetBrains/JetBrainsRuntime</a></li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class JBRCustomDecorations
|
||||
{
|
||||
private static boolean initialized;
|
||||
private static Method Window_hasCustomDecoration;
|
||||
private static Method Window_setHasCustomDecoration;
|
||||
private static Method WWindowPeer_setCustomDecorationHitTestSpots;
|
||||
private static Method WWindowPeer_setCustomDecorationTitleBarHeight;
|
||||
private static Method AWTAccessor_getComponentAccessor;
|
||||
private static Method AWTAccessor_ComponentAccessor_getPeer;
|
||||
|
||||
public static boolean isSupported() {
|
||||
initialize();
|
||||
return Window_setHasCustomDecoration != null;
|
||||
}
|
||||
|
||||
static void install( JRootPane rootPane ) {
|
||||
if( !isSupported() )
|
||||
return;
|
||||
|
||||
// check whether root pane already has a parent, which is the case when switching LaF
|
||||
if( rootPane.getParent() != null )
|
||||
return;
|
||||
|
||||
// Use hierarchy listener to wait until the root pane is added to a window.
|
||||
// Enabling JBR decorations must be done very early, probably before
|
||||
// window becomes displayable (window.isDisplayable()). Tried also using
|
||||
// "ancestor" property change event on root pane, but this is invoked too late.
|
||||
HierarchyListener addListener = new HierarchyListener() {
|
||||
@Override
|
||||
public void hierarchyChanged( HierarchyEvent e ) {
|
||||
if( e.getChanged() != rootPane || (e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED) == 0 )
|
||||
return;
|
||||
|
||||
Container parent = e.getChangedParent();
|
||||
if( parent instanceof Window )
|
||||
install( (Window) parent );
|
||||
|
||||
// use invokeLater to remove listener to avoid that listener
|
||||
// is removed while listener queue is processed
|
||||
EventQueue.invokeLater( () -> {
|
||||
rootPane.removeHierarchyListener( this );
|
||||
} );
|
||||
}
|
||||
};
|
||||
rootPane.addHierarchyListener( addListener );
|
||||
}
|
||||
|
||||
static void install( Window window ) {
|
||||
if( !isSupported() )
|
||||
return;
|
||||
|
||||
// do not enable JBR decorations if LaF provides decorations
|
||||
if( UIManager.getLookAndFeel().getSupportsWindowDecorations() )
|
||||
return;
|
||||
|
||||
if( window instanceof JFrame ) {
|
||||
JFrame frame = (JFrame) window;
|
||||
|
||||
// do not enable JBR decorations if JFrame should use system window decorations
|
||||
// and if not forced to use JBR decorations
|
||||
if( !JFrame.isDefaultLookAndFeelDecorated() &&
|
||||
!FlatSystemProperties.getBoolean( FlatSystemProperties.USE_JETBRAINS_CUSTOM_DECORATIONS, false ))
|
||||
return;
|
||||
|
||||
// do not enable JBR decorations if frame is undecorated
|
||||
if( frame.isUndecorated() )
|
||||
return;
|
||||
|
||||
// enable JBR custom window decoration for window
|
||||
setHasCustomDecoration( frame );
|
||||
|
||||
// enable Swing window decoration
|
||||
frame.getRootPane().setWindowDecorationStyle( JRootPane.FRAME );
|
||||
|
||||
} else if( window instanceof JDialog ) {
|
||||
JDialog dialog = (JDialog) window;
|
||||
|
||||
// do not enable JBR decorations if JDialog should use system window decorations
|
||||
// and if not forced to use JBR decorations
|
||||
if( !JDialog.isDefaultLookAndFeelDecorated() &&
|
||||
!FlatSystemProperties.getBoolean( FlatSystemProperties.USE_JETBRAINS_CUSTOM_DECORATIONS, false ))
|
||||
return;
|
||||
|
||||
// do not enable JBR decorations if dialog is undecorated
|
||||
if( dialog.isUndecorated() )
|
||||
return;
|
||||
|
||||
// enable JBR custom window decoration for window
|
||||
setHasCustomDecoration( dialog );
|
||||
|
||||
// enable Swing window decoration
|
||||
dialog.getRootPane().setWindowDecorationStyle( JRootPane.PLAIN_DIALOG );
|
||||
}
|
||||
}
|
||||
|
||||
static boolean hasCustomDecoration( Window window ) {
|
||||
if( !isSupported() )
|
||||
return false;
|
||||
|
||||
try {
|
||||
return (Boolean) Window_hasCustomDecoration.invoke( window );
|
||||
} catch( Exception ex ) {
|
||||
Logger.getLogger( FlatLaf.class.getName() ).log( Level.SEVERE, null, ex );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void setHasCustomDecoration( Window window ) {
|
||||
if( !isSupported() )
|
||||
return;
|
||||
|
||||
try {
|
||||
Window_setHasCustomDecoration.invoke( window );
|
||||
} catch( Exception ex ) {
|
||||
Logger.getLogger( FlatLaf.class.getName() ).log( Level.SEVERE, null, ex );
|
||||
}
|
||||
}
|
||||
|
||||
static void setHitTestSpotsAndTitleBarHeight( Window window, List<Rectangle> hitTestSpots, int titleBarHeight ) {
|
||||
if( !isSupported() )
|
||||
return;
|
||||
|
||||
try {
|
||||
Object compAccessor = AWTAccessor_getComponentAccessor.invoke( null );
|
||||
Object peer = AWTAccessor_ComponentAccessor_getPeer.invoke( compAccessor, window );
|
||||
WWindowPeer_setCustomDecorationHitTestSpots.invoke( peer, hitTestSpots );
|
||||
WWindowPeer_setCustomDecorationTitleBarHeight.invoke( peer, titleBarHeight );
|
||||
} catch( Exception ex ) {
|
||||
Logger.getLogger( FlatLaf.class.getName() ).log( Level.SEVERE, null, ex );
|
||||
}
|
||||
}
|
||||
|
||||
private static void initialize() {
|
||||
if( initialized )
|
||||
return;
|
||||
initialized = true;
|
||||
|
||||
// requires JetBrains Runtime 11 and Windows 10
|
||||
if( !SystemInfo.IS_JETBRAINS_JVM_11_OR_LATER || !SystemInfo.IS_WINDOWS_10_OR_LATER )
|
||||
return;
|
||||
|
||||
if( !FlatSystemProperties.getBoolean( FlatSystemProperties.USE_JETBRAINS_CUSTOM_DECORATIONS, true ) )
|
||||
return;
|
||||
|
||||
try {
|
||||
Class<?> awtAcessorClass = Class.forName( "sun.awt.AWTAccessor" );
|
||||
Class<?> compAccessorClass = Class.forName( "sun.awt.AWTAccessor$ComponentAccessor" );
|
||||
AWTAccessor_getComponentAccessor = awtAcessorClass.getDeclaredMethod( "getComponentAccessor" );
|
||||
AWTAccessor_ComponentAccessor_getPeer = compAccessorClass.getDeclaredMethod( "getPeer", Component.class );
|
||||
|
||||
Class<?> peerClass = Class.forName( "sun.awt.windows.WWindowPeer" );
|
||||
WWindowPeer_setCustomDecorationHitTestSpots = peerClass.getDeclaredMethod( "setCustomDecorationHitTestSpots", List.class );
|
||||
WWindowPeer_setCustomDecorationTitleBarHeight = peerClass.getDeclaredMethod( "setCustomDecorationTitleBarHeight", int.class );
|
||||
WWindowPeer_setCustomDecorationHitTestSpots.setAccessible( true );
|
||||
WWindowPeer_setCustomDecorationTitleBarHeight.setAccessible( true );
|
||||
|
||||
Window_hasCustomDecoration = Window.class.getDeclaredMethod( "hasCustomDecoration" );
|
||||
Window_setHasCustomDecoration = Window.class.getDeclaredMethod( "setHasCustomDecoration" );
|
||||
Window_hasCustomDecoration.setAccessible( true );
|
||||
Window_setHasCustomDecoration.setAccessible( true );
|
||||
} catch( Exception ex ) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
//---- class JBRWindowTopBorder -------------------------------------------
|
||||
|
||||
static class JBRWindowTopBorder
|
||||
extends BorderUIResource.EmptyBorderUIResource
|
||||
{
|
||||
private static JBRWindowTopBorder instance;
|
||||
|
||||
private final Color defaultActiveBorder = new Color( 0x707070 );
|
||||
private final Color inactiveLightColor = new Color( 0xaaaaaa );
|
||||
private final Color inactiveDarkColor = new Color( 0x3f3f3f );
|
||||
|
||||
private boolean colorizationAffectsBorders;
|
||||
private Color activeColor = defaultActiveBorder;
|
||||
|
||||
static JBRWindowTopBorder getInstance() {
|
||||
if( instance == null )
|
||||
instance = new JBRWindowTopBorder();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private JBRWindowTopBorder() {
|
||||
super( 1, 0, 0, 0 );
|
||||
|
||||
colorizationAffectsBorders = calculateAffectsBorders();
|
||||
activeColor = calculateActiveBorderColor();
|
||||
|
||||
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
||||
toolkit.addPropertyChangeListener( "win.dwm.colorizationColor.affects.borders", e -> {
|
||||
colorizationAffectsBorders = calculateAffectsBorders();
|
||||
activeColor = calculateActiveBorderColor();
|
||||
} );
|
||||
|
||||
PropertyChangeListener l = e -> {
|
||||
activeColor = calculateActiveBorderColor();
|
||||
};
|
||||
toolkit.addPropertyChangeListener( "win.dwm.colorizationColor", l );
|
||||
toolkit.addPropertyChangeListener( "win.dwm.colorizationColorBalance", l );
|
||||
toolkit.addPropertyChangeListener( "win.frame.activeBorderColor", l );
|
||||
}
|
||||
|
||||
private boolean calculateAffectsBorders() {
|
||||
Object value = Toolkit.getDefaultToolkit().getDesktopProperty( "win.dwm.colorizationColor.affects.borders" );
|
||||
return (value instanceof Boolean) ? (Boolean) value : true;
|
||||
}
|
||||
|
||||
private Color calculateActiveBorderColor() {
|
||||
if( !colorizationAffectsBorders )
|
||||
return defaultActiveBorder;
|
||||
|
||||
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
||||
Color colorizationColor = (Color) toolkit.getDesktopProperty( "win.dwm.colorizationColor" );
|
||||
if( colorizationColor != null ) {
|
||||
Object colorizationColorBalanceObj = toolkit.getDesktopProperty( "win.dwm.colorizationColorBalance" );
|
||||
if( colorizationColorBalanceObj instanceof Integer ) {
|
||||
int colorizationColorBalance = (Integer) colorizationColorBalanceObj;
|
||||
if( colorizationColorBalance < 0 )
|
||||
colorizationColorBalance = 100;
|
||||
|
||||
if( colorizationColorBalance == 0 )
|
||||
return new Color( 0xD9D9D9 );
|
||||
if( colorizationColorBalance == 100 )
|
||||
return colorizationColor;
|
||||
|
||||
float alpha = colorizationColorBalance / 100.0f;
|
||||
float remainder = 1 - alpha;
|
||||
int r = Math.round( (colorizationColor.getRed() * alpha + 0xD9 * remainder) );
|
||||
int g = Math.round( (colorizationColor.getGreen() * alpha + 0xD9 * remainder) );
|
||||
int b = Math.round( (colorizationColor.getBlue() * alpha + 0xD9 * remainder) );
|
||||
return new Color( r, g, b );
|
||||
}
|
||||
return colorizationColor;
|
||||
}
|
||||
|
||||
Color activeBorderColor = (Color) toolkit.getDesktopProperty( "win.frame.activeBorderColor" );
|
||||
return (activeBorderColor != null) ? activeBorderColor : UIManager.getColor( "MenuBar.borderColor" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||
Window window = SwingUtilities.windowForComponent( c );
|
||||
boolean active = (window != null) ? window.isActive() : false;
|
||||
|
||||
g.setColor( active ? activeColor : (FlatLaf.isLafDark() ? inactiveDarkColor : inactiveLightColor) );
|
||||
HiDPIUtils.paintAtScale1x( (Graphics2D) g, x, y, width, height, this::paintImpl );
|
||||
}
|
||||
|
||||
private void paintImpl( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||
g.drawRect( x, y, width - 1, 0 );
|
||||
}
|
||||
|
||||
void repaintBorder( Component c ) {
|
||||
c.repaint( 0, 0, c.getWidth(), 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import javax.swing.JComponent;
|
||||
import com.formdev.flatlaf.FlatSystemProperties;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
@@ -104,7 +105,7 @@ public class HiDPIUtils
|
||||
|
||||
private static boolean useTextYCorrection() {
|
||||
if( useTextYCorrection == null )
|
||||
useTextYCorrection = Boolean.valueOf( System.getProperty( "flatlaf.useTextYCorrection", "true" ) );
|
||||
useTextYCorrection = FlatSystemProperties.getBoolean( FlatSystemProperties.USE_TEXT_Y_CORRECTION, true );
|
||||
return useTextYCorrection;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,30 +37,38 @@ public class ScaledImageIcon
|
||||
implements Icon
|
||||
{
|
||||
private final ImageIcon imageIcon;
|
||||
private final int iconWidth;
|
||||
private final int iconHeight;
|
||||
|
||||
private double lastSystemScaleFactor;
|
||||
private float lastUserScaleFactor;
|
||||
private Image lastImage;
|
||||
|
||||
public ScaledImageIcon( ImageIcon imageIcon ) {
|
||||
this( imageIcon, imageIcon.getIconWidth(), imageIcon.getIconHeight() );
|
||||
}
|
||||
|
||||
public ScaledImageIcon( ImageIcon imageIcon, int iconWidth, int iconHeight ) {
|
||||
this.imageIcon = imageIcon;
|
||||
this.iconWidth = iconWidth;
|
||||
this.iconHeight = iconHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return UIScale.scale( imageIcon.getIconWidth() );
|
||||
return UIScale.scale( iconWidth );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return UIScale.scale( imageIcon.getIconHeight() );
|
||||
return UIScale.scale( iconHeight );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintIcon( Component c, Graphics g, int x, int y ) {
|
||||
/*debug
|
||||
g.setColor( Color.red );
|
||||
g.drawRect( x, y, getIconWidth(), getIconHeight() );
|
||||
g.drawRect( x, y, getIconWidth() - 1, getIconHeight() - 1 );
|
||||
debug*/
|
||||
|
||||
// scale factor
|
||||
@@ -69,7 +77,7 @@ debug*/
|
||||
double scaleFactor = systemScaleFactor * userScaleFactor;
|
||||
|
||||
// paint input image icon if not necessary to scale
|
||||
if( scaleFactor == 1 ) {
|
||||
if( scaleFactor == 1 && iconWidth == imageIcon.getIconWidth() && iconHeight == imageIcon.getIconHeight() ) {
|
||||
imageIcon.paintIcon( c, g, x, y );
|
||||
return;
|
||||
}
|
||||
@@ -84,12 +92,11 @@ debug*/
|
||||
}
|
||||
|
||||
// destination image size
|
||||
int destImageWidth = (int) Math.round( imageIcon.getIconWidth() * scaleFactor );
|
||||
int destImageHeight = (int) Math.round( imageIcon.getIconHeight() * scaleFactor );
|
||||
int destImageWidth = (int) Math.round( iconWidth * scaleFactor );
|
||||
int destImageHeight = (int) Math.round( iconHeight * scaleFactor );
|
||||
|
||||
// get resolution variant of image if it is a multi-resolution image
|
||||
Image image = MultiResolutionImageSupport.getResolutionVariant(
|
||||
imageIcon.getImage(), destImageWidth, destImageHeight );
|
||||
Image image = getResolutionVariant( destImageWidth, destImageHeight );
|
||||
|
||||
// size of image
|
||||
int imageWidth = image.getWidth( null );
|
||||
@@ -124,6 +131,11 @@ debug*/
|
||||
paintLastImage( g, x, y );
|
||||
}
|
||||
|
||||
protected Image getResolutionVariant( int destImageWidth, int destImageHeight ) {
|
||||
return MultiResolutionImageSupport.getResolutionVariant(
|
||||
imageIcon.getImage(), destImageWidth, destImageHeight );
|
||||
}
|
||||
|
||||
private void paintLastImage( Graphics g, int x, int y ) {
|
||||
if( lastSystemScaleFactor > 1 ) {
|
||||
HiDPIUtils.paintAtScale1x( (Graphics2D) g, x, y, 100, 100, // width and height are not used
|
||||
|
||||
@@ -32,14 +32,19 @@ public class SystemInfo
|
||||
public static final boolean IS_LINUX;
|
||||
|
||||
// OS versions
|
||||
public static final boolean IS_WINDOWS_10_OR_LATER;
|
||||
public static final boolean IS_MAC_OS_10_11_EL_CAPITAN_OR_LATER;
|
||||
public static final boolean IS_MAC_OS_10_14_MOJAVE;
|
||||
public static final boolean IS_MAC_OS_10_15_CATALINA_OR_LATER;
|
||||
|
||||
// Java versions
|
||||
public static final boolean IS_JAVA_9_OR_LATER;
|
||||
public static final boolean IS_JAVA_11_OR_LATER;
|
||||
public static final boolean IS_JAVA_15_OR_LATER;
|
||||
|
||||
// Java VMs
|
||||
public static final boolean IS_JETBRAINS_JVM;
|
||||
public static final boolean IS_JETBRAINS_JVM_11_OR_LATER;
|
||||
|
||||
// UI toolkits
|
||||
public static final boolean IS_KDE;
|
||||
@@ -53,16 +58,21 @@ public class SystemInfo
|
||||
|
||||
// OS versions
|
||||
long osVersion = scanVersion( System.getProperty( "os.version" ) );
|
||||
IS_WINDOWS_10_OR_LATER = (IS_WINDOWS && osVersion >= toVersion( 10, 0, 0, 0 ));
|
||||
IS_MAC_OS_10_11_EL_CAPITAN_OR_LATER = (IS_MAC && osVersion >= toVersion( 10, 11, 0, 0 ));
|
||||
IS_MAC_OS_10_14_MOJAVE = (IS_MAC && osVersion >= toVersion( 10, 14, 0, 0 ));
|
||||
IS_MAC_OS_10_15_CATALINA_OR_LATER = (IS_MAC && osVersion >= toVersion( 10, 15, 0, 0 ));
|
||||
|
||||
// Java versions
|
||||
long javaVersion = scanVersion( System.getProperty( "java.version" ) );
|
||||
IS_JAVA_9_OR_LATER = (javaVersion >= toVersion( 9, 0, 0, 0 ));
|
||||
IS_JAVA_11_OR_LATER = (javaVersion >= toVersion( 11, 0, 0, 0 ));
|
||||
IS_JAVA_15_OR_LATER = (javaVersion >= toVersion( 15, 0, 0, 0 ));
|
||||
|
||||
// Java VMs
|
||||
IS_JETBRAINS_JVM = System.getProperty( "java.vm.vendor", "Unknown" )
|
||||
.toLowerCase( Locale.ENGLISH ).contains( "jetbrains" );
|
||||
IS_JETBRAINS_JVM_11_OR_LATER = IS_JETBRAINS_JVM && IS_JAVA_11_OR_LATER;
|
||||
|
||||
// UI toolkits
|
||||
IS_KDE = (IS_LINUX && System.getenv( "KDE_FULL_SESSION" ) != null);
|
||||
|
||||
@@ -32,6 +32,7 @@ import javax.swing.plaf.DimensionUIResource;
|
||||
import javax.swing.plaf.FontUIResource;
|
||||
import javax.swing.plaf.InsetsUIResource;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import com.formdev.flatlaf.FlatSystemProperties;
|
||||
|
||||
/**
|
||||
* Two scaling modes are supported for HiDPI displays:
|
||||
@@ -195,8 +196,7 @@ public class UIScale
|
||||
|
||||
private static boolean isUserScalingEnabled() {
|
||||
// same as in IntelliJ IDEA
|
||||
String hidpi = System.getProperty( "hidpi" );
|
||||
return (hidpi != null) ? Boolean.parseBoolean( hidpi ) : true;
|
||||
return FlatSystemProperties.getBoolean( "hidpi", true );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,7 +204,7 @@ public class UIScale
|
||||
* to the given font.
|
||||
*/
|
||||
public static FontUIResource applyCustomScaleFactor( FontUIResource font ) {
|
||||
String uiScale = System.getProperty( "flatlaf.uiScale" );
|
||||
String uiScale = System.getProperty( FlatSystemProperties.UI_SCALE );
|
||||
float scaleFactor = parseScaleFactor( uiScale );
|
||||
if( scaleFactor <= 0 )
|
||||
return font;
|
||||
|
||||
@@ -293,6 +293,13 @@ TableHeader.separatorColor=lighten($TableHeader.background,10%)
|
||||
TableHeader.bottomSeparatorColor=$TableHeader.separatorColor
|
||||
|
||||
|
||||
#---- TitlePane ----
|
||||
|
||||
TitlePane.embeddedForeground=darken($TitlePane.foreground,15%)
|
||||
TitlePane.buttonHoverBackground=lighten($TitlePane.background,10%,derived)
|
||||
TitlePane.buttonPressedBackground=lighten($TitlePane.background,20%,derived)
|
||||
|
||||
|
||||
#---- ToggleButton ----
|
||||
|
||||
ToggleButton.selectedBackground=lighten($ToggleButton.background,10%,derived)
|
||||
|
||||
@@ -425,6 +425,14 @@ RadioButtonMenuItem.borderPainted=true
|
||||
RadioButtonMenuItem.background=@menuBackground
|
||||
|
||||
|
||||
#---- RootPane ----
|
||||
|
||||
RootPane.border=com.formdev.flatlaf.ui.FlatRootPaneUI$FlatWindowBorder
|
||||
RootPane.borderDragThickness=5
|
||||
RootPane.cornerDragWidth=16
|
||||
RootPane.honorMinimumSizeOnResize=true
|
||||
|
||||
|
||||
#---- ScrollBar ----
|
||||
|
||||
ScrollBar.width=10
|
||||
@@ -578,6 +586,31 @@ TitledBorder.titleColor=@foreground
|
||||
TitledBorder.border=1,1,1,1,$Separator.foreground
|
||||
|
||||
|
||||
#---- TitlePane ----
|
||||
|
||||
TitlePane.menuBarEmbedded=true
|
||||
TitlePane.iconSize=16,16
|
||||
TitlePane.iconMargins=3,8,3,0
|
||||
TitlePane.menuBarMargins=0,8,0,22
|
||||
TitlePane.titleMargins=3,8,3,8
|
||||
TitlePane.buttonSize=44,30
|
||||
TitlePane.buttonMaximizedHeight=22
|
||||
TitlePane.closeIcon=com.formdev.flatlaf.icons.FlatWindowCloseIcon
|
||||
TitlePane.iconifyIcon=com.formdev.flatlaf.icons.FlatWindowIconifyIcon
|
||||
TitlePane.maximizeIcon=com.formdev.flatlaf.icons.FlatWindowMaximizeIcon
|
||||
TitlePane.restoreIcon=com.formdev.flatlaf.icons.FlatWindowRestoreIcon
|
||||
|
||||
TitlePane.background=$MenuBar.background
|
||||
TitlePane.inactiveBackground=$TitlePane.background
|
||||
TitlePane.foreground=@foreground
|
||||
TitlePane.inactiveForeground=@disabledText
|
||||
|
||||
TitlePane.closeHoverBackground=#e81123
|
||||
TitlePane.closePressedBackground=rgba($TitlePane.closeHoverBackground,60%)
|
||||
TitlePane.closeHoverForeground=#fff
|
||||
TitlePane.closePressedForeground=#fff
|
||||
|
||||
|
||||
#---- ToggleButton ----
|
||||
|
||||
ToggleButton.border=com.formdev.flatlaf.ui.FlatButtonBorder
|
||||
|
||||
@@ -305,6 +305,13 @@ TableHeader.separatorColor=darken($TableHeader.background,10%)
|
||||
TableHeader.bottomSeparatorColor=$TableHeader.separatorColor
|
||||
|
||||
|
||||
#---- TitlePane ----
|
||||
|
||||
TitlePane.embeddedForeground=lighten($TitlePane.foreground,35%)
|
||||
TitlePane.buttonHoverBackground=darken($TitlePane.background,10%,derived)
|
||||
TitlePane.buttonPressedBackground=darken($TitlePane.background,20%,derived)
|
||||
|
||||
|
||||
#---- ToggleButton ----
|
||||
|
||||
ToggleButton.selectedBackground=darken($ToggleButton.background,20%,derived)
|
||||
|
||||
@@ -23,11 +23,13 @@ import java.util.Arrays;
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.DefaultEditorKit;
|
||||
import javax.swing.text.StyleContext;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.demo.extras.*;
|
||||
import com.formdev.flatlaf.demo.intellijthemes.*;
|
||||
import com.formdev.flatlaf.extras.FlatSVGIcon;
|
||||
import com.formdev.flatlaf.extras.SVGUtils;
|
||||
import com.formdev.flatlaf.ui.JBRCustomDecorations;
|
||||
import net.miginfocom.swing.*;
|
||||
|
||||
/**
|
||||
@@ -74,6 +76,26 @@ class DemoFrame
|
||||
} );
|
||||
}
|
||||
|
||||
private void windowDecorationsChanged() {
|
||||
boolean windowDecorations = windowDecorationsCheckBoxMenuItem.isSelected();
|
||||
|
||||
dispose();
|
||||
setUndecorated( windowDecorations );
|
||||
getRootPane().setWindowDecorationStyle( windowDecorations ? JRootPane.FRAME : JRootPane.NONE );
|
||||
menuBarEmbeddedCheckBoxMenuItem.setEnabled( windowDecorations );
|
||||
setVisible( true );
|
||||
}
|
||||
|
||||
private void menuBarEmbeddedChanged() {
|
||||
getRootPane().putClientProperty( FlatClientProperties.MENU_BAR_EMBEDDED,
|
||||
menuBarEmbeddedCheckBoxMenuItem.isSelected() ? null : false );
|
||||
|
||||
// alternative method for all frames and menu bars in an application
|
||||
// UIManager.put( "TitlePane.menuBarEmbedded", menuBarEmbeddedCheckBoxMenuItem.isSelected() );
|
||||
// revalidate();
|
||||
// repaint();
|
||||
}
|
||||
|
||||
private void underlineMenuSelection() {
|
||||
UIManager.put( "MenuItem.selectionType", underlineMenuSelectionMenuItem.isSelected() ? "underline" : null );
|
||||
}
|
||||
@@ -222,6 +244,8 @@ class DemoFrame
|
||||
JMenuItem incrFontMenuItem = new JMenuItem();
|
||||
JMenuItem decrFontMenuItem = new JMenuItem();
|
||||
JMenu optionsMenu = new JMenu();
|
||||
windowDecorationsCheckBoxMenuItem = new JCheckBoxMenuItem();
|
||||
menuBarEmbeddedCheckBoxMenuItem = new JCheckBoxMenuItem();
|
||||
underlineMenuSelectionMenuItem = new JCheckBoxMenuItem();
|
||||
alwaysShowMnemonicsMenuItem = new JCheckBoxMenuItem();
|
||||
JMenu helpMenu = new JMenu();
|
||||
@@ -456,6 +480,18 @@ class DemoFrame
|
||||
{
|
||||
optionsMenu.setText("Options");
|
||||
|
||||
//---- windowDecorationsCheckBoxMenuItem ----
|
||||
windowDecorationsCheckBoxMenuItem.setText("Window decorations");
|
||||
windowDecorationsCheckBoxMenuItem.setSelected(true);
|
||||
windowDecorationsCheckBoxMenuItem.addActionListener(e -> windowDecorationsChanged());
|
||||
optionsMenu.add(windowDecorationsCheckBoxMenuItem);
|
||||
|
||||
//---- menuBarEmbeddedCheckBoxMenuItem ----
|
||||
menuBarEmbeddedCheckBoxMenuItem.setText("Embedded menu bar");
|
||||
menuBarEmbeddedCheckBoxMenuItem.setSelected(true);
|
||||
menuBarEmbeddedCheckBoxMenuItem.addActionListener(e -> menuBarEmbeddedChanged());
|
||||
optionsMenu.add(menuBarEmbeddedCheckBoxMenuItem);
|
||||
|
||||
//---- underlineMenuSelectionMenuItem ----
|
||||
underlineMenuSelectionMenuItem.setText("Use underline menu selection");
|
||||
underlineMenuSelectionMenuItem.addActionListener(e -> underlineMenuSelection());
|
||||
@@ -571,10 +607,17 @@ class DemoFrame
|
||||
cutMenuItem.addActionListener( new DefaultEditorKit.CutAction() );
|
||||
copyMenuItem.addActionListener( new DefaultEditorKit.CopyAction() );
|
||||
pasteMenuItem.addActionListener( new DefaultEditorKit.PasteAction() );
|
||||
|
||||
boolean supportsWindowDecorations = UIManager.getLookAndFeel()
|
||||
.getSupportsWindowDecorations() || JBRCustomDecorations.isSupported();
|
||||
windowDecorationsCheckBoxMenuItem.setEnabled( supportsWindowDecorations && !JBRCustomDecorations.isSupported() );
|
||||
menuBarEmbeddedCheckBoxMenuItem.setEnabled( supportsWindowDecorations );
|
||||
}
|
||||
|
||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||
private JMenu fontMenu;
|
||||
private JCheckBoxMenuItem windowDecorationsCheckBoxMenuItem;
|
||||
private JCheckBoxMenuItem menuBarEmbeddedCheckBoxMenuItem;
|
||||
private JCheckBoxMenuItem underlineMenuSelectionMenuItem;
|
||||
private JCheckBoxMenuItem alwaysShowMnemonicsMenuItem;
|
||||
private JTabbedPane tabbedPane;
|
||||
|
||||
@@ -322,6 +322,24 @@ new FormModel {
|
||||
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||
name: "optionsMenu"
|
||||
"text": "Options"
|
||||
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
|
||||
name: "windowDecorationsCheckBoxMenuItem"
|
||||
"text": "Window decorations"
|
||||
"selected": true
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "windowDecorationsChanged", false ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
|
||||
name: "menuBarEmbeddedCheckBoxMenuItem"
|
||||
"text": "Embedded menu bar"
|
||||
"selected": true
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuBarEmbeddedChanged", false ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
|
||||
name: "underlineMenuSelectionMenuItem"
|
||||
"text": "Use underline menu selection"
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.formdev.flatlaf.demo;
|
||||
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.SwingUtilities;
|
||||
import com.formdev.flatlaf.extras.FlatInspector;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
@@ -36,6 +38,10 @@ public class FlatLafDemo
|
||||
SwingUtilities.invokeLater( () -> {
|
||||
DemoPrefs.init( PREFS_ROOT_PATH );
|
||||
|
||||
// enable window decorations
|
||||
JFrame.setDefaultLookAndFeelDecorated( true );
|
||||
JDialog.setDefaultLookAndFeelDecorated( true );
|
||||
|
||||
// set look and feel
|
||||
DemoPrefs.initLaf( args );
|
||||
|
||||
|
||||
@@ -293,6 +293,9 @@ public class FlatInspector
|
||||
if( c.getParent() instanceof JRootPane && c == ((JRootPane)c.getParent()).getGlassPane() )
|
||||
continue;
|
||||
|
||||
if( "com.formdev.flatlaf.ui.FlatWindowResizer".equals( c.getClass().getName() ) )
|
||||
continue;
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
||||
@@ -309,8 +312,9 @@ public class FlatInspector
|
||||
highlightFigure.setVisible( c != null );
|
||||
|
||||
if( c != null ) {
|
||||
Insets insets = rootPane.getInsets();
|
||||
highlightFigure.setBounds( new Rectangle(
|
||||
SwingUtilities.convertPoint( c, 0, 0, rootPane ),
|
||||
SwingUtilities.convertPoint( c, -insets.left, -insets.top, rootPane ),
|
||||
c.getSize() ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.FlatIconColors;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
@@ -164,8 +163,7 @@ public class FlatSVGIcon
|
||||
}
|
||||
|
||||
private static void lafChanged() {
|
||||
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
|
||||
darkLaf = (lookAndFeel instanceof FlatLaf && ((FlatLaf)lookAndFeel).isDark());
|
||||
darkLaf = FlatLaf.isLafDark();
|
||||
}
|
||||
|
||||
//---- class ColorFilter --------------------------------------------------
|
||||
|
||||
BIN
flatlaf-testing/Window Icon Test Images.sketch
Normal file
BIN
flatlaf-testing/Windows 10 decorations.png
Normal file
|
After Width: | Height: | Size: 105 KiB |
@@ -598,12 +598,7 @@ public class FlatDisabledIconsTest
|
||||
}
|
||||
|
||||
private ImageIcon getCurrentIcon() {
|
||||
return isDark() ? darkIcon : lightIcon;
|
||||
}
|
||||
|
||||
private boolean isDark() {
|
||||
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
|
||||
return lookAndFeel instanceof FlatLaf && ((FlatLaf)lookAndFeel).isDark();
|
||||
return FlatLaf.isLafDark() ? darkIcon : lightIcon;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.awt.Insets;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import com.formdev.flatlaf.FlatSystemProperties;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
import com.formdev.flatlaf.util.Graphics2DProxy;
|
||||
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||
@@ -40,7 +41,7 @@ public class FlatPaintingStringTest
|
||||
extends JPanel
|
||||
{
|
||||
public static void main( String[] args ) {
|
||||
System.setProperty( "flatlaf.uiScale", "1x" );
|
||||
System.setProperty( FlatSystemProperties.UI_SCALE, "1x" );
|
||||
System.setProperty( "sun.java2d.uiScale", "1x" );
|
||||
|
||||
SwingUtilities.invokeLater( () -> {
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.formdev.flatlaf.FlatDarkLaf;
|
||||
import com.formdev.flatlaf.FlatIntelliJLaf;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.FlatLightLaf;
|
||||
import com.formdev.flatlaf.FlatSystemProperties;
|
||||
import com.formdev.flatlaf.IntelliJTheme;
|
||||
import com.formdev.flatlaf.demo.LookAndFeelsComboBox;
|
||||
import com.formdev.flatlaf.demo.DemoPrefs;
|
||||
@@ -66,10 +67,10 @@ public class FlatTestFrame
|
||||
DemoPrefs.init( PREFS_ROOT_PATH );
|
||||
|
||||
// set scale factor
|
||||
if( System.getProperty( "flatlaf.uiScale", System.getProperty( "sun.java2d.uiScale" ) ) == null ) {
|
||||
if( System.getProperty( FlatSystemProperties.UI_SCALE, System.getProperty( "sun.java2d.uiScale" ) ) == null ) {
|
||||
String scaleFactor = DemoPrefs.getState().get( KEY_SCALE_FACTOR, null );
|
||||
if( scaleFactor != null )
|
||||
System.setProperty( "flatlaf.uiScale", scaleFactor );
|
||||
System.setProperty( FlatSystemProperties.UI_SCALE, scaleFactor );
|
||||
}
|
||||
|
||||
// set look and feel
|
||||
@@ -145,7 +146,7 @@ public class FlatTestFrame
|
||||
lookAndFeelComboBox.setModel( lafModel );
|
||||
|
||||
updateScaleFactorComboBox();
|
||||
String scaleFactor = System.getProperty( "flatlaf.uiScale", System.getProperty( "sun.java2d.uiScale" ) );
|
||||
String scaleFactor = System.getProperty( FlatSystemProperties.UI_SCALE, System.getProperty( "sun.java2d.uiScale" ) );
|
||||
if( scaleFactor != null )
|
||||
scaleFactorComboBox.setSelectedItem( scaleFactor );
|
||||
|
||||
@@ -399,8 +400,7 @@ public class FlatTestFrame
|
||||
boolean explicit = explicitColorsCheckBox.isSelected();
|
||||
ColorUIResource restoreColor = new ColorUIResource( Color.white );
|
||||
|
||||
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
|
||||
boolean dark = (lookAndFeel instanceof FlatLaf && ((FlatLaf)lookAndFeel).isDark());
|
||||
boolean dark = FlatLaf.isLafDark();
|
||||
Color magenta = dark ? Color.magenta.darker() : Color.magenta;
|
||||
Color orange = dark ? Color.orange.darker() : Color.orange;
|
||||
Color blue = dark ? Color.blue.darker() : Color.blue;
|
||||
@@ -473,10 +473,10 @@ public class FlatTestFrame
|
||||
scaleFactorComboBox.setPopupVisible( false );
|
||||
|
||||
if( scaleFactor != null ) {
|
||||
System.setProperty( "flatlaf.uiScale", scaleFactor );
|
||||
System.setProperty( FlatSystemProperties.UI_SCALE, scaleFactor );
|
||||
DemoPrefs.getState().put( KEY_SCALE_FACTOR, scaleFactor );
|
||||
} else {
|
||||
System.clearProperty( "flatlaf.uiScale" );
|
||||
System.clearProperty( FlatSystemProperties.UI_SCALE );
|
||||
DemoPrefs.getState().remove( KEY_SCALE_FACTOR );
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,627 @@
|
||||
/*
|
||||
* Copyright 2020 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.testing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.Dialog.ModalityType;
|
||||
import java.awt.event.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.swing.*;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import net.miginfocom.swing.*;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatWindowDecorationsTest
|
||||
extends FlatTestPanel
|
||||
{
|
||||
public static void main( String[] args ) {
|
||||
SwingUtilities.invokeLater( () -> {
|
||||
// enable custom window decoration (if LaF supports it)
|
||||
JFrame.setDefaultLookAndFeelDecorated( true );
|
||||
JDialog.setDefaultLookAndFeelDecorated( true );
|
||||
|
||||
FlatTestFrame frame = FlatTestFrame.create( args, "FlatWindowDecorationsTest" );
|
||||
|
||||
// WARNING: Do not this in real-world programs.
|
||||
// frame.setUndecorated( true );
|
||||
// frame.getRootPane().setWindowDecorationStyle( JRootPane.FRAME );
|
||||
|
||||
Class<?> cls = FlatWindowDecorationsTest.class;
|
||||
List<Image> images = Arrays.asList(
|
||||
new ImageIcon( cls.getResource( "/com/formdev/flatlaf/testing/test16.png" ) ).getImage(),
|
||||
new ImageIcon( cls.getResource( "/com/formdev/flatlaf/testing/test24.png" ) ).getImage(),
|
||||
new ImageIcon( cls.getResource( "/com/formdev/flatlaf/testing/test32.png" ) ).getImage(),
|
||||
new ImageIcon( cls.getResource( "/com/formdev/flatlaf/testing/test48.png" ) ).getImage(),
|
||||
new ImageIcon( cls.getResource( "/com/formdev/flatlaf/testing/test64.png" ) ).getImage(),
|
||||
new ImageIcon( cls.getResource( "/com/formdev/flatlaf/testing/test128.png" ) ).getImage()
|
||||
);
|
||||
// shuffle to test whether FlatLaf chooses the right size
|
||||
Collections.shuffle( images );
|
||||
frame.setIconImages( images );
|
||||
|
||||
frame.showFrame( FlatWindowDecorationsTest::new, panel -> ((FlatWindowDecorationsTest)panel).menuBar );
|
||||
} );
|
||||
}
|
||||
|
||||
private List<Image> images;
|
||||
|
||||
FlatWindowDecorationsTest() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNotify() {
|
||||
super.addNotify();
|
||||
|
||||
Window window = SwingUtilities.windowForComponent( this );
|
||||
menuBarCheckBox.setEnabled( window instanceof JFrame );
|
||||
menuBarEmbeddedCheckBox.setEnabled( window instanceof JFrame );
|
||||
maximizedBoundsCheckBox.setEnabled( window instanceof Frame );
|
||||
|
||||
boolean windowHasIcons = (window != null && !window.getIconImages().isEmpty());
|
||||
iconNoneRadioButton.setEnabled( windowHasIcons );
|
||||
iconTestAllRadioButton.setEnabled( windowHasIcons );
|
||||
iconTestRandomRadioButton.setEnabled( windowHasIcons );
|
||||
|
||||
if( window instanceof Frame )
|
||||
undecoratedCheckBox.setSelected( ((Frame)window).isUndecorated() );
|
||||
else if( window instanceof Dialog )
|
||||
undecoratedCheckBox.setSelected( ((Dialog)window).isUndecorated() );
|
||||
|
||||
JRootPane rootPane = getWindowRootPane();
|
||||
if( rootPane != null ) {
|
||||
int style = rootPane.getWindowDecorationStyle();
|
||||
if( style == JRootPane.NONE )
|
||||
styleNoneRadioButton.setSelected( true );
|
||||
else if( style == JRootPane.FRAME )
|
||||
styleFrameRadioButton.setSelected( true );
|
||||
else if( style == JRootPane.PLAIN_DIALOG )
|
||||
stylePlainRadioButton.setSelected( true );
|
||||
else if( style == JRootPane.INFORMATION_DIALOG )
|
||||
styleInfoRadioButton.setSelected( true );
|
||||
else
|
||||
throw new RuntimeException(); // not used
|
||||
}
|
||||
}
|
||||
|
||||
private void menuBarChanged() {
|
||||
Window window = SwingUtilities.windowForComponent( this );
|
||||
if( window instanceof JFrame ) {
|
||||
((JFrame)window).setJMenuBar( menuBarCheckBox.isSelected() ? menuBar : null );
|
||||
window.revalidate();
|
||||
window.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
private void menuBarEmbeddedChanged() {
|
||||
JRootPane rootPane = getWindowRootPane();
|
||||
if( rootPane != null )
|
||||
rootPane.putClientProperty( FlatClientProperties.MENU_BAR_EMBEDDED, menuBarEmbeddedCheckBox.isSelected() );
|
||||
}
|
||||
|
||||
private void resizableChanged() {
|
||||
Window window = SwingUtilities.windowForComponent( this );
|
||||
if( window instanceof Frame )
|
||||
((Frame)window).setResizable( resizableCheckBox.isSelected() );
|
||||
else if( window instanceof Dialog )
|
||||
((Dialog)window).setResizable( resizableCheckBox.isSelected() );
|
||||
}
|
||||
|
||||
private void undecoratedChanged() {
|
||||
Window window = SwingUtilities.windowForComponent( this );
|
||||
if( window == null )
|
||||
return;
|
||||
|
||||
window.dispose();
|
||||
|
||||
if( window instanceof Frame )
|
||||
((Frame)window).setUndecorated( undecoratedCheckBox.isSelected() );
|
||||
else if( window instanceof Dialog )
|
||||
((Dialog)window).setUndecorated( undecoratedCheckBox.isSelected() );
|
||||
|
||||
window.setVisible( true );
|
||||
}
|
||||
|
||||
private void maximizedBoundsChanged() {
|
||||
Window window = SwingUtilities.windowForComponent( this );
|
||||
if( window instanceof Frame ) {
|
||||
((Frame)window).setMaximizedBounds( maximizedBoundsCheckBox.isSelected()
|
||||
? new Rectangle( 50, 100, 1000, 700 )
|
||||
: null );
|
||||
}
|
||||
}
|
||||
|
||||
private void menuItemActionPerformed(ActionEvent e) {
|
||||
SwingUtilities.invokeLater( () -> {
|
||||
JOptionPane.showMessageDialog( this, e.getActionCommand(), "Menu Item", JOptionPane.PLAIN_MESSAGE );
|
||||
} );
|
||||
}
|
||||
|
||||
private void openDialog() {
|
||||
Window owner = SwingUtilities.windowForComponent( this );
|
||||
JDialog dialog = new JDialog( owner, "Dialog", ModalityType.APPLICATION_MODAL );
|
||||
dialog.add( new FlatWindowDecorationsTest() );
|
||||
dialog.pack();
|
||||
dialog.setLocationRelativeTo( this );
|
||||
dialog.setVisible( true );
|
||||
}
|
||||
|
||||
private void decorationStyleChanged() {
|
||||
int style;
|
||||
if( styleFrameRadioButton.isSelected() )
|
||||
style = JRootPane.FRAME;
|
||||
else if( stylePlainRadioButton.isSelected() )
|
||||
style = JRootPane.PLAIN_DIALOG;
|
||||
else if( styleInfoRadioButton.isSelected() )
|
||||
style = JRootPane.INFORMATION_DIALOG;
|
||||
else if( styleErrorRadioButton.isSelected() )
|
||||
style = JRootPane.ERROR_DIALOG;
|
||||
else if( styleQuestionRadioButton.isSelected() )
|
||||
style = JRootPane.QUESTION_DIALOG;
|
||||
else if( styleWarningRadioButton.isSelected() )
|
||||
style = JRootPane.WARNING_DIALOG;
|
||||
else if( styleColorChooserRadioButton.isSelected() )
|
||||
style = JRootPane.COLOR_CHOOSER_DIALOG;
|
||||
else if( styleFileChooserRadioButton.isSelected() )
|
||||
style = JRootPane.FILE_CHOOSER_DIALOG;
|
||||
else
|
||||
style = JRootPane.NONE;
|
||||
|
||||
JRootPane rootPane = getWindowRootPane();
|
||||
if( rootPane != null )
|
||||
rootPane.setWindowDecorationStyle( style );
|
||||
}
|
||||
|
||||
private void iconChanged() {
|
||||
Window window = SwingUtilities.windowForComponent( this );
|
||||
if( window == null )
|
||||
return;
|
||||
|
||||
if( images == null )
|
||||
images = window.getIconImages();
|
||||
|
||||
if( iconNoneRadioButton.isSelected() )
|
||||
window.setIconImage( null );
|
||||
else if( iconTestAllRadioButton.isSelected() )
|
||||
window.setIconImages( images );
|
||||
else if( iconTestRandomRadioButton.isSelected() )
|
||||
window.setIconImage( images.get( (int) (Math.random() * images.size()) ) );
|
||||
}
|
||||
|
||||
private JRootPane getWindowRootPane() {
|
||||
Window window = SwingUtilities.windowForComponent( this );
|
||||
if( window instanceof JFrame )
|
||||
return ((JFrame)window).getRootPane();
|
||||
else if( window instanceof JDialog )
|
||||
return ((JDialog)window).getRootPane();
|
||||
return null;
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||
menuBarCheckBox = new JCheckBox();
|
||||
menuBarEmbeddedCheckBox = new JCheckBox();
|
||||
resizableCheckBox = new JCheckBox();
|
||||
maximizedBoundsCheckBox = new JCheckBox();
|
||||
undecoratedCheckBox = new JCheckBox();
|
||||
JLabel label1 = new JLabel();
|
||||
JLabel label2 = new JLabel();
|
||||
JPanel panel1 = new JPanel();
|
||||
styleNoneRadioButton = new JRadioButton();
|
||||
styleFrameRadioButton = new JRadioButton();
|
||||
stylePlainRadioButton = new JRadioButton();
|
||||
styleInfoRadioButton = new JRadioButton();
|
||||
styleErrorRadioButton = new JRadioButton();
|
||||
styleQuestionRadioButton = new JRadioButton();
|
||||
styleWarningRadioButton = new JRadioButton();
|
||||
styleColorChooserRadioButton = new JRadioButton();
|
||||
styleFileChooserRadioButton = new JRadioButton();
|
||||
JPanel panel2 = new JPanel();
|
||||
iconNoneRadioButton = new JRadioButton();
|
||||
iconTestAllRadioButton = new JRadioButton();
|
||||
iconTestRandomRadioButton = new JRadioButton();
|
||||
JButton openDialogButton = new JButton();
|
||||
menuBar = new JMenuBar();
|
||||
JMenu fileMenu = new JMenu();
|
||||
JMenuItem newMenuItem = new JMenuItem();
|
||||
JMenuItem openMenuItem = new JMenuItem();
|
||||
JMenuItem closeMenuItem = new JMenuItem();
|
||||
JMenuItem closeMenuItem2 = new JMenuItem();
|
||||
JMenuItem exitMenuItem = new JMenuItem();
|
||||
JMenu editMenu = new JMenu();
|
||||
JMenuItem undoMenuItem = new JMenuItem();
|
||||
JMenuItem redoMenuItem = new JMenuItem();
|
||||
JMenuItem cutMenuItem = new JMenuItem();
|
||||
JMenuItem copyMenuItem = new JMenuItem();
|
||||
JMenuItem pasteMenuItem = new JMenuItem();
|
||||
JMenuItem deleteMenuItem = new JMenuItem();
|
||||
JMenu viewMenu = new JMenu();
|
||||
JCheckBoxMenuItem checkBoxMenuItem1 = new JCheckBoxMenuItem();
|
||||
JMenu menu1 = new JMenu();
|
||||
JMenu subViewsMenu = new JMenu();
|
||||
JMenu subSubViewsMenu = new JMenu();
|
||||
JMenuItem errorLogViewMenuItem = new JMenuItem();
|
||||
JMenuItem searchViewMenuItem = new JMenuItem();
|
||||
JMenuItem projectViewMenuItem = new JMenuItem();
|
||||
JMenuItem structureViewMenuItem = new JMenuItem();
|
||||
JMenuItem propertiesViewMenuItem = new JMenuItem();
|
||||
JMenu helpMenu = new JMenu();
|
||||
JMenuItem aboutMenuItem = new JMenuItem();
|
||||
|
||||
//======== this ========
|
||||
setLayout(new MigLayout(
|
||||
"ltr,insets dialog,hidemode 3",
|
||||
// columns
|
||||
"[left]para" +
|
||||
"[fill]",
|
||||
// rows
|
||||
"para[]0" +
|
||||
"[]0" +
|
||||
"[]0" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[top]" +
|
||||
"[]"));
|
||||
|
||||
//---- menuBarCheckBox ----
|
||||
menuBarCheckBox.setText("menu bar");
|
||||
menuBarCheckBox.setSelected(true);
|
||||
menuBarCheckBox.addActionListener(e -> menuBarChanged());
|
||||
add(menuBarCheckBox, "cell 0 0");
|
||||
|
||||
//---- menuBarEmbeddedCheckBox ----
|
||||
menuBarEmbeddedCheckBox.setText("embedded menu bar");
|
||||
menuBarEmbeddedCheckBox.setSelected(true);
|
||||
menuBarEmbeddedCheckBox.addActionListener(e -> menuBarEmbeddedChanged());
|
||||
add(menuBarEmbeddedCheckBox, "cell 0 1");
|
||||
|
||||
//---- resizableCheckBox ----
|
||||
resizableCheckBox.setText("resizable");
|
||||
resizableCheckBox.setSelected(true);
|
||||
resizableCheckBox.addActionListener(e -> resizableChanged());
|
||||
add(resizableCheckBox, "cell 0 2");
|
||||
|
||||
//---- maximizedBoundsCheckBox ----
|
||||
maximizedBoundsCheckBox.setText("maximized bounds (50,100, 1000,700)");
|
||||
maximizedBoundsCheckBox.addActionListener(e -> maximizedBoundsChanged());
|
||||
add(maximizedBoundsCheckBox, "cell 1 2");
|
||||
|
||||
//---- undecoratedCheckBox ----
|
||||
undecoratedCheckBox.setText("undecorated");
|
||||
undecoratedCheckBox.addActionListener(e -> undecoratedChanged());
|
||||
add(undecoratedCheckBox, "cell 0 3");
|
||||
|
||||
//---- label1 ----
|
||||
label1.setText("Style:");
|
||||
add(label1, "cell 0 4");
|
||||
|
||||
//---- label2 ----
|
||||
label2.setText("Icon:");
|
||||
add(label2, "cell 1 4");
|
||||
|
||||
//======== panel1 ========
|
||||
{
|
||||
panel1.setLayout(new MigLayout(
|
||||
"ltr,insets 0,hidemode 3,gap 0 0",
|
||||
// columns
|
||||
"[fill]",
|
||||
// rows
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]"));
|
||||
|
||||
//---- styleNoneRadioButton ----
|
||||
styleNoneRadioButton.setText("none");
|
||||
styleNoneRadioButton.addActionListener(e -> decorationStyleChanged());
|
||||
panel1.add(styleNoneRadioButton, "cell 0 0");
|
||||
|
||||
//---- styleFrameRadioButton ----
|
||||
styleFrameRadioButton.setText("frame");
|
||||
styleFrameRadioButton.setSelected(true);
|
||||
styleFrameRadioButton.addActionListener(e -> decorationStyleChanged());
|
||||
panel1.add(styleFrameRadioButton, "cell 0 1");
|
||||
|
||||
//---- stylePlainRadioButton ----
|
||||
stylePlainRadioButton.setText("plain dialog");
|
||||
stylePlainRadioButton.addActionListener(e -> decorationStyleChanged());
|
||||
panel1.add(stylePlainRadioButton, "cell 0 2");
|
||||
|
||||
//---- styleInfoRadioButton ----
|
||||
styleInfoRadioButton.setText("info dialog");
|
||||
styleInfoRadioButton.addActionListener(e -> decorationStyleChanged());
|
||||
panel1.add(styleInfoRadioButton, "cell 0 3");
|
||||
|
||||
//---- styleErrorRadioButton ----
|
||||
styleErrorRadioButton.setText("error dialog");
|
||||
styleErrorRadioButton.addActionListener(e -> decorationStyleChanged());
|
||||
panel1.add(styleErrorRadioButton, "cell 0 4");
|
||||
|
||||
//---- styleQuestionRadioButton ----
|
||||
styleQuestionRadioButton.setText("question dialog");
|
||||
styleQuestionRadioButton.addActionListener(e -> decorationStyleChanged());
|
||||
panel1.add(styleQuestionRadioButton, "cell 0 5");
|
||||
|
||||
//---- styleWarningRadioButton ----
|
||||
styleWarningRadioButton.setText("warning dialog");
|
||||
styleWarningRadioButton.addActionListener(e -> decorationStyleChanged());
|
||||
panel1.add(styleWarningRadioButton, "cell 0 6");
|
||||
|
||||
//---- styleColorChooserRadioButton ----
|
||||
styleColorChooserRadioButton.setText("color chooser dialog");
|
||||
styleColorChooserRadioButton.addActionListener(e -> decorationStyleChanged());
|
||||
panel1.add(styleColorChooserRadioButton, "cell 0 7");
|
||||
|
||||
//---- styleFileChooserRadioButton ----
|
||||
styleFileChooserRadioButton.setText("file chooser dialog");
|
||||
styleFileChooserRadioButton.addActionListener(e -> decorationStyleChanged());
|
||||
panel1.add(styleFileChooserRadioButton, "cell 0 8");
|
||||
}
|
||||
add(panel1, "cell 0 5");
|
||||
|
||||
//======== panel2 ========
|
||||
{
|
||||
panel2.setLayout(new MigLayout(
|
||||
"ltr,insets 0,hidemode 3,gap 0 0",
|
||||
// columns
|
||||
"[fill]",
|
||||
// rows
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]"));
|
||||
|
||||
//---- iconNoneRadioButton ----
|
||||
iconNoneRadioButton.setText("none");
|
||||
iconNoneRadioButton.addActionListener(e -> iconChanged());
|
||||
panel2.add(iconNoneRadioButton, "cell 0 0");
|
||||
|
||||
//---- iconTestAllRadioButton ----
|
||||
iconTestAllRadioButton.setText("test all");
|
||||
iconTestAllRadioButton.setSelected(true);
|
||||
iconTestAllRadioButton.addActionListener(e -> iconChanged());
|
||||
panel2.add(iconTestAllRadioButton, "cell 0 1");
|
||||
|
||||
//---- iconTestRandomRadioButton ----
|
||||
iconTestRandomRadioButton.setText("test random");
|
||||
iconTestRandomRadioButton.addActionListener(e -> iconChanged());
|
||||
panel2.add(iconTestRandomRadioButton, "cell 0 2");
|
||||
}
|
||||
add(panel2, "cell 1 5");
|
||||
|
||||
//---- openDialogButton ----
|
||||
openDialogButton.setText("Open Dialog");
|
||||
openDialogButton.addActionListener(e -> openDialog());
|
||||
add(openDialogButton, "cell 0 6");
|
||||
|
||||
//======== menuBar ========
|
||||
{
|
||||
|
||||
//======== fileMenu ========
|
||||
{
|
||||
fileMenu.setText("File");
|
||||
fileMenu.setMnemonic('F');
|
||||
|
||||
//---- newMenuItem ----
|
||||
newMenuItem.setText("New");
|
||||
newMenuItem.setMnemonic('N');
|
||||
newMenuItem.addActionListener(e -> menuItemActionPerformed(e));
|
||||
fileMenu.add(newMenuItem);
|
||||
|
||||
//---- openMenuItem ----
|
||||
openMenuItem.setText("Open");
|
||||
openMenuItem.setMnemonic('O');
|
||||
openMenuItem.addActionListener(e -> menuItemActionPerformed(e));
|
||||
fileMenu.add(openMenuItem);
|
||||
fileMenu.addSeparator();
|
||||
|
||||
//---- closeMenuItem ----
|
||||
closeMenuItem.setText("Close");
|
||||
closeMenuItem.setMnemonic('C');
|
||||
closeMenuItem.addActionListener(e -> menuItemActionPerformed(e));
|
||||
fileMenu.add(closeMenuItem);
|
||||
|
||||
//---- closeMenuItem2 ----
|
||||
closeMenuItem2.setText("Close All");
|
||||
closeMenuItem2.addActionListener(e -> menuItemActionPerformed(e));
|
||||
fileMenu.add(closeMenuItem2);
|
||||
fileMenu.addSeparator();
|
||||
|
||||
//---- exitMenuItem ----
|
||||
exitMenuItem.setText("Exit");
|
||||
exitMenuItem.setMnemonic('X');
|
||||
exitMenuItem.addActionListener(e -> menuItemActionPerformed(e));
|
||||
fileMenu.add(exitMenuItem);
|
||||
}
|
||||
menuBar.add(fileMenu);
|
||||
|
||||
//======== editMenu ========
|
||||
{
|
||||
editMenu.setText("Edit");
|
||||
editMenu.setMnemonic('E');
|
||||
|
||||
//---- undoMenuItem ----
|
||||
undoMenuItem.setText("Undo");
|
||||
undoMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||
undoMenuItem.setMnemonic('U');
|
||||
undoMenuItem.addActionListener(e -> menuItemActionPerformed(e));
|
||||
editMenu.add(undoMenuItem);
|
||||
|
||||
//---- redoMenuItem ----
|
||||
redoMenuItem.setText("Redo");
|
||||
redoMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||
redoMenuItem.setMnemonic('R');
|
||||
redoMenuItem.addActionListener(e -> menuItemActionPerformed(e));
|
||||
editMenu.add(redoMenuItem);
|
||||
editMenu.addSeparator();
|
||||
|
||||
//---- cutMenuItem ----
|
||||
cutMenuItem.setText("Cut");
|
||||
cutMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||
cutMenuItem.setMnemonic('C');
|
||||
editMenu.add(cutMenuItem);
|
||||
|
||||
//---- copyMenuItem ----
|
||||
copyMenuItem.setText("Copy");
|
||||
copyMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||
copyMenuItem.setMnemonic('O');
|
||||
editMenu.add(copyMenuItem);
|
||||
|
||||
//---- pasteMenuItem ----
|
||||
pasteMenuItem.setText("Paste");
|
||||
pasteMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||
pasteMenuItem.setMnemonic('P');
|
||||
editMenu.add(pasteMenuItem);
|
||||
editMenu.addSeparator();
|
||||
|
||||
//---- deleteMenuItem ----
|
||||
deleteMenuItem.setText("Delete");
|
||||
deleteMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
|
||||
deleteMenuItem.setMnemonic('D');
|
||||
deleteMenuItem.addActionListener(e -> menuItemActionPerformed(e));
|
||||
editMenu.add(deleteMenuItem);
|
||||
}
|
||||
menuBar.add(editMenu);
|
||||
|
||||
//======== viewMenu ========
|
||||
{
|
||||
viewMenu.setText("View");
|
||||
viewMenu.setMnemonic('V');
|
||||
|
||||
//---- checkBoxMenuItem1 ----
|
||||
checkBoxMenuItem1.setText("Show Toolbar");
|
||||
checkBoxMenuItem1.setSelected(true);
|
||||
checkBoxMenuItem1.setMnemonic('T');
|
||||
checkBoxMenuItem1.addActionListener(e -> menuItemActionPerformed(e));
|
||||
viewMenu.add(checkBoxMenuItem1);
|
||||
|
||||
//======== menu1 ========
|
||||
{
|
||||
menu1.setText("Show View");
|
||||
menu1.setMnemonic('V');
|
||||
|
||||
//======== subViewsMenu ========
|
||||
{
|
||||
subViewsMenu.setText("Sub Views");
|
||||
subViewsMenu.setMnemonic('S');
|
||||
|
||||
//======== subSubViewsMenu ========
|
||||
{
|
||||
subSubViewsMenu.setText("Sub sub Views");
|
||||
subSubViewsMenu.setMnemonic('U');
|
||||
|
||||
//---- errorLogViewMenuItem ----
|
||||
errorLogViewMenuItem.setText("Error Log");
|
||||
errorLogViewMenuItem.setMnemonic('E');
|
||||
errorLogViewMenuItem.addActionListener(e -> menuItemActionPerformed(e));
|
||||
subSubViewsMenu.add(errorLogViewMenuItem);
|
||||
}
|
||||
subViewsMenu.add(subSubViewsMenu);
|
||||
|
||||
//---- searchViewMenuItem ----
|
||||
searchViewMenuItem.setText("Search");
|
||||
searchViewMenuItem.setMnemonic('S');
|
||||
searchViewMenuItem.addActionListener(e -> menuItemActionPerformed(e));
|
||||
subViewsMenu.add(searchViewMenuItem);
|
||||
}
|
||||
menu1.add(subViewsMenu);
|
||||
|
||||
//---- projectViewMenuItem ----
|
||||
projectViewMenuItem.setText("Project");
|
||||
projectViewMenuItem.setMnemonic('P');
|
||||
projectViewMenuItem.addActionListener(e -> menuItemActionPerformed(e));
|
||||
menu1.add(projectViewMenuItem);
|
||||
|
||||
//---- structureViewMenuItem ----
|
||||
structureViewMenuItem.setText("Structure");
|
||||
structureViewMenuItem.setMnemonic('T');
|
||||
structureViewMenuItem.addActionListener(e -> menuItemActionPerformed(e));
|
||||
menu1.add(structureViewMenuItem);
|
||||
|
||||
//---- propertiesViewMenuItem ----
|
||||
propertiesViewMenuItem.setText("Properties");
|
||||
propertiesViewMenuItem.setMnemonic('O');
|
||||
propertiesViewMenuItem.addActionListener(e -> menuItemActionPerformed(e));
|
||||
menu1.add(propertiesViewMenuItem);
|
||||
}
|
||||
viewMenu.add(menu1);
|
||||
}
|
||||
menuBar.add(viewMenu);
|
||||
|
||||
//======== helpMenu ========
|
||||
{
|
||||
helpMenu.setText("Help");
|
||||
helpMenu.setMnemonic('H');
|
||||
|
||||
//---- aboutMenuItem ----
|
||||
aboutMenuItem.setText("About");
|
||||
aboutMenuItem.setMnemonic('A');
|
||||
aboutMenuItem.addActionListener(e -> menuItemActionPerformed(e));
|
||||
helpMenu.add(aboutMenuItem);
|
||||
}
|
||||
menuBar.add(helpMenu);
|
||||
}
|
||||
|
||||
//---- styleButtonGroup ----
|
||||
ButtonGroup styleButtonGroup = new ButtonGroup();
|
||||
styleButtonGroup.add(styleNoneRadioButton);
|
||||
styleButtonGroup.add(styleFrameRadioButton);
|
||||
styleButtonGroup.add(stylePlainRadioButton);
|
||||
styleButtonGroup.add(styleInfoRadioButton);
|
||||
styleButtonGroup.add(styleErrorRadioButton);
|
||||
styleButtonGroup.add(styleQuestionRadioButton);
|
||||
styleButtonGroup.add(styleWarningRadioButton);
|
||||
styleButtonGroup.add(styleColorChooserRadioButton);
|
||||
styleButtonGroup.add(styleFileChooserRadioButton);
|
||||
|
||||
//---- iconButtonGroup ----
|
||||
ButtonGroup iconButtonGroup = new ButtonGroup();
|
||||
iconButtonGroup.add(iconNoneRadioButton);
|
||||
iconButtonGroup.add(iconTestAllRadioButton);
|
||||
iconButtonGroup.add(iconTestRandomRadioButton);
|
||||
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||
}
|
||||
|
||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||
private JCheckBox menuBarCheckBox;
|
||||
private JCheckBox menuBarEmbeddedCheckBox;
|
||||
private JCheckBox resizableCheckBox;
|
||||
private JCheckBox maximizedBoundsCheckBox;
|
||||
private JCheckBox undecoratedCheckBox;
|
||||
private JRadioButton styleNoneRadioButton;
|
||||
private JRadioButton styleFrameRadioButton;
|
||||
private JRadioButton stylePlainRadioButton;
|
||||
private JRadioButton styleInfoRadioButton;
|
||||
private JRadioButton styleErrorRadioButton;
|
||||
private JRadioButton styleQuestionRadioButton;
|
||||
private JRadioButton styleWarningRadioButton;
|
||||
private JRadioButton styleColorChooserRadioButton;
|
||||
private JRadioButton styleFileChooserRadioButton;
|
||||
private JRadioButton iconNoneRadioButton;
|
||||
private JRadioButton iconTestAllRadioButton;
|
||||
private JRadioButton iconTestRandomRadioButton;
|
||||
private JMenuBar menuBar;
|
||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||
}
|
||||
@@ -0,0 +1,421 @@
|
||||
JFDML JFormDesigner: "7.0.2.0.298" Java: "13.0.2" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
root: new FormRoot {
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.defaultVariableLocal": true
|
||||
}
|
||||
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
|
||||
"$columnConstraints": "[left]para[fill]"
|
||||
"$rowConstraints": "para[]0[]0[]0[][][top][]"
|
||||
} ) {
|
||||
name: "this"
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "menuBarCheckBox"
|
||||
"text": "menu bar"
|
||||
"selected": true
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuBarChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "menuBarEmbeddedCheckBox"
|
||||
"text": "embedded menu bar"
|
||||
"selected": true
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuBarEmbeddedChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "resizableCheckBox"
|
||||
"text": "resizable"
|
||||
"selected": true
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "resizableChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 2"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "maximizedBoundsCheckBox"
|
||||
"text": "maximized bounds (50,100, 1000,700)"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "maximizedBoundsChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 2"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "undecoratedCheckBox"
|
||||
"text": "undecorated"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "undecoratedChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 3"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label1"
|
||||
"text": "Style:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 4"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label2"
|
||||
"text": "Icon:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 4"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$columnConstraints": "[fill]"
|
||||
"$rowConstraints": "[][][][][][][][][]"
|
||||
"$layoutConstraints": "ltr,insets 0,hidemode 3,gap 0 0"
|
||||
} ) {
|
||||
name: "panel1"
|
||||
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||
name: "styleNoneRadioButton"
|
||||
"text": "none"
|
||||
"$buttonGroup": new FormReference( "styleButtonGroup" )
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "decorationStyleChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||
name: "styleFrameRadioButton"
|
||||
"text": "frame"
|
||||
"$buttonGroup": new FormReference( "styleButtonGroup" )
|
||||
"selected": true
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "decorationStyleChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||
name: "stylePlainRadioButton"
|
||||
"text": "plain dialog"
|
||||
"$buttonGroup": new FormReference( "styleButtonGroup" )
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "decorationStyleChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 2"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||
name: "styleInfoRadioButton"
|
||||
"text": "info dialog"
|
||||
"$buttonGroup": new FormReference( "styleButtonGroup" )
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "decorationStyleChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 3"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||
name: "styleErrorRadioButton"
|
||||
"text": "error dialog"
|
||||
"$buttonGroup": new FormReference( "styleButtonGroup" )
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "decorationStyleChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 4"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||
name: "styleQuestionRadioButton"
|
||||
"text": "question dialog"
|
||||
"$buttonGroup": new FormReference( "styleButtonGroup" )
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "decorationStyleChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 5"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||
name: "styleWarningRadioButton"
|
||||
"text": "warning dialog"
|
||||
"$buttonGroup": new FormReference( "styleButtonGroup" )
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "decorationStyleChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 6"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||
name: "styleColorChooserRadioButton"
|
||||
"text": "color chooser dialog"
|
||||
"$buttonGroup": new FormReference( "styleButtonGroup" )
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "decorationStyleChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 7"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||
name: "styleFileChooserRadioButton"
|
||||
"text": "file chooser dialog"
|
||||
"$buttonGroup": new FormReference( "styleButtonGroup" )
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "decorationStyleChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 8"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 5"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$columnConstraints": "[fill]"
|
||||
"$rowConstraints": "[][][]"
|
||||
"$layoutConstraints": "ltr,insets 0,hidemode 3,gap 0 0"
|
||||
} ) {
|
||||
name: "panel2"
|
||||
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||
name: "iconNoneRadioButton"
|
||||
"text": "none"
|
||||
"$buttonGroup": new FormReference( "iconButtonGroup" )
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "iconChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||
name: "iconTestAllRadioButton"
|
||||
"text": "test all"
|
||||
"selected": true
|
||||
"$buttonGroup": new FormReference( "iconButtonGroup" )
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "iconChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||
name: "iconTestRandomRadioButton"
|
||||
"text": "test random"
|
||||
"$buttonGroup": new FormReference( "iconButtonGroup" )
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "iconChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 2"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 5"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "openDialogButton"
|
||||
"text": "Open Dialog"
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "openDialog", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 6"
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 0 )
|
||||
"size": new java.awt.Dimension( 450, 380 )
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JMenuBar", new FormLayoutManager( class javax.swing.JMenuBar ) ) {
|
||||
name: "menuBar"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||
name: "fileMenu"
|
||||
"text": "File"
|
||||
"mnemonic": 70
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "newMenuItem"
|
||||
"text": "New"
|
||||
"mnemonic": 78
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "openMenuItem"
|
||||
"text": "Open"
|
||||
"mnemonic": 79
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) {
|
||||
name: "separator2"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "closeMenuItem"
|
||||
"text": "Close"
|
||||
"mnemonic": 67
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "closeMenuItem2"
|
||||
"text": "Close All"
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) {
|
||||
name: "separator1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "exitMenuItem"
|
||||
"text": "Exit"
|
||||
"mnemonic": 88
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
} )
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||
name: "editMenu"
|
||||
"text": "Edit"
|
||||
"mnemonic": 69
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "undoMenuItem"
|
||||
"text": "Undo"
|
||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 90, 4226, false )
|
||||
"mnemonic": 85
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "redoMenuItem"
|
||||
"text": "Redo"
|
||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 89, 4226, false )
|
||||
"mnemonic": 82
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) {
|
||||
name: "separator4"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "cutMenuItem"
|
||||
"text": "Cut"
|
||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 88, 4226, false )
|
||||
"mnemonic": 67
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "copyMenuItem"
|
||||
"text": "Copy"
|
||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 67, 4226, false )
|
||||
"mnemonic": 79
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "pasteMenuItem"
|
||||
"text": "Paste"
|
||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 86, 4226, false )
|
||||
"mnemonic": 80
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) {
|
||||
name: "separator3"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "deleteMenuItem"
|
||||
"text": "Delete"
|
||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 127, 0, false )
|
||||
"mnemonic": 68
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
} )
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||
name: "viewMenu"
|
||||
"text": "View"
|
||||
"mnemonic": 86
|
||||
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
|
||||
name: "checkBoxMenuItem1"
|
||||
"text": "Show Toolbar"
|
||||
"selected": true
|
||||
"mnemonic": 84
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||
name: "menu1"
|
||||
"text": "Show View"
|
||||
"mnemonic": 86
|
||||
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||
name: "subViewsMenu"
|
||||
"text": "Sub Views"
|
||||
"mnemonic": 83
|
||||
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||
name: "subSubViewsMenu"
|
||||
"text": "Sub sub Views"
|
||||
"mnemonic": 85
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "errorLogViewMenuItem"
|
||||
"text": "Error Log"
|
||||
"mnemonic": 69
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
} )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "searchViewMenuItem"
|
||||
"text": "Search"
|
||||
"mnemonic": 83
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
} )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "projectViewMenuItem"
|
||||
"text": "Project"
|
||||
"mnemonic": 80
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "structureViewMenuItem"
|
||||
"text": "Structure"
|
||||
"mnemonic": 84
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "propertiesViewMenuItem"
|
||||
"text": "Properties"
|
||||
"mnemonic": 79
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
} )
|
||||
} )
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||
name: "helpMenu"
|
||||
"text": "Help"
|
||||
"mnemonic": 72
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "aboutMenuItem"
|
||||
"text": "About"
|
||||
"mnemonic": 65
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
} )
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 410 )
|
||||
"size": new java.awt.Dimension( 255, 30 )
|
||||
} )
|
||||
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
||||
name: "styleButtonGroup"
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 450 )
|
||||
} )
|
||||
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
||||
name: "iconButtonGroup"
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 502 )
|
||||
} )
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,7 @@ public class UIDefaultsDump
|
||||
public static void main( String[] args ) {
|
||||
Locale.setDefault( Locale.ENGLISH );
|
||||
System.setProperty( "sun.java2d.uiScale", "1x" );
|
||||
System.setProperty( "flatlaf.uiScale", "1x" );
|
||||
System.setProperty( FlatSystemProperties.UI_SCALE, "1x" );
|
||||
|
||||
File dir = new File( "src/main/resources/com/formdev/flatlaf/testing/uidefaults" );
|
||||
|
||||
|
||||
@@ -316,6 +316,14 @@ TitledBorder.titleColor=#ff00ff
|
||||
TitledBorder.border=1,1,1,1,#ff00ff
|
||||
|
||||
|
||||
#---- TitlePane ----
|
||||
|
||||
TitlePane.background=#0f0
|
||||
TitlePane.inactiveBackground=#080
|
||||
TitlePane.foreground=#00f
|
||||
TitlePane.inactiveForeground=#fff
|
||||
|
||||
|
||||
#---- ToggleButton ----
|
||||
|
||||
ToggleButton.background=#ddddff
|
||||
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 428 B |
|
After Width: | Height: | Size: 624 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
@@ -752,6 +752,9 @@ Resizable.resizeBorder [lazy] 4,4,4,4 false com.formdev.flatlaf.ui.F
|
||||
|
||||
#---- RootPane ----
|
||||
|
||||
RootPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatRootPaneUI$FlatWindowBorder [UI]
|
||||
RootPane.borderDragThickness 5
|
||||
RootPane.cornerDragWidth 16
|
||||
RootPane.defaultButtonWindowKeyBindings length=8 [Ljava.lang.Object;
|
||||
[0] ENTER
|
||||
[1] press
|
||||
@@ -761,6 +764,7 @@ RootPane.defaultButtonWindowKeyBindings length=8 [Ljava.lang.Object;
|
||||
[5] press
|
||||
[6] ctrl released ENTER
|
||||
[7] release
|
||||
RootPane.honorMinimumSizeOnResize true
|
||||
RootPaneUI com.formdev.flatlaf.ui.FlatRootPaneUI
|
||||
|
||||
|
||||
@@ -1052,6 +1056,32 @@ TextPane.selectionForeground #bbbbbb javax.swing.plaf.ColorUIResource [UI]
|
||||
TextPaneUI com.formdev.flatlaf.ui.FlatTextPaneUI
|
||||
|
||||
|
||||
#---- TitlePane ----
|
||||
|
||||
TitlePane.background #303234 javax.swing.plaf.ColorUIResource [UI]
|
||||
TitlePane.buttonHoverBackground #484c4f com.formdev.flatlaf.util.DerivedColor [UI] lighten(10% autoInverse)
|
||||
TitlePane.buttonMaximizedHeight 22
|
||||
TitlePane.buttonPressedBackground #616569 com.formdev.flatlaf.util.DerivedColor [UI] lighten(20% autoInverse)
|
||||
TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI]
|
||||
TitlePane.closeHoverBackground #e81123 javax.swing.plaf.ColorUIResource [UI]
|
||||
TitlePane.closeHoverForeground #ffffff javax.swing.plaf.ColorUIResource [UI]
|
||||
TitlePane.closeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI]
|
||||
TitlePane.closePressedBackground #99e81123 javax.swing.plaf.ColorUIResource [UI]
|
||||
TitlePane.closePressedForeground #ffffff javax.swing.plaf.ColorUIResource [UI]
|
||||
TitlePane.embeddedForeground #959595 javax.swing.plaf.ColorUIResource [UI]
|
||||
TitlePane.foreground #bbbbbb javax.swing.plaf.ColorUIResource [UI]
|
||||
TitlePane.iconMargins 3,8,3,0 javax.swing.plaf.InsetsUIResource [UI]
|
||||
TitlePane.iconSize 16,16 javax.swing.plaf.DimensionUIResource [UI]
|
||||
TitlePane.iconifyIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowIconifyIcon [UI]
|
||||
TitlePane.inactiveBackground #303234 javax.swing.plaf.ColorUIResource [UI]
|
||||
TitlePane.inactiveForeground #777777 javax.swing.plaf.ColorUIResource [UI]
|
||||
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
|
||||
TitlePane.menuBarEmbedded true
|
||||
TitlePane.menuBarMargins 0,8,0,22 javax.swing.plaf.InsetsUIResource [UI]
|
||||
TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
|
||||
TitlePane.titleMargins 3,8,3,8 javax.swing.plaf.InsetsUIResource [UI]
|
||||
|
||||
|
||||
#---- TitledBorder ----
|
||||
|
||||
TitledBorder.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatLineBorder [UI] lineColor=#515151 javax.swing.plaf.ColorUIResource [UI] lineThickness=1.000000
|
||||
|
||||
@@ -757,6 +757,9 @@ Resizable.resizeBorder [lazy] 4,4,4,4 false com.formdev.flatlaf.ui.F
|
||||
|
||||
#---- RootPane ----
|
||||
|
||||
RootPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatRootPaneUI$FlatWindowBorder [UI]
|
||||
RootPane.borderDragThickness 5
|
||||
RootPane.cornerDragWidth 16
|
||||
RootPane.defaultButtonWindowKeyBindings length=8 [Ljava.lang.Object;
|
||||
[0] ENTER
|
||||
[1] press
|
||||
@@ -766,6 +769,7 @@ RootPane.defaultButtonWindowKeyBindings length=8 [Ljava.lang.Object;
|
||||
[5] press
|
||||
[6] ctrl released ENTER
|
||||
[7] release
|
||||
RootPane.honorMinimumSizeOnResize true
|
||||
RootPaneUI com.formdev.flatlaf.ui.FlatRootPaneUI
|
||||
|
||||
|
||||
@@ -1057,6 +1061,32 @@ TextPane.selectionForeground #ffffff javax.swing.plaf.ColorUIResource [UI]
|
||||
TextPaneUI com.formdev.flatlaf.ui.FlatTextPaneUI
|
||||
|
||||
|
||||
#---- TitlePane ----
|
||||
|
||||
TitlePane.background #ffffff javax.swing.plaf.ColorUIResource [UI]
|
||||
TitlePane.buttonHoverBackground #e6e6e6 com.formdev.flatlaf.util.DerivedColor [UI] darken(10% autoInverse)
|
||||
TitlePane.buttonMaximizedHeight 22
|
||||
TitlePane.buttonPressedBackground #cccccc com.formdev.flatlaf.util.DerivedColor [UI] darken(20% autoInverse)
|
||||
TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI]
|
||||
TitlePane.closeHoverBackground #e81123 javax.swing.plaf.ColorUIResource [UI]
|
||||
TitlePane.closeHoverForeground #ffffff javax.swing.plaf.ColorUIResource [UI]
|
||||
TitlePane.closeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI]
|
||||
TitlePane.closePressedBackground #99e81123 javax.swing.plaf.ColorUIResource [UI]
|
||||
TitlePane.closePressedForeground #ffffff javax.swing.plaf.ColorUIResource [UI]
|
||||
TitlePane.embeddedForeground #595959 javax.swing.plaf.ColorUIResource [UI]
|
||||
TitlePane.foreground #000000 javax.swing.plaf.ColorUIResource [UI]
|
||||
TitlePane.iconMargins 3,8,3,0 javax.swing.plaf.InsetsUIResource [UI]
|
||||
TitlePane.iconSize 16,16 javax.swing.plaf.DimensionUIResource [UI]
|
||||
TitlePane.iconifyIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowIconifyIcon [UI]
|
||||
TitlePane.inactiveBackground #ffffff javax.swing.plaf.ColorUIResource [UI]
|
||||
TitlePane.inactiveForeground #8c8c8c javax.swing.plaf.ColorUIResource [UI]
|
||||
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
|
||||
TitlePane.menuBarEmbedded true
|
||||
TitlePane.menuBarMargins 0,8,0,22 javax.swing.plaf.InsetsUIResource [UI]
|
||||
TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
|
||||
TitlePane.titleMargins 3,8,3,8 javax.swing.plaf.InsetsUIResource [UI]
|
||||
|
||||
|
||||
#---- TitledBorder ----
|
||||
|
||||
TitledBorder.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatLineBorder [UI] lineColor=#d1d1d1 javax.swing.plaf.ColorUIResource [UI] lineThickness=1.000000
|
||||
|
||||