Antialiasing rendering hints for text seem broken for Swing components Java 1.7 (Windows). Setting KEY_ANTIALIASING
and/or KEY_TEXT_ANTIALIASING
does not affect anymore the display of JLabel
, JEditorPane
, etc. - but actually I need different settings in my project.
You can compare the different behavior in Java 1.6
(jdk1.6.0_45) and Java 1.7
(jdk1.7.0_40) in this screenshot, produced with the test program below:
Left side is Java 1.6, right side is Java 1.7. The first column is painted with Graphics2D.drawString
, the second with a JLabel
. In Java 1.6 the rendering hints affect the JLabel display, whereas in Java 1.7 all JLabels render the same (except for the one with fractional metrics).
Do you know how I can have the antialiasing hints affect Swing components in Java 1.7?
Test program:
import java.awt.*;
import java.util.*;
import javax.swing.*;
public class AntialiasMain extends JFrame {
public AntialiasMain() {
JPanel panel = new JPanel(new GridLayout(0, 1));
panel.add(new AntialiasLabel("default", null));
HashMap<Key, Object> hints = new HashMap<Key, Object>();
hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
panel.add(new AntialiasLabel("AA off", hints));
hints = new HashMap<Key, Object>();
hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
panel.add(new AntialiasLabel("AA on", hints));
hints = new HashMap<Key, Object>();
hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
panel.add(new AntialiasLabel("TextAA off", hints));
hints = new HashMap<Key, Object>();
hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
panel.add(new AntialiasLabel("TextAA on", hints));
hints = new HashMap<Key, Object>();
hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
panel.add(new AntialiasLabel("AA+TextAA on", hints));
hints = new HashMap<Key, Object>();
hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
hints.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
panel.add(new AntialiasLabel("AA+FracMetr on", hints));
hints = new HashMap<Key, Object>();
hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
panel.add(new AntialiasLabel("AA+TextLCD on", hints));
hints = new HashMap<Key, Object>();
hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
panel.add(new AntialiasLabel("TextLCD on", hints));
getContentPane().add(panel);
}
class AntialiasLabel extends JLabel {
private final HashMap<Key, Object> hints;
private final String label;
private static final String PALYNDROME = "The quick brown fox jumped over the lazy dog";
public AntialiasLabel(String label, HashMap<Key, Object> hints) {
super(PALYNDROME);
setForeground(Color.BLACK);
setBorder(BorderFactory.createEmptyBorder(10, 150, 10, 10));
this.label = label;
this.hints = hints;
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
if (hints != null)
g2.setRenderingHints(hints);
g2.drawString("Setting: " + label, 2, getHeight() / 2 + 5);
super.paintComponent(g2);
}
}
public static void main(final String[] args) {
JFrame f = new AntialiasMain();
f.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
f.pack();
f.setVisible(true);
}
}
Edit: System properties swing.aatext
and awt.useSystemAAFontSettings
have no effect. Neither has changing the Look and Feel
.
Found a solution in this answer. Update the code in your question with:
private static final Object AA_TEXT_PROP = getAaTextProperty();
public static Object getAaTextProperty() {
Object aatext = null;
try {
Class<?> c = Class.forName("sun.swing.SwingUtilities2");
Field f = c.getField("AA_TEXT_PROPERTY_KEY");
aatext = f.get(null);
} catch (Exception e) {
e.printStackTrace();
}
return aatext;
}
...
public AntialiasLabel(String label, HashMap<Key, Object> hints) {
super(PALYNDROME);
putClientProperty(AA_TEXT_PROP, null);
...
}
Tested on Java 1.7 Windows. Note that recent (Feb-2015) Windows updates like kb3013455 have broken font anti-aliasing on many systems.
First, a few points on the behavior of Swing components:
super.paintComponent()
can set up whatever rendering hints it wants - it appear that the UI delegate for JLabel from the look and feel is overriding yoursMetalLookAndFeel
which was designed with that use-case in mind.That being said, as of JDK 1.6 (and therefore as far as I know, 1.7, but no promises) you could access the default rendering hints used by AWT and Swing via an undocumented (and therefore not supported) desktop property
(Map<RenderingHints.Key, Object>)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));
Here is a usage example I wrote for NetBeans, circa 2004 - see the getHints()
method. It does the opposite of what you are after, since it is trying to force antialiasing to be on. But manipulating the contents of that Map
, or replacing it, may work to globally change the antialiasing settings.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With