私の質問はそれほど難しいものではなく、質問で与えられた私の 2 つのアイデアは実際には同じアイデアであることがわかりました。これは、を変換しTransformedStroke
て歪んだ を実装するクラスです。Stroke
Shape
import java.awt.*;
import java.awt.geom.*;
/**
* A implementation of {@link Stroke} which transforms another Stroke
* with an {@link AffineTransform} before stroking with it.
*
* This class is immutable as long as the underlying stroke is
* immutable.
*/
public class TransformedStroke
implements Stroke
{
/**
* To make this serializable without problems.
*/
private static final long serialVersionUID = 1;
/**
* the AffineTransform used to transform the shape before stroking.
*/
private AffineTransform transform;
/**
* The inverse of {@link #transform}, used to transform
* back after stroking.
*/
private AffineTransform inverse;
/**
* Our base stroke.
*/
private Stroke stroke;
/**
* Creates a TransformedStroke based on another Stroke
* and an AffineTransform.
*/
public TransformedStroke(Stroke base, AffineTransform at)
throws NoninvertibleTransformException
{
this.transform = new AffineTransform(at);
this.inverse = transform.createInverse();
this.stroke = base;
}
/**
* Strokes the given Shape with this stroke, creating an outline.
*
* This outline is distorted by our AffineTransform relative to the
* outline which would be given by the base stroke, but only in terms
* of scaling (i.e. thickness of the lines), as translation and rotation
* are undone after the stroking.
*/
public Shape createStrokedShape(Shape s) {
Shape sTrans = transform.createTransformedShape(s);
Shape sTransStroked = stroke.createStrokedShape(sTrans);
Shape sStroked = inverse.createTransformedShape(sTransStroked);
return sStroked;
}
}
それを使用した私のペイント方法は次のようになります。
public void paintComponent(Graphics context) {
super.paintComponent(context);
Graphics2D g = (Graphics2D)context.create();
int height = getHeight();
int width = getWidth();
g.scale(width/4.0, height/7.0);
try {
g.setStroke(new TransformedStroke(new BasicStroke(2f),
g.getTransform()));
}
catch(NoninvertibleTransformException ex) {
// should not occur if width and height > 0
ex.printStackTrace();
}
g.setColor(Color.BLACK);
g.draw(new Rectangle( 1, 2, 2, 4));
}
次に、私のウィンドウは次のようになります。

私はこれで十分満足していますが、誰かがもっとアイデアを持っている場合でも、遠慮なく答えてください。
注意:これは、 の後に適用される変換だけでなく、デバイス空間に対するgの完全な変換をg.getTransform()
返しています。したがって、Graphics をコンポーネントに渡す前にスケーリングを行った場合でも、メソッドに指定された 2 ピクセルのグラフィックスではなく、2 デバイス ピクセル幅のストロークで描画されます。これが問題になる場合は、次のように使用します。.create()
public void paintComponent(Graphics context) {
super.paintComponent(context);
Graphics2D g = (Graphics2D)context.create();
AffineTransform trans = new AffineTransform();
int height = getHeight();
int width = getWidth();
trans.scale(width/4.0, height/7.0);
g.transform(trans);
try {
g.setStroke(new TransformedStroke(new BasicStroke(2f),
trans));
}
catch(NoninvertibleTransformException ex) {
// should not occur if width and height > 0
ex.printStackTrace();
}
g.setColor(Color.BLACK);
g.draw(new Rectangle( 1, 2, 2, 4));
}
Swing では通常、 に指定された GraphicspaintComponent
は変換されるだけで ((0,0) はコンポーネントの左上隅になります)、スケーリングされないため、違いはありません。