在缩放的graphics2d中使用束带会产生各种间距和字形

时间:2015-03-04 19:01:05

标签: java swing graphics2d drawstring

我正在尝试使用下面的代码缩小文本,但缩放不会正确缩放文本的字体。我相信它不会保持结果相同。

我的目标是缩放html字符串,但问题仍然存在。例如,如果我绘制html文本(JTextPane中的不同前景和背景),就好像字符串在跳舞一样。 :(

换句话说,它不能顺利扩展。

import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JPanel;

public class scaledText extends javax.swing.JDialog {

    public scaledText(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        setSize(800, 450);
        setLocationRelativeTo(null);
        setContentPane(new JPanel() {

            private float timer = 0.001f;

            @Override
            protected void paintComponent(Graphics g) {
                Graphics2D g2 = (Graphics2D) g;
                super.paintComponent(g2);

                timer += 0.01f;
                if (timer > 2.7) {
                    timer = 0.001f;
                }
                float t = Math.min(timer, 2.5f);
                g2.setFont(new Font("Arial", 0, 60));

                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
                g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);

                String text = "This is a text";
                FontMetrics fm = new FontMetrics(g2.getFont()) {
                };
                g2.translate((600 - g2.getFontMetrics(g2.getFont()).stringWidth(text)) / 2, (450 - fm.getHeight()) / 2);
                g2.scale(t, t);
                g2.drawString(text, 0f, 0f);
                g2.draw(new Ellipse2D.Double(0, 0, 100, 100));
                try {
                    Thread.sleep(20);
                } catch (InterruptedException ex) {
                }
                this.repaint();
            }
        });
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                scaledText dialog = new scaledText(new javax.swing.JFrame(), true);
                dialog.addWindowListener(new java.awt.event.WindowAdapter() {

                    public void windowClosing(java.awt.event.WindowEvent e) {
                        System.exit(0);
                    }
                });
                dialog.setVisible(true);
            }
        });
    }
}

1 个答案:

答案 0 :(得分:1)

这是另一种让我能够绘制字符串的方法。但是,它不允许我保留字体样式和颜色:(这给了我文本的形状。但它完美地缩放。

import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.text.AttributedString;

import javax.swing.JPanel;

public class scaledText extends javax.swing.JDialog {

    public static Shape getTextShape(Graphics2D g2d, String text, Font font, boolean ltr) {
        AttributedString attstring = new AttributedString(text);
        attstring.addAttribute(TextAttribute.FONT, font);
        attstring.addAttribute(TextAttribute.RUN_DIRECTION, ltr ? TextAttribute.RUN_DIRECTION_LTR : TextAttribute.RUN_DIRECTION_RTL);
        FontRenderContext frc = g2d.getFontRenderContext();
        TextLayout t = new TextLayout(attstring.getIterator(), frc);
        return t.getOutline(null);
    }

    public scaledText(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        setSize(800, 450);
        setLocationRelativeTo(null);
        setContentPane(new JPanel() {

            private float timer = 1.001f;

            @Override
            protected void paintComponent(Graphics g) {
                Graphics2D g2 = (Graphics2D) g;
                super.paintComponent(g2);

                timer += 0.005f;
                if (timer > 2.7) {
                    timer = 1.001f;
                }
                float t = Math.min(timer, 2.5f);
                GraphicsEnvironment ge =
                        GraphicsEnvironment.getLocalGraphicsEnvironment();

                g2.setFont(new Font("Arial", 0, 100));

                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
                g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

                String text = "This is a text مرحبا";

                Shape shape = getTextShape(g2, text, g2.getFont(), true);

                FontMetrics fm = new FontMetrics(g2.getFont()) {
                };
                g2.translate(10, (450 - fm.getHeight()) / 2);
                g2.scale(t / 2.5, t / 2.5);

                g2.fill(shape);

                try {
                    Thread.sleep(20);
                } catch (InterruptedException ex) {
                }
                this.repaint();
            }
        });
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                scaledText dialog = new scaledText(new javax.swing.JFrame(), true);
                dialog.addWindowListener(new java.awt.event.WindowAdapter() {

                    public void windowClosing(java.awt.event.WindowEvent e) {
                        System.exit(0);
                    }
                });
                dialog.setVisible(true);
            }
        });
    }
}