【问题标题】:Aligning Shape's Center to JPanel's Center将 Shape 的中心与 JPanel 的中心对齐
【发布时间】:2013-05-19 17:49:45
【问题描述】:

我一直在尝试将 java2d 形状的中心与 JPanel 的中心对齐,但没有成功。我能够使用 getBounds 方法对图像和许多 2D 形状(如平行四边形)进行此操作,但对于菱形却不能,尽管它们都遵循相同的模式。严重的是,当我从实际项目中准备 SSCCE 时,我无法正确对齐它们。 我写了一个 drawShape 方法来在中心绘制形状。我不明白我要去哪里错了。 这是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);
                    }
             }

任何帮助将不胜感激 编辑: 我刚刚从代码中删除了令人困惑的行...

【问题讨论】:

  • 将您覆盖的 Point 对象传递到您的工厂是一个坏主意。
  • @MelNicholson 这可能是个坏主意,但这似乎不是问题。我删除了这些行并尝试了没有任何改进....

标签: java swing jpanel java-2d paintcomponent


【解决方案1】:

您需要考虑 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

【讨论】:

  • 投反对票的人有没有试过这个代码?请解释为什么这不是一个可接受的解决方案的原因。我觉得它比公认的答案更好,因为所有翻译都在一个地方完成。事实上,接受的答案只有效,因为 bounds.x 值恰好为 0(否则您还需要操作 a.x )。此解决方案适用于所有情况。
  • 你的很完美,这就是我想要的。我想假设我自己的系统创建我的形状并绘制它翻译......
  • @mKorbel 你是什么意思?我没有投反对票...几分钟前我的代表还不够高...
  • @camickr 你能解释一下我做错了什么以及你的代码和我的代码有什么区别吗?另外,使用 getBounds2D 而不是 getBounds 有什么不同吗?
  • 他的回答是(很可能)down_voted,现在没有任何downvoting :-)
【解决方案2】:

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

改变

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);

【讨论】:

  • 是的,抱歉,这在 SSCCE 中是错误的,但实际代码包含您编写的内容并导致梯形出现问题。那么,这是否足以居中...或者如果我已正确翻译,我的代码中是否还有其他问题导致问题?
  • @pinkpanther 是的,这足以居中。您可能确实在重复使用不同形状的 Point 对象,就像 Mel Nicholson 提到的那样,但也许这也只是您的 SSCCE 中的一个错字?
【解决方案3】:

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

a.y=0;

对此:

a.y=height/2;

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

【讨论】:

  • (好吧,现在别再用头撞墙了。这发生在我们最好的人身上(或者我被告知:P)。)
  • 没关系,有没有其他东西阻止我的梯形居中....
  • @pinkpanther:实际上是你的菱形没有居中。请参阅我的更新答案。 (你的梯形放置得很好。)
  • 谢谢,效果很好,但为什么呢?当我只是相对于边界矩形放置时,为什么这很重要?我的错,这里是午夜,我说的是梯形而不是菱形....
  • 查看我更新的答案以获得简短的解释(如果没有意义,请告诉我,我会尝试更好地解释它)。
猜你喜欢
  • 1970-01-01
  • 2021-07-17
  • 2022-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-26
  • 2011-11-11
  • 2010-11-02
相关资源
最近更新 更多