我有一些Graphics2D区域,我绘制几何图元。它可以使用g2.scale(x,y)轻松缩放。现在我想在可缩放区域中绘制一些文本并将文本编辑到其中。它也有效,但不幸的是有一个问题可以说明。这是它100%监视显示器的方式:
这就是300%的情况:
lette“A”的位置几乎可以,但是字母B的位置左右跳跃。 我想JEditorPane只是用最近的字体来渲染缩放字体。不同字体的空间可能会有不同的像素大小。这并不会在字符串的开头产生问题,但最后会累积错误。
我怎样才能获得JEditorPane在任何g2.scale()中将字体呈现在完全相同的位置? (例如,OpenOffice可以解决同样的问题)。
UPD:sscce
class Canvas extends JPanel {
@Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g.translate(p.x, p.y);
g2.scale(scale, scale);
g2.setColor(Color.GRAY);
g2.fill(g2.getClip());
JEditorPane pane = new JEditorPane();
pane.setFont(pane.getFont().deriveFont(22f));
pane.setText("A B");
pane.setBounds(new Rectangle(100, 100, 700, 30));
g2.translate(100, 100);
pane.paint(g2);
g2.translate(-100, -100);
g2.setColor(Color.BLACK);
g2.draw(new Rectangle(100, 100, 700, 30));
g2.scale(1 / scale, 1 / scale);
g.translate(-p.x, -p.y);
g2.setColor(Color.GREEN);
g2.setFont(g2.getFont().deriveFont(33f));
g2.drawString("Scale (mouse wheel): " + new DecimalFormat("#.##").format(scale * 100) + "%", 2, 768-66);
g2.drawString("(Drag mouse to move)", 2, 768-33);
}
// +++++++++++++++++++++++++++ GUI +++++++++++++++++++++++++++++++++++++
public Canvas() {
addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
scale += e.getWheelRotation() * 1.0 / 10;
repaint();
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
p.x = e.getPoint().x - startDrag.x;
p.y = e.getPoint().y - startDrag.y;
repaint();
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
startDrag = e.getPoint();
startDrag.x -= p.x;
startDrag.y -= p.y;
}
});
}
public static double scale = 1.0;
public static Point p = new Point();
public static Point startDrag = new Point();
}
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Canvas());
frame.setSize(1024, 768);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
答案 0 :(得分:2)
查看与JEditorPane缩放相关的http://java-sl.com/articles.html篇文章。 “使用自定义GlyphPainter和小数度量支持进行缩放”一文解释了字体缩放和测量问题。您可以使用基于TextLayout或基于GlyphVector的绘画来修复分数fnt测量。
答案 1 :(得分:1)
我和同一个人争吵了一段时间。当您尝试右对齐文本并使用较小的字体大小(因此行上有许多字符)时,问题会更大。缩放只会使错误倍增并使其易于显示。
使用“Scaling with custom GlyphPainter and fractional measure support”文章和代码将有助于从int切换到float摆脱舍入错误。它的工作几乎没问题,但并不完全正确,即那里还有其他事情发生。
在ScaledGlyphPainter.getTabbedTextWidth中,我取代了实际的月经
nextX += metrics.getStringBounds(txtStr, n - charCount, n, painterGr).getWidth();
使用
FontRenderContext frc = new FontRenderContext(new AffineTransform (), true, true);
TextLayout layout = new TextLayout (text, metrics.getFont(), frc);
nextX += layout.getBounds().getWidth();
显然,两次测量都会在同一文本上返回不同的结果!如果测量以一种方式进行并且绘制另一种方式,则会出现绘图错误。一旦我更改了上面的代码以使用TextLayout测量,所有问题都消失了,并且理由可以根据需要运行。