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

java swing-如何在下一个矩形上绘制一个矩形?,java,swing,Java,Swing,使用JavaSwing,我有一条水平线(充当地平线)。我想画一个叠在另一个上面的矩形,其中最大宽度的矩形在底部,最小宽度的矩形在顶部。我还希望当用户重新调整屏幕大小时,矩形保持在地平线上。这是我到目前为止的计算结果: package testing; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Gr

使用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);
            }
        }
    }
}
封装测试;
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Rectangle;
导入java.awt.RenderingHints;
导入java.util.ArrayList;
导入java.util.List;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共类测试扩展了JFrame{
专用静态最终整数帧_宽度=600;
专用静态最终整型框架高度=500;
公共静态void main(字符串[]args){
新测试();
}
受保护测试(){
本集标题为“河内之塔”;
此.setSize(框宽、框高);
此.setPreferredSize(新尺寸(框架宽度、框架高度));
此.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
此.setMinimumSize(新尺寸(框架宽度、框架高度));
此.setMaximumSize(新尺寸(框架宽度、框架高度));
此.setSize(新尺寸(框架宽度、框架高度));
这个.背景(颜色.蓝色);
添加(新的PanelTest(),BorderLayout.CENTER);
此.setVisible(true);
}
公共类PanelTest扩展了JPanel{
专用静态最终整数帧_宽度=600;
专用静态最终整型框架高度=500;
受保护面板测试(){
setLayout(新的BorderLayout());
此.setSize(框宽、框高);
此.setMinimumSize(新尺寸(框架宽度、框架高度));
此.setMaximumSize(新尺寸(框架宽度、框架高度));
这是一个背景色(颜色为青色);
添加(newcomponenttest(),BorderLayout.CENTER);
重新验证();
重新油漆();
this.setVisible(true);//可能不需要
}
}
公共类ComponentTest扩展了JComponent{
私有列表矩形;
公共组件测试(){
rects=newarraylist();
添加(新的矩形(30,30,30,30));
添加(新的矩形(30,30,30,30));
添加(新的矩形(30,30,30,30));
添加(新的矩形(30,30,30,30));
}
@凌驾
受保护组件(图形g){
超级组件(g);
图形2d graph2=(图形2d)g;
graph2.setRenderingHint(renderingHits.KEY\u ANTIALIASING,renderingHits.VALUE\u ANTIALIAS\u ON);
油漆(g);
}
公共空间涂料(图g){
//画平台
g、 抽绳(100,getHeight()-100,getWidth()-100,getHeight()-100);
对于(int i=0;i
这将使矩形堆叠起来,但在屏幕顶部附近浮动:

我如何让它保持在黑色地平线上?换句话说,如何使最大的矩形位于黑线的顶部?此外,当屏幕被拖动到一个更大的尺寸时,我怎样才能使所有的矩形高度(相等)增长,并使其仍然停留在黑色的地平线上

还要注意的是,绘制的矩形数由用户决定(在本例中为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);
    }
for(int i=0;i
因此,如果每个条的高度为30,则这是每个矩形需要从以下位置开始的像素高度:

  • getHeight()-100-(30*计数(矩形))
  • getHeight()-100-(30*(计数(rects)-1))
  • getHeight()-100-(30*(计数(rects)-4))
  • 因此,对于第n个矩形,
    getHeight()-100-(30*(count(rects)-d.getNumber())


    我不确定在调整大小时这是否会起作用,但您可能必须插入正确的生命周期事件才能使其起作用。正如上面的评论中所提到的,一个可重复性最低的示例可以帮助您获得更多的帮助,您不需要class
    ComponentTest
    。您只需要class
    PanelTest
    ,并且只需要重写class
    PanelTest
    中的方法
    paintComponent()
    。参考

    如果在
    PanelTest
    中固定地平线的位置,则需要绘制相对于地平线的矩形。每个矩形的
    x
    坐标与高度相同,因此您只需要计算宽度(您已经正确地计算了宽度)和
    y
    坐标

    这意味着最底部矩形(即接触地平线的矩形)的
    y
    坐标需要是地平线的
    y
    坐标减去矩形的高度

    最底部矩形正上方矩形的
    y
    坐标需要是地平线的
    y
    坐标减去矩形高度的两倍,因为每个矩形