Поворот текста в Java2D на Mac

Вот проблема, с которой я сейчас сталкиваюсь: я хочу нарисовать строку на JPanel, используя Java2D. Строка должна быть повернута на заданный пользователем угол.

Под этой строкой я также закрашиваю фон заданным цветом, чтобы облегчить чтение (на моем JPanel рисуется множество других вещей).

Что я сделал в переопределенном методе рисования моей JPanel, так это следующее:

final Graphics2D g2 = (Graphics2D) g.create();

final int textWidth = g.getFontMetrics().stringWidth(textToDraw);
final int textHeight = g.getFontMetrics().getHeight();

g2.translate(pointToDraw.x, pointToDraw.y);
g2.rotate(angle);

g2.setColor(textBackground);
g2.fillRect(deltaX, -textHeight, textWidth, textHeight);

g2.setColor(drawColor);
g2.setFont(font);
g2.drawString(textToDraw, deltaX, deltaY);
g2.dispose();

Это очень хорошо работает в Linux, но в Mac OS X (с Java 1.6) текст отображается неправильно: текст правильно повернут, но после каждого символа есть разрыв строки.

Как я могу заставить его работать на обеих платформах?


person Ben    schedule 08.02.2013    source источник


Ответы (1)


Я не думаю, что это решение, которое вам понадобится, но из всего, что я смог прочитать, лучшего решения не найти...

Проблема, кажется, в том, что Mac вращает каждый символ, а не только String

введите здесь описание изображения

В общем, я обманул. Это преобразует текст в BufferedImage (вы должны создавать изображение только при изменении свойств, в отличие от меня, что я сделал в методе paint), а затем поворачивает изображение...

public class RotateText {

    public static void main(String[] args) {
        new RotateText();
    }

    public RotateText() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private String textToDraw = "Stack Overflow";
        private double angle = 90;
        private Color drawColor = Color.BLACK;

        public TestPane() {
            Timer timer = new Timer(50, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    angle += 2;
                    repaint();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

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

            FontMetrics fm = g2.getFontMetrics();

            int textWidth = fm.stringWidth(textToDraw);
            int textHeight = fm.getHeight();

            BufferedImage img = new BufferedImage(textWidth, textHeight, BufferedImage.TYPE_INT_ARGB);
            Graphics2D ig = img.createGraphics();
            ig.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            ig.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            ig.setColor(drawColor);
            ig.drawString(textToDraw, 0, fm.getAscent());
            ig.dispose();

            int x = (getWidth() - textWidth) / 2;
            int y = (getHeight() - textHeight) / 2;

            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setTransform(AffineTransform.getRotateInstance(Math.toRadians(angle), getWidth() / 2, getHeight() / 2));
            g2.drawImage(img, x, y, this);
            g2.dispose();
        }

    }

}
person MadProgrammer    schedule 08.02.2013
comment
Это увлекательная ошибка, боль в тылу, но увлекательная - person MadProgrammer; 08.02.2013