2

I have been trying to align my java2d shape's center to the JPanel's center with no success. I was able to do it for an image and many 2D shapes like parallelogram using getBounds method but not for rhombus though all of them follow the same pattern. Drastically, when I prepared an SSCCE out of the actual project I could align none of them correctly. I've written a drawShape method for drawing shapes on center. I didn't understand where I'm going wrong. This is SSCCE:

            import java.awt.*;
            import java.awt.geom.*;
            import java.util.*;
            import javax.swing.*;
            public class TestPanel extends JPanel{
                    Point a,b,c,d;
                    Shape trapezium,parallelogram;
                    Random random=new Random();
                    public TestPanel(){
                        a=new Point();
                        b=new Point();
                        c=new Point();
                        d=new Point();
                        rhombusFactory(a,b,c,d);
                        trapezium=getQuadrilateral(a,b,c,d);


                    }
                    private void rhombusFactory(Point a,Point b,Point c,Point d)
                    {       int width=random.nextInt(200-100)+100;
                            int height=random.nextInt(150-50)+50;
                            a.x=0;
                            a.y=0;
                            b.x=a.x+width/2;
                            b.y=a.y+height/2;
                            c.x=a.x+width;
                            c.y=a.y;
                            d.x=a.x+width/2;
                            d.y=a.y-height/2;
                    }
                    private void parallelogramFactory(Point a,Point b,Point c,Point d){
                        int l1=random.nextInt(200-100)+100;
                        int l2=random.nextInt(150-70)+70;
                        int offset=(random.nextInt(2)==0?-1:1)*(random.nextInt(50-20)+20);
                        a.x=0;
                        a.y=0;
                        b.x=a.x+l1;
                        b.y=a.y;
                        d.x=a.x+offset;
                        d.y=a.y+l2;
                        c.x=d.x+l1;
                        c.y=d.y;
                }
                     private Shape getQuadrilateral(Point a,Point b,Point c,Point d){
                         GeneralPath gp=new GeneralPath();
                         gp.moveTo(a.x,a.y);
                         gp.lineTo(b.x,b.y);
                         gp.lineTo(c.x,c.y);
                         gp.lineTo(d.x,d.y);
                         gp.closePath();
                         return gp;
                    }
                    private void drawShape(Graphics2D g,Shape shape){
                        AffineTransform oldt=g.getTransform();
                        Rectangle2D bounds=shape.getBounds2D();
                        double height=bounds.getHeight();
                        double width=bounds.getWidth();
                        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                        g.setStroke(new BasicStroke(2.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
                        g.translate(this.getWidth()/2,this.getHeight()/2);
                        g.translate(-width/2,-height/2);
                        g.draw(shape.getBounds2D());
                        g.draw(shape);
                        g.setTransform(oldt);
                }
                    public void paintComponent(Graphics g2){
                            super.paintComponent(g2);
                            Graphics2D g=(Graphics2D)g2;
                            drawShape(g,trapezium);
                            //drawShape(g,parallelogram);
                    }
                    public static void main(String args[]){
                            JFrame jf=new JFrame();
                            TestPanel tp=new TestPanel();
                            jf.setLayout(new BorderLayout());
                            jf.add(tp,BorderLayout.CENTER);
                            jf.setSize(500,500);
                            jf.setVisible(true);
                    }
             }

Any help would be appreciated EDIT: I just removed the confusing lines out of the code...

4

3 回答 3

7

您需要考虑 Shape 的有界 x/y 位置:

Rectangle bounds=shape.getBounds(); // changed this
...
//g.translate(this.getWidth()/2,this.getHeight()/2);
//g.translate(-width/2,-height/2);
g.translate((this.getWidth() - width) / 2,(this.getHeight() - height) / 2);
g.translate(-bounds.x, -bounds.y); // added this
于 2013-05-19T18:21:17.170 回答
1

编辑
在方法rhombusFactory()中,更改:

a.y=0;

对此:

a.y=height/2;

简短说明
在您的drawShape()方法中,您将图形上下文的原点放置在您假设形状边界的左上角为 (Point: [(getWidth-width)/2, (getHeight()-height)/2]) 的位置. 在您的rhombusFactory()方法中,您将点设置a为 (0, 0),从而将形状的左上角移动到 (0,-height/2),从而有效地导致它没有垂直居中。

于 2013-05-19T18:07:34.820 回答
1

你的翻译是错误的。您应该首先将绘图空间的原点转换为面板的中心,然后将绘图的中心转换为原点。你把后者做对了,但第一个做错了。

改变

g.translate(this.getWidth(),this.getHeight());
g.translate(-width/2,-height/2);

g.translate(this.getWidth()/2,this.getHeight()/2);
g.translate(-width/2,-height/2);

要不就

g.translate((this.getWidth() - width) / 2,(this.getHeight() - height) / 2);
于 2013-05-19T18:08:23.640 回答