java - 如何在Java中分层绘制组件?

标签 java swing graphics jframe jpanel

我在对应用程序的图形部分进行编码时遇到了很大的问题,我需要将组件一个一个地放在另一个之上:

  1. 首先我有 JFrame (固定大小)

  2. 其中我有两个 JPanel 组件。我希望它们有彩色背景。 这是简单的部分。

  3. JPanel 组件之一上,我想绘制固定形状 - 矩形、车道等。这里我遇到问题,我有两个类:一个扩展 JPanel 是这部分的背景,第二个扩展了 JComponent 并表示我绘制的元素(有多个元素)。我不知道如何在 JPanel 中绘制元素 - 我尝试了几种方法,但什么也没有显示。对我来说很重要的是,JComponent 应该仅与此 JPanel 绘制和连接,而不是与整个框架连接。

  4. 最重要的是,我想要有移动的形状。当我只有框架(比如说矩形)时,这很容易,因为我只更改位置并调用 repaint() 方法,但如何做到这一点才能使移动形状连接到并位于 内部JPanel 并将之前的图层保留在其位置?

在我的尝试中,我创建了一些带有矩形的类:

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;

public class Main{
    public Main() {
        JFrame frame = new JFrame();
        frame.setSize(1200, 900);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        JPanel background = new JPanel();
        background.setBackground(Color.lightGray);

        GreenRect gr = new GreenRect();
        gr.setPreferredSize(new Dimension(500,800));
        background.add(gr, BorderLayout.WEST);


        RedRect rr = new RedRect();
        rr.setPreferredSize(new Dimension(500,800));
        background.add(rr, BorderLayout.EAST);

        frame.add(background);
    }

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

class GreenRect extends JPanel {
    ArrayList<BlackRect> r = new ArrayList<>();
    ArrayList<MovingRec> m = new ArrayList<>();

   public GreenRect() {
       setBackground(Color.green);
       addRec(10,10);
       addRec(50,50);
       addRec(100,100);
       addRec(1000,1000);
   }

   public void addRec(int x, int y) {
       r.add(new BlackRect(x,y));
   }
}


class RedRect extends JPanel {
    public RedRect() {
        setBackground(Color.red);
    }
}

class BlackRect extends JComponent {
    int x, y;
    int w = 100, h = 100;

    public BlackRect (int x, int y){
        this.x = x;
        this.y = y;
    }

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

        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.BLACK);
        g2d.fillRect(x, y, w, h);
    }
}

class MovingRec  extends JComponent {
    int x, y;
    int w = 20, h = 20;

    public MovingRec (int x, int y){
        this.x = x;
        this.y = y;
    }

    public void paintComponent(Graphics g) {
        super.paintComponents(g);

        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.BLUE);
        g2d.fillRect(x, y, w, h);
    }

    public void update() {
        x += 5;
        y += 5;
    }
}

现在我在第 3 点和第 4 点上遇到了问题,因为我无法在背景上放置黑色矩形并在顶部移动矩形。

我将感谢所有帮助:)

最佳答案

您不需要(也不应该)从 JComponent 扩展 BlackRectMovingRect

例如,BlackRect 可以是一个简单的对象,例如:

class BlackRect {
    int x, y;
    int w = 100, h = 100;

    public BlackRect(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void paint(Graphics2D g2d) {
        g2d.setColor(Color.BLACK);
        g2d.fillRect(x, y, w, h);
    }
}

您应该重写GreenRect的绘制方法,以在该面板上绘制矩形:

public GreenRect extends JPanel {
    // Existing members 

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

        Graphics2D g2d = (Graphics2D) g;

        for (BlackRect black_rect : r) {
            black_rect.paint(g2d);
        }

        // Also paint list of moving rectangles here
    }
}

当调用GreenRect.repaint()时,它将绘制其背景,以及r(和m)列表中的所有矩形,当您添加该代码)。如果 m 个矩形的位置已更新,它们将绘制在新位置,因此它们看起来像是在移动。由于移动矩形是最后绘制的,因此它们将出现在“顶部”。

使用 Swing Timer来驱动动画。当计时器到期时,它应该稍微移动所有移动矩形(即调用 MovingRec.update()),并在 GreenRect< 上调用 repaint()/.

关于java - 如何在Java中分层绘制组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53981141/

相关文章:

java - 为什么它打印 "tostring"两次?

iOS - 计算区域中颜色的百分比

linux - 通过 mesa 在旧硬件上运行 OpenGL 程序

java - 修改我的java swing计算器的图形

java - Java 类 java.util.ArrayList 的消息体编写器

java - Jackson:有没有办法在 boolean 反序列化中忽略 0/1?

Java TCP套接字接受停止运行代码

java - 如何在向模型添加行时更改 JTable 行背景颜色?

java - 将对象添加到 JList 以在滚动 Pane 上显示时遇到问题

java - 如何通过按空格键切换 JPanel