Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render text using FRACTIONALMETRICS in Java 7

I have a desktop Java application i'm working on and have been using JDK 6 for development via IDE. I use the rendering hint VALUE_FRACTIONALMETRICS_ON along with other hints to better render text in JLabels. These hints work beautifully on JVM 1.6 but i've recently noticed that it seems to ignore the VALUE_FRACTIONALMETRICS_ON completely when I run the app with a JRE 1.7 Is there something i'm doing wrong here that makes Java 7 ignore these hints?

lblDate = new ATimeLabel(ATimeLabel.DATE_LETTERS) {
    private static final long serialVersionUID = 1L;

    @Override
    protected void paintComponent(Graphics g) {

        Graphics2D g2d = (Graphics2D) g;

        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
                RenderingHints.VALUE_FRACTIONALMETRICS_ON);

        super.paintComponent(g2d);
    }
};

FRACTIONALMETRICS has the biggest noticeable visual effect on text so getting that to work is what i'm looking to do.

here is a screen shot comparison of what it looks like when I run the app from my IDE (Left) which uses Java 6 and when I double click the Jar file its self (Right) which uses my systems JRE, Java 7. (I also temporary added the red border to show that the paint method does work)

Any help would be very much appreciated.

like image 537
Sammy Guergachi Avatar asked Mar 19 '13 19:03

Sammy Guergachi


1 Answers

Normally there is no need for setting VALUE_FRACTIONALMETRICS_ON. Try using the provided desktop hints. You may also double-check the Swing antialiasing hint from the FontRenderContext. Example use is shown below.

If you wish to bolden the text, which is a side effect of fractional metrics, I would prefer using a bold font, or render the output to an image, and blur it befor drawing. That would ensure a system-independent solution.

import java.awt.*;
import java.awt.event.*;
import java.util.Map;
import javax.swing.JLabel;

public class TextHints {
    public static void main(String[] args) {
        Frame frame = new Frame();
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        JLabel label = new JLabel("Sunday, March 17") {
            @Override
            protected void paintComponent(Graphics g) {

                Graphics2D g2d = (Graphics2D) g;

                Map desktopHints = (Map) Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints");
                if (desktopHints != null) {
                    g2d.addRenderingHints(desktopHints);
                    System.out.println("Desktop: " + desktopHints);
                }
                java.awt.FontMetrics fm = getFontMetrics(getFont());
                Object swingHint = fm.getFontRenderContext().getAntiAliasingHint();
                System.out.println("Swing AntiAliasingHint: " + swingHint);

                super.paintComponent(g2d);
            }
        };
        label.setBackground(Color.BLACK);
        label.setForeground(Color.LIGHT_GRAY);
        label.setOpaque(true);

        label.setFont(label.getFont().deriveFont(Font.BOLD, 14f));

        frame.add(label);
        frame.setSize(new Dimension(160, 100));
        frame.setVisible(true);
    }
}
like image 139
sina72 Avatar answered Nov 15 '22 16:11

sina72