を使用して、幾何学的プリミティブとテキストを配置する必要がありjava.awt.Graphics2d
ます。それらをスケーリングすると、要素同士の相対的な位置がスケールに依存しないことが期待されます。残念ながら、Graphics2D.scale(...)
いくつかのオブジェクトを描画するために使用するGraphics2D.drawRectangle(...)
とGraphics2D.drawString(...)
、相対位置が変わります。次の図で説明するとよいでしょう。
これは、この画像を生成するコードです。
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle("Title");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JPanel() {
{
setPreferredSize(new Dimension(1024, 300));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
for(int i = 1; i < 5; i++) {
doDraw(g2, i, i*10);
}
}
void doDraw(Graphics2D g2, double scale, int yOffset) {
String txt = "A--> B";
AffineTransform at = g2.getTransform();
g2.scale(scale, scale);
g2.setColor(Color.DARK_GRAY);
g2.drawRect(10, 10 + yOffset, 234, 20);
g2.drawString(txt, 14, 24 + yOffset);
g2.setColor(Color.red);
g2.drawOval(228, 12 + yOffset, 14, 14);
g2.setTransform(at);
}
});
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
ご覧のとおり、要素の位置は一定です。変更されるのはスケールだけです。100% では、赤い円は正確に B 文字上にあります。しかし、300% 以上では完全に間違っています。私は何か間違ったことをしていますか、それともJavaのバグですか? その問題の回避策はありますか?
私が実際に達成したいのは、どのスケールでも、赤い円が常に文字「B」の周りに描かれていることです。
UPD:それが起こる理由は、Java がスケーリングされたフォントをレンダリングする方法だと思います。それは単なるフォントではなく、幾何学的操作のようにスケーリングされますが、どのスケールでも Java は適切なドットサイズのフォントを使用します。したがって、75% の Arial 8 は、Arial 8 が 3/4 に縮小されたものではなく、Arial 6 と同じようにレンダリングされます。そうしないと、拡大縮小されたテキストが見栄えが悪くなります。しかし、私はそれで間違っているかもしれません。
UPD 2 : SwingUtilities2.drawText() を試しました - 効果はありません。
背景:実際、私はある種のベクター編集プログラムを作成しています。だから私はX、Y座標を持つドキュメント内のオブジェクトを持っています。だから私はそれらを何らかの形でドキュメントに配置したいだけです。問題は、ズームを変更すると、オブジェクトが互いに相対的な位置で「ジャンプ」することです。したがって、CHECKEDのようなテキストを作成し、文字Cをボックス/サークルに入れたい場合、スケールに依存します。