如何在下一个矩形上绘制矩形?

d4so4syb  于 2021-07-08  发布在  Java
关注(0)|答案(2)|浏览(389)

使用javaswing,我有一条水平线(作为地平线)。我想画矩形,堆叠,一个在另一个上面,最大宽度的矩形在底部,最小宽度的矩形在顶部。当用户重新调整屏幕大小时,我还希望矩形保持在地平线上。这是我到目前为止的计算结果:

package testing;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Test extends JFrame {
    private static final int FRAME_WIDTH = 600;
    private static final int FRAME_HEIGHT = 500;

    public static void main(String[] args) {
        new Test();
    }

    protected Test() {
        this.setTitle("Tower of Hanoi");
        this.setSize(FRAME_WIDTH, FRAME_HEIGHT);
        this.setPreferredSize(new Dimension(FRAME_WIDTH, FRAME_HEIGHT));
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setMinimumSize(new Dimension(FRAME_WIDTH, FRAME_HEIGHT));
        this.setMaximumSize(new Dimension(FRAME_WIDTH, FRAME_HEIGHT));
        this.setSize(new Dimension(FRAME_WIDTH, FRAME_HEIGHT));
        this.setBackground(Color.BLUE);
        this.add(new PanelTest(), BorderLayout.CENTER);
        this.setVisible(true);
    }

    public class PanelTest extends JPanel {

        private static final int FRAME_WIDTH = 600;
        private static final int FRAME_HEIGHT = 500;

        protected PanelTest() {
            setLayout(new BorderLayout());
            this.setSize(FRAME_WIDTH, FRAME_HEIGHT);
            this.setMinimumSize(new Dimension(FRAME_WIDTH, FRAME_HEIGHT));
            this.setMaximumSize(new Dimension(FRAME_WIDTH, FRAME_HEIGHT));
            this.setBackground(Color.CYAN);
            this.add(new ComponentTest(), BorderLayout.CENTER);
            revalidate();
            repaint();
            this.setVisible(true); //probably not necessary

        }
    }

    public class ComponentTest extends JComponent {
        private List<Rectangle> rects; 

        public ComponentTest() {
            rects = new ArrayList<>(); 
            rects.add(new Rectangle(30, 30, 30, 30));
            rects.add(new Rectangle(30, 30, 30, 30));
            rects.add(new Rectangle(30, 30, 30, 30));
            rects.add(new Rectangle(30, 30, 30, 30));
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D graph2 = (Graphics2D) g;
            graph2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            paint(g);
        }

        public void paint(Graphics g) {
            // Draw the platform
            g.drawLine(100, getHeight() - 100, getWidth() - 100, getHeight() - 100);

            for(int i = 0; i < rects.size(); i++) {
                rects.get(i).setBounds(getWidth()/2,
                        (30 * i + 1),
                        30 * i + 1,
                        30
                        );
                g.drawRect(rects.get(i).x, rects.get(i).y, rects.get(i).width, rects.get(i).height);
            }
        }
    }
}

这将使矩形堆叠起来,但浮动在屏幕顶部附近:

我怎样才能让它粘在黑色的地平线上?换句话说,如何让最大的矩形停留在黑线之上?此外,当屏幕被拖动到一个更大的尺寸-我如何增长所有的矩形高度(平等)和它仍然坚持在黑色的地平线?
还要注意的是,被绘制的矩形的数量是由用户决定的(在本例中是5,但最多可以是9)。
执行此操作也无法按预期工作:

for(int i = 0; i < rects.size(); i++) {
        rects.get(i).setBounds(getWidth()/2,
                (30 * i + 1),
                getHeight() - 100 - (30 * (rects.size() - (i + 1))),
                30
                );
        g.drawRect(rects.get(i).x, rects.get(i).y, rects.get(i).width, rects.get(i).height);
    }
1sbrub3j

1sbrub3j1#

因此,如果每个条的高度为30,那么这就是每个rect需要开始的像素高度:
getheight()-100-(30count(rects))
getheight()-100-(30
(count(rects)-1))。。。
getheight()-100-(30*(计数(矩形)-4))
所以,对于第n个矩形, getHeight() - 100 - (30 * (count(rects) - d.getNumber())) 我不确定在调整大小时是否可以工作,但是您可能必须插入正确的生命周期事件才能工作。正如上面的评论所提到的,一个可重复性很低的例子将有可能提供更多帮助

brccelvz

brccelvz2#

你不需要上课 ComponentTest . 你只需要上课 PanelTest 你只需要重写方法 paintComponent() 在课堂上 PanelTest . 请参阅执行自定义绘制。
如果你确定地平线的位置 PanelTest 然后你需要画出相对于地平线的矩形。这个 x 每个矩形的坐标和高度是一样的,所以您只需要计算宽度(您已经正确地计算了)和宽度 y 协调。
这意味着 y 最底部矩形的坐标,即接触地平线的矩形,必须是 y 地平线的坐标减去矩形的高度。
这个 y 最底部矩形正上方矩形的坐标必须为 y 地平线的坐标减去矩形高度的两倍,因为每个矩形的高度相同。
其余的矩形也是如此。
这是我重写的课文 PanelTest . 就像我说的,不用上课 ComponentTest 我也没有改变课程 Test .
请注意,由于您正在绘制矩形,因此使用抗锯齿没有任何区别。当你画曲线或斜线的时候会有不同。也不需要上课 Graphics2D 因为你不使用那个类的任何方法。

public class PanelTest extends JPanel {
    private static final int FRAME_WIDTH = 600;
    private static final int FRAME_HEIGHT = 500;

    private List<Rectangle> rects;

    protected PanelTest() {
        rects = new ArrayList<>();
        rects.add(new Rectangle(30, 30, 30, 30));
        rects.add(new Rectangle(30, 30, 30, 30));
        rects.add(new Rectangle(30, 30, 30, 30));
        rects.add(new Rectangle(30, 30, 30, 30));
        this.setPreferredSize(new Dimension(FRAME_WIDTH, FRAME_HEIGHT));
        this.setMinimumSize(new Dimension(FRAME_WIDTH, FRAME_HEIGHT));
        this.setMaximumSize(new Dimension(FRAME_WIDTH, FRAME_HEIGHT));
        this.setBackground(Color.CYAN);
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.drawLine(100, getHeight() - 100, getWidth() - 100, getHeight() - 100);

        for (int i = 0; i < rects.size(); i++) {
            rects.get(i).x = getWidth() / 2;
            rects.get(i).y = getHeight() - 100 - (30 * (rects.size() - i));
            rects.get(i).width = 30 * i + 1;
            rects.get(i).height = 30;
            g.drawRect(rects.get(i).x, rects.get(i).y, rects.get(i).width, rects.get(i).height);
        }
    }
}

相关问题