mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 14:00:55 +03:00
Styling: fixed styling protected JRE fields using @StyleableField annotation (regression in commit ff00a6c0f0)
This commit is contained in:
@@ -19,6 +19,7 @@ package com.formdev.flatlaf.ui;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.Map;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
@@ -27,6 +28,7 @@ import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicCheckBoxMenuItemUI;
|
||||
import javax.swing.plaf.basic.BasicMenuItemUI;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableField;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableLookupProvider;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
|
||||
@@ -66,7 +68,7 @@ import com.formdev.flatlaf.util.LoggingFacade;
|
||||
|
||||
public class FlatCheckBoxMenuItemUI
|
||||
extends BasicCheckBoxMenuItemUI
|
||||
implements StyleableUI
|
||||
implements StyleableUI, StyleableLookupProvider
|
||||
{
|
||||
private FlatMenuItemRenderer renderer;
|
||||
private Map<String, Object> oldStyleValues;
|
||||
@@ -140,6 +142,14 @@ public class FlatCheckBoxMenuItemUI
|
||||
return FlatMenuItemUI.getStyleableValue( this, renderer, key );
|
||||
}
|
||||
|
||||
/** @since 2.5 */
|
||||
@Override
|
||||
public MethodHandles.Lookup getLookupForStyling() {
|
||||
// MethodHandles.lookup() is caller sensitive and must be invoked in this class,
|
||||
// otherwise it is not possible to access protected fields in JRE superclass
|
||||
return MethodHandles.lookup();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dimension getPreferredMenuItemSize( JComponent c, Icon checkIcon, Icon arrowIcon, int defaultTextIconGap ) {
|
||||
return renderer.getPreferredMenuItemSize();
|
||||
|
||||
@@ -42,6 +42,7 @@ import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import javax.swing.AbstractAction;
|
||||
@@ -71,6 +72,7 @@ import javax.swing.plaf.basic.ComboPopup;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableField;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableLookupProvider;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
@@ -122,7 +124,7 @@ import com.formdev.flatlaf.util.SystemInfo;
|
||||
|
||||
public class FlatComboBoxUI
|
||||
extends BasicComboBoxUI
|
||||
implements StyleableUI
|
||||
implements StyleableUI, StyleableLookupProvider
|
||||
{
|
||||
@Styleable protected int minimumWidth;
|
||||
@Styleable protected int editorColumns;
|
||||
@@ -511,6 +513,14 @@ public class FlatComboBoxUI
|
||||
return FlatStylingSupport.getAnnotatedStyleableValue( this, comboBox.getBorder(), key );
|
||||
}
|
||||
|
||||
/** @since 2.5 */
|
||||
@Override
|
||||
public MethodHandles.Lookup getLookupForStyling() {
|
||||
// MethodHandles.lookup() is caller sensitive and must be invoked in this class,
|
||||
// otherwise it is not possible to access protected fields in JRE superclass
|
||||
return MethodHandles.lookup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update( Graphics g, JComponent c ) {
|
||||
float focusWidth = FlatUIUtils.getBorderFocusWidth( c );
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.formdev.flatlaf.ui;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.Map;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
@@ -27,6 +28,7 @@ import javax.swing.LookAndFeel;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicMenuItemUI;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableField;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableLookupProvider;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.UnknownStyleException;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
@@ -67,7 +69,7 @@ import com.formdev.flatlaf.util.LoggingFacade;
|
||||
|
||||
public class FlatMenuItemUI
|
||||
extends BasicMenuItemUI
|
||||
implements StyleableUI
|
||||
implements StyleableUI, StyleableLookupProvider
|
||||
{
|
||||
private FlatMenuItemRenderer renderer;
|
||||
private Map<String, Object> oldStyleValues;
|
||||
@@ -166,6 +168,14 @@ public class FlatMenuItemUI
|
||||
return value;
|
||||
}
|
||||
|
||||
/** @since 2.5 */
|
||||
@Override
|
||||
public MethodHandles.Lookup getLookupForStyling() {
|
||||
// MethodHandles.lookup() is caller sensitive and must be invoked in this class,
|
||||
// otherwise it is not possible to access protected fields in JRE superclass
|
||||
return MethodHandles.lookup();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dimension getPreferredMenuItemSize( JComponent c, Icon checkIcon, Icon arrowIcon, int defaultTextIconGap ) {
|
||||
return renderer.getPreferredMenuItemSize();
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import javax.swing.ButtonModel;
|
||||
@@ -38,6 +39,7 @@ import javax.swing.plaf.MenuBarUI;
|
||||
import javax.swing.plaf.basic.BasicMenuItemUI;
|
||||
import javax.swing.plaf.basic.BasicMenuUI;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableField;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableLookupProvider;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
|
||||
@@ -87,7 +89,7 @@ import com.formdev.flatlaf.util.LoggingFacade;
|
||||
|
||||
public class FlatMenuUI
|
||||
extends BasicMenuUI
|
||||
implements StyleableUI
|
||||
implements StyleableUI, StyleableLookupProvider
|
||||
{
|
||||
private FlatMenuItemRenderer renderer;
|
||||
private Map<String, Object> oldStyleValues;
|
||||
@@ -188,6 +190,14 @@ public class FlatMenuUI
|
||||
return FlatMenuItemUI.getStyleableValue( this, renderer, key );
|
||||
}
|
||||
|
||||
/** @since 2.5 */
|
||||
@Override
|
||||
public MethodHandles.Lookup getLookupForStyling() {
|
||||
// MethodHandles.lookup() is caller sensitive and must be invoked in this class,
|
||||
// otherwise it is not possible to access protected fields in JRE superclass
|
||||
return MethodHandles.lookup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize( JComponent c ) {
|
||||
// avoid that top-level menus (in menu bar) are made smaller if horizontal space is rare
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.formdev.flatlaf.ui;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.Map;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
@@ -27,6 +28,7 @@ import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicMenuItemUI;
|
||||
import javax.swing.plaf.basic.BasicRadioButtonMenuItemUI;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableField;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableLookupProvider;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
|
||||
@@ -66,7 +68,7 @@ import com.formdev.flatlaf.util.LoggingFacade;
|
||||
|
||||
public class FlatRadioButtonMenuItemUI
|
||||
extends BasicRadioButtonMenuItemUI
|
||||
implements StyleableUI
|
||||
implements StyleableUI, StyleableLookupProvider
|
||||
{
|
||||
private FlatMenuItemRenderer renderer;
|
||||
private Map<String, Object> oldStyleValues;
|
||||
@@ -140,6 +142,14 @@ public class FlatRadioButtonMenuItemUI
|
||||
return FlatMenuItemUI.getStyleableValue( this, renderer, key );
|
||||
}
|
||||
|
||||
/** @since 2.5 */
|
||||
@Override
|
||||
public MethodHandles.Lookup getLookupForStyling() {
|
||||
// MethodHandles.lookup() is caller sensitive and must be invoked in this class,
|
||||
// otherwise it is not possible to access protected fields in JRE superclass
|
||||
return MethodHandles.lookup();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dimension getPreferredMenuItemSize( JComponent c, Icon checkIcon, Icon arrowIcon, int defaultTextIconGap ) {
|
||||
return renderer.getPreferredMenuItemSize();
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.awt.Rectangle;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import javax.swing.InputMap;
|
||||
@@ -38,6 +39,7 @@ import javax.swing.plaf.basic.BasicScrollBarUI;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableField;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableLookupProvider;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
@@ -86,7 +88,7 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
public class FlatScrollBarUI
|
||||
extends BasicScrollBarUI
|
||||
implements StyleableUI
|
||||
implements StyleableUI, StyleableLookupProvider
|
||||
{
|
||||
// overrides BasicScrollBarUI.supportsAbsolutePositioning (which is private)
|
||||
@Styleable protected boolean allowsAbsolutePositioning;
|
||||
@@ -268,6 +270,14 @@ public class FlatScrollBarUI
|
||||
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||
}
|
||||
|
||||
/** @since 2.5 */
|
||||
@Override
|
||||
public MethodHandles.Lookup getLookupForStyling() {
|
||||
// MethodHandles.lookup() is caller sensitive and must be invoked in this class,
|
||||
// otherwise it is not possible to access protected fields in JRE superclass
|
||||
return MethodHandles.lookup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize( JComponent c ) {
|
||||
return UIScale.scale( super.getPreferredSize( c ) );
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.lang.annotation.Repeatable;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
@@ -70,6 +71,9 @@ public class FlatStylingSupport
|
||||
* <p>
|
||||
* Use this annotation, instead of {@link Styleable}, to style fields
|
||||
* in superclasses, where it is not possible to use {@link Styleable}.
|
||||
* <p>
|
||||
* Classes using this annotation may implement {@link StyleableLookupProvider}
|
||||
* to give access to protected fields (in JRE) in modular applications.
|
||||
*
|
||||
* @since 2.5
|
||||
*/
|
||||
@@ -107,6 +111,11 @@ public class FlatStylingSupport
|
||||
/** @since 2.5 */ Object getStyleableValue( String key );
|
||||
}
|
||||
|
||||
/** @since 2.5 */
|
||||
public interface StyleableLookupProvider {
|
||||
MethodHandles.Lookup getLookupForStyling();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the style specified in client property {@link FlatClientProperties#STYLE}.
|
||||
@@ -443,14 +452,14 @@ public class FlatStylingSupport
|
||||
try {
|
||||
Field f = cls.getDeclaredField( fieldName );
|
||||
if( predicate == null || predicate.test( f ) )
|
||||
return applyToField( f, obj, value );
|
||||
return applyToField( f, obj, value, false );
|
||||
} catch( NoSuchFieldException ex ) {
|
||||
// field not found in class --> try superclass
|
||||
}
|
||||
|
||||
for( StyleableField styleableField : cls.getAnnotationsByType( StyleableField.class ) ) {
|
||||
if( key.equals( styleableField.key() ) )
|
||||
return applyToField( getStyleableField( styleableField ), obj, value );
|
||||
return applyToField( getStyleableField( styleableField ), obj, value, true );
|
||||
}
|
||||
|
||||
cls = cls.getSuperclass();
|
||||
@@ -465,9 +474,23 @@ public class FlatStylingSupport
|
||||
}
|
||||
}
|
||||
|
||||
private static Object applyToField( Field f, Object obj, Object value ) {
|
||||
private static Object applyToField( Field f, Object obj, Object value, boolean useMethodHandles ) {
|
||||
checkValidField( f );
|
||||
|
||||
if( useMethodHandles && obj instanceof StyleableLookupProvider ) {
|
||||
try {
|
||||
// use method handles to access protected fields in JRE in modular applications
|
||||
MethodHandles.Lookup lookup = ((StyleableLookupProvider)obj).getLookupForStyling();
|
||||
|
||||
// get old value and set new value
|
||||
Object oldValue = lookup.unreflectGetter( f ).invoke( obj );
|
||||
lookup.unreflectSetter( f ).invoke( obj, convertToEnum( value, f.getType() ) );
|
||||
return oldValue;
|
||||
} catch( Throwable ex ) {
|
||||
throw newFieldAccessFailed( f, ex );
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// necessary to access protected fields in other packages
|
||||
f.setAccessible( true );
|
||||
@@ -481,9 +504,19 @@ public class FlatStylingSupport
|
||||
}
|
||||
}
|
||||
|
||||
private static Object getFieldValue( Field f, Object obj ) {
|
||||
private static Object getFieldValue( Field f, Object obj, boolean useMethodHandles ) {
|
||||
checkValidField( f );
|
||||
|
||||
if( useMethodHandles && obj instanceof StyleableLookupProvider ) {
|
||||
// use method handles to access protected fields in JRE in modular applications
|
||||
try {
|
||||
MethodHandles.Lookup lookup = ((StyleableLookupProvider)obj).getLookupForStyling();
|
||||
return lookup.unreflectGetter( f ).invoke( obj );
|
||||
} catch( Throwable ex ) {
|
||||
throw newFieldAccessFailed( f, ex );
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
f.setAccessible( true );
|
||||
return f.get( obj );
|
||||
@@ -492,7 +525,7 @@ public class FlatStylingSupport
|
||||
}
|
||||
}
|
||||
|
||||
private static IllegalArgumentException newFieldAccessFailed( Field f, IllegalAccessException ex ) {
|
||||
private static IllegalArgumentException newFieldAccessFailed( Field f, Throwable ex ) {
|
||||
return new IllegalArgumentException( "failed to access field '" + f.getDeclaringClass().getName() + "." + f.getName() + "'", ex );
|
||||
}
|
||||
|
||||
@@ -792,7 +825,7 @@ public class FlatStylingSupport
|
||||
if( styleable.type() != Void.class )
|
||||
throw new IllegalArgumentException( "'Styleable.type' on field '" + fieldName + "' not supported" );
|
||||
|
||||
return getFieldValue( f, obj );
|
||||
return getFieldValue( f, obj, false );
|
||||
}
|
||||
} catch( NoSuchFieldException ex ) {
|
||||
// field not found in class --> try superclass
|
||||
@@ -800,10 +833,8 @@ public class FlatStylingSupport
|
||||
|
||||
// find field specified in 'StyleableField' annotation
|
||||
for( StyleableField styleableField : cls.getAnnotationsByType( StyleableField.class ) ) {
|
||||
if( key.equals( styleableField.key() ) ) {
|
||||
Field f = getStyleableField( styleableField );
|
||||
return getFieldValue( f, obj );
|
||||
}
|
||||
if( key.equals( styleableField.key() ) )
|
||||
return getFieldValue( getStyleableField( styleableField ), obj, true );
|
||||
}
|
||||
|
||||
cls = cls.getSuperclass();
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
|
||||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk-17/"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="-Ddummy=dummy"/>
|
||||
<listAttribute key="org.eclipse.jdt.launching.MODULEPATH">
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk-17/" path="4" type="4"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/flatlaf-testing-modular-app/build/libs/flatlaf-testing-modular-app-2.0-SNAPSHOT.jar" path="4" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/flatlaf-core/build/libs/flatlaf-2.0-SNAPSHOT.jar" path="4" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/flatlaf-extras/build/libs/flatlaf-extras-2.0-SNAPSHOT.jar" path="4" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/flatlaf-testing-modular-app/build/libs/flatlaf-testing-modular-app-2.5-SNAPSHOT.jar" path="4" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/flatlaf-core/build/libs/flatlaf-2.5-SNAPSHOT.jar" path="4" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/flatlaf-extras/build/libs/flatlaf-extras-2.5-SNAPSHOT.jar" path="4" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry externalArchive="C:/Users/charly/.gradle/caches/modules-2/files-2.1/com.formdev/svgSalamander/1.1.2.4/828c2ce815bf62031764f5219597948bd2587aa5/svgSalamander-1.1.2.4.jar" path="4" type="2"/> "/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="flatlaf-testing-modular-app"/>
|
||||
|
||||
@@ -20,7 +20,9 @@ import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollBar;
|
||||
import javax.swing.SwingUtilities;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.FlatLightLaf;
|
||||
import com.formdev.flatlaf.extras.FlatSVGIcon;
|
||||
@@ -39,6 +41,8 @@ public class FlatModularAppTest
|
||||
|
||||
JButton button1 = new JButton( "Hello" );
|
||||
JButton button2 = new JButton( "World" );
|
||||
JScrollBar scrollBar = new JScrollBar();
|
||||
scrollBar.putClientProperty( FlatClientProperties.STYLE, "track: #0f0" );
|
||||
|
||||
button1.setIcon( new FlatSVGIcon(
|
||||
FlatModularAppTest.class.getResource( "/com/formdev/flatlaf/testing/modular/app/icons/copy.svg" ) ) );
|
||||
@@ -47,6 +51,7 @@ public class FlatModularAppTest
|
||||
panel.add( new JLabel( "Hello World" ) );
|
||||
panel.add( button1 );
|
||||
panel.add( button2 );
|
||||
panel.add( scrollBar );
|
||||
|
||||
JFrame frame = new JFrame( "FlatModularAppTest" );
|
||||
frame.setIconImages( FlatSVGUtils.createWindowIconImages(
|
||||
|
||||
Reference in New Issue
Block a user