Text anti-aliasing in Java 1.7 (Windows)

Rendering smoothing for text seems broken for components of Swing Java 1.7 (Windows). Setting KEY_ANTIALIASING and / or KEY_TEXT_ANTIALIASING no longer affects the display of JEditorPane , JEditorPane , etc. - but actually I need different settings in my project.

In this screenshot, you can compare the different behavior in Java 1.6 (jdk1.6.0_45) and Java 1.7 (jdk1.7.0_40) created using the test program below:

Left side run with Java 1.6, right side with Java 1.7

The left side is Java 1.6, the right side is Java 1.7. The first column is colored with Graphics2D.drawString , the second with JLabel . In Java 1.6, rendering hints affect the display of JLabel, while in Java 1.7 all JLabels render the same (except for units with fractional metrics).

Did you know that smoothing hints affect Swing components in Java 1.7?

Testing 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 do not work. Also does not change Look and Feel .

+6
source share
3 answers

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. Please note that recent Windows updates (February 2015), such as kb3013455 , break font smoothing on many systems.

+3
source

Firstly, a few points regarding the behavior of Swing components:

  • The UI divider for the Swing component that you call when you call super.paintComponent() can set up any rendering hints that it wants - it seems like the UI delegate for JLabel is from look and redefinition
  • If you do not want to use anti-aliasing (i.e. using remote X or similar), you should probably use MetalLookAndFeel , which was designed with this in mind.
  • There is no guarantee that the user interface delegate for any component will not override everything that you configured for rendering β€” that is, the behavior you see is completely legal.

Speaking of JDK 1.6 (and to my knowledge 1.7, but not promises), you can access the default rendering hints used by AWT and Swing through undocumented (and therefore not supported).

(Map<RenderingHints.Key, Object>)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));

Here is a usage example that I wrote for NetBeans around 2004 - see the getHints() method . It does the opposite of what you need, as it tries to force anti-aliasing to be turned on. But manipulating the contents of this Map or replacing it may work to globally change the anti-aliasing settings.

+1
source

I know this is an ancient question, but I ran into the same problems.

After researching, I found that if you add the following to the main () method, the code will work as expected:

 System.setProperty("awt.useSystemAAFontSettings","off"); System.setProperty("swing.aatext", "false"); 

Apparently, the default values ​​for Java 7 have changed from both "off" properties to 'on'

0
source

Source: https://habr.com/ru/post/953703/


All Articles