如果移动和调整大小,则以下组件正确绘制,但如果从屏幕中拖出则不会。
为什么?
public class Test_ShapeDraw {
public static class JShape extends JComponent {
private Shape shape;
private AffineTransform tx;
private Rectangle2D bounds;
public JShape() {
}
public void setShape(Shape value) {
this.shape = value;
bounds = shape.getBounds2D();
setPreferredSize(new Dimension((int) bounds.getWidth(), (int)bounds.getHeight()));
tx = AffineTransform.getTranslateInstance(-bounds.getMinX(), -bounds.getMinY());
}
public Shape getShape() {
return shape;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if( shape != null ) {
Graphics2D g2d = (Graphics2D)g;
g2d.setTransform(tx);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
((Graphics2D)g).draw(shape);
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
Shape shape = new Ellipse2D.Double(0,0,300,300);
JShape jShape = new JShape();
jShape.setShape(shape);
JFrame f = new JFrame("Shape Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(jShape);
f.pack();
f.setVisible(true);
}
}
答案 0 :(得分:4)
AffineTransform originalTransform = g2d.getTransform();
g2d.transform(tx);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
((Graphics2D)g).draw(shape);
g2d.setTransform(originalTransform);
说明:请参阅JavaDoc for Graphics2D.setTransform:警告:永远不应该使用此方法在现有转换之上应用新的坐标转换,因为Graphics2D可能已经具有其他用途所需的转换,例如渲染Swing组件或应用缩放变换来调整打印机的分辨率。
要添加坐标变换,请使用变换,旋转,缩放或剪切方法。 setTransform方法仅用于在渲染后恢复原始的Graphics2D变换。
答案 1 :(得分:0)
尝试删除getPreferredSize()方法并在setShape方法中使用setPreferredSize():
public void setShape(Shape value) {
this.shape = value;
bounds = shape.getBounds2D();
setPreferredSize(new Dimension((int) bounds.getWidth(), (int)bounds.getHeight()));
tx = AffineTransform.getTranslateInstance(-bounds.getMinX(), -bounds.getMinY());
}