UI defaults: add text antialiasing hint

(preparation for replacing "base" Metal LaF with BasicLookAndFeel)
This commit is contained in:
Karl Tauber
2020-02-19 15:35:29 +01:00
parent 5a4e321f78
commit ae8093313e

View File

@@ -23,6 +23,7 @@ import java.awt.EventQueue;
import java.awt.Font; import java.awt.Font;
import java.awt.KeyEventPostProcessor; import java.awt.KeyEventPostProcessor;
import java.awt.KeyboardFocusManager; import java.awt.KeyboardFocusManager;
import java.awt.RenderingHints;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.awt.Window; import java.awt.Window;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
@@ -31,6 +32,7 @@ import java.beans.PropertyChangeListener;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -61,12 +63,15 @@ public abstract class FlatLaf
extends BasicLookAndFeel extends BasicLookAndFeel
{ {
static final Logger LOG = Logger.getLogger( FlatLaf.class.getName() ); static final Logger LOG = Logger.getLogger( FlatLaf.class.getName() );
private static final String DESKTOPFONTHINTS = "awt.font.desktophints";
private BasicLookAndFeel base; private BasicLookAndFeel base;
private String desktopPropertyName; private String desktopPropertyName;
private PropertyChangeListener desktopPropertyListener; private PropertyChangeListener desktopPropertyListener;
private static boolean updateUIPending;
private KeyEventPostProcessor mnemonicListener; private KeyEventPostProcessor mnemonicListener;
private static boolean showMnemonics; private static boolean showMnemonics;
private static WeakReference<Window> lastShowMnemonicWindow; private static WeakReference<Window> lastShowMnemonicWindow;
@@ -139,9 +144,19 @@ public abstract class FlatLaf
} }
if( desktopPropertyName != null ) { if( desktopPropertyName != null ) {
desktopPropertyListener = e -> { desktopPropertyListener = e -> {
String propertyName = e.getPropertyName();
if( desktopPropertyName.equals( propertyName ) )
reSetLookAndFeel(); reSetLookAndFeel();
else if( DESKTOPFONTHINTS.equals( propertyName ) ) {
if( UIManager.getLookAndFeel() instanceof FlatLaf ) {
putAATextInfo( UIManager.getLookAndFeelDefaults() );
updateUILater();
}
}
}; };
Toolkit.getDefaultToolkit().addPropertyChangeListener( desktopPropertyName, desktopPropertyListener ); Toolkit toolkit = Toolkit.getDefaultToolkit();
toolkit.addPropertyChangeListener( desktopPropertyName, desktopPropertyListener );
toolkit.addPropertyChangeListener( DESKTOPFONTHINTS, desktopPropertyListener );
} }
// Following code should be ideally in initialize(), but needs color from UI defaults. // Following code should be ideally in initialize(), but needs color from UI defaults.
@@ -161,7 +176,9 @@ public abstract class FlatLaf
public void uninitialize() { public void uninitialize() {
// remove desktop property listener // remove desktop property listener
if( desktopPropertyListener != null ) { if( desktopPropertyListener != null ) {
Toolkit.getDefaultToolkit().removePropertyChangeListener( desktopPropertyName, desktopPropertyListener ); Toolkit toolkit = Toolkit.getDefaultToolkit();
toolkit.removePropertyChangeListener( desktopPropertyName, desktopPropertyListener );
toolkit.removePropertyChangeListener( DESKTOPFONTHINTS, desktopPropertyListener );
desktopPropertyName = null; desktopPropertyName = null;
desktopPropertyListener = null; desktopPropertyListener = null;
} }
@@ -260,6 +277,10 @@ public abstract class FlatLaf
if( useScreenMenuBar ) if( useScreenMenuBar )
defaults.put( "MenuBarUI", aquaMenuBarUI ); defaults.put( "MenuBarUI", aquaMenuBarUI );
// initialize text antialiasing
if( !SystemInfo.IS_MAC )
putAATextInfo( defaults );
invokePostInitialization( defaults ); invokePostInitialization( defaults );
return defaults; return defaults;
@@ -353,6 +374,39 @@ public abstract class FlatLaf
defaults.put( "Objects.BlackText", new ColorUIResource( 0x231F20 ) ); defaults.put( "Objects.BlackText", new ColorUIResource( 0x231F20 ) );
} }
private void putAATextInfo( UIDefaults defaults ) {
if( SystemInfo.IS_JAVA_9_OR_LATER ) {
Object desktopHints = Toolkit.getDefaultToolkit().getDesktopProperty( DESKTOPFONTHINTS );
if( desktopHints instanceof Map ) {
@SuppressWarnings( "unchecked" )
Map<Object, Object> hints = (Map<Object, Object>) desktopHints;
Object aaHint = hints.get( RenderingHints.KEY_TEXT_ANTIALIASING );
if( aaHint != null &&
aaHint != RenderingHints.VALUE_TEXT_ANTIALIAS_OFF &&
aaHint != RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT )
{
defaults.put( RenderingHints.KEY_TEXT_ANTIALIASING, aaHint );
defaults.put( RenderingHints.KEY_TEXT_LCD_CONTRAST,
hints.get( RenderingHints.KEY_TEXT_LCD_CONTRAST ) );
}
}
} else {
// Java 8
try {
Object key = Class.forName( "sun.swing.SwingUtilities2" )
.getField( "AA_TEXT_PROPERTY_KEY" )
.get( null );
Object value = Class.forName( "sun.swing.SwingUtilities2$AATextInfo" )
.getMethod( "getAATextInfo", boolean.class )
.invoke( null, true );
defaults.put( key, value );
} catch( Exception ex ) {
Logger.getLogger( FlatLaf.class.getName() ).log( Level.SEVERE, null, ex );
throw new RuntimeException( ex );
}
}
}
private void putDefaults( UIDefaults defaults, Object value, String... keys ) { private void putDefaults( UIDefaults defaults, Object value, String... keys ) {
for( String key : keys ) for( String key : keys )
defaults.put( key, value ); defaults.put( key, value );
@@ -379,7 +433,7 @@ public abstract class FlatLaf
} }
/** /**
* Update UI of all application windows. * Update UI of all application windows immediately.
* Invoke after changing LaF. * Invoke after changing LaF.
*/ */
public static void updateUI() { public static void updateUI() {
@@ -387,6 +441,25 @@ public abstract class FlatLaf
SwingUtilities.updateComponentTreeUI( w ); SwingUtilities.updateComponentTreeUI( w );
} }
/**
* Update UI of all application windows later.
*/
public static void updateUILater() {
synchronized( FlatLaf.class ) {
if( updateUIPending )
return;
updateUIPending = true;
}
EventQueue.invokeLater( () -> {
updateUI();
synchronized( FlatLaf.class ) {
updateUIPending = false;
}
} );
}
public static boolean isShowMnemonics() { public static boolean isShowMnemonics() {
return showMnemonics || !UIManager.getBoolean( "Component.hideMnemonics" ); return showMnemonics || !UIManager.getBoolean( "Component.hideMnemonics" );
} }