Part 2 - How do I get consistent rendering when scaling a JTextPane?

耗尽温柔 提交于 2019-11-28 02:06:53
trashgod

Sadly, scaling to a larger size from a fixed resolution will always result in some aliasing artifact. Here's an alternative approach that scales the font used by JTextPane.

For low-level control, consider TextLayout, which includes a FontRenderContext that can manage the anti-aliasing and fractional metrics settings, as seen in this example.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;

/** @see https://stackoverflow.com/questions/4566211 */
public class ScaledJTextPane {

    private static final int SIZE = 14;
    private static final String FONT = "Dialog";

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("ScaledJTextPane using BufferedImage");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final JTextPane tp = new JTextPane();
        tp.setFont(new Font(FONT, Font.PLAIN, SIZE));
        tp.setPreferredSize(new Dimension(400, 300));
        StyledDocument doc = tp.getStyledDocument();
        Style defaultStyle = StyleContext.getDefaultStyleContext()
            .getStyle(StyleContext.DEFAULT_STYLE);
        Style boldStyle = doc.addStyle("bold", defaultStyle);
        StyleConstants.setBold(boldStyle, true);
        String boldText = "Four score and seven years ago ";
        String plainText = "our fathers brought forth on this continent, "
            + "a new nation, conceived in Liberty, and dedicated to the "
            + "proposition that all men are created equal.";
        try {
            doc.insertString(doc.getLength(), boldText, boldStyle);
            doc.insertString(doc.getLength(), plainText, defaultStyle);
        } catch (BadLocationException ble) {
            ble.printStackTrace(System.err);
        }
        final JPanel panel = new JPanel();
        panel.add(tp);

        final JComboBox zoomCombo = new JComboBox(new String[]{
                "75%", "100%", "150%", "175%", "200%"});
        zoomCombo.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                String s = (String) zoomCombo.getSelectedItem();
                s = s.substring(0, s.length() - 1);
                double scale = new Double(s).doubleValue() / 100;
                int size = (int) (SIZE * scale);
                tp.setFont(new Font(FONT, Font.PLAIN, size));
            }
        });
        zoomCombo.setSelectedItem("100%");
        JPanel optionsPanel = new JPanel();
        optionsPanel.add(zoomCombo);
        panel.setBackground(Color.WHITE);
        frame.add(panel, BorderLayout.CENTER);
        frame.add(optionsPanel, BorderLayout.NORTH);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

I would like to allow users to zoom into or out of a non-editable JTextPane.

Since the text pane is non-editable, maybe you can create an image of the text pane by using the Screen Image class. Then you can draw the image on a panel using the approriate scaling factor.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!