【问题标题】:How to paint components in layers in Java?如何在 Java 中分层绘制组件?
【发布时间】:2018-12-30 20:23:28
【问题描述】:

我在为我的应用程序的图形部分编码时遇到了很大的问题,我需要将组件放在一起:

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

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

  3. JPanel 组件之一上,我想绘制固定形状 - 矩形、车道等。这里我有一个问题,我有两个类:一个扩展 JPanel 并且是这部分的背景,第二个扩展JComponent 并代表我绘制的元素(有几个元素)。我不知道如何在JPanel 中绘制元素 - 我尝试了几种方法,但没有任何结果。对我来说很重要的一点是,JComponents 应该只用这个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 点的问题,因为我不能在背景上放置黑色矩形并在顶部放置移动矩形。

我将不胜感激所有帮助:)

【问题讨论】:

    标签: java swing graphics jframe jpanel


    【解决方案1】:

    您不需要(也不应该)从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 的paint 方法,以在该面板上绘制矩形:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 2013-11-08
      • 2021-01-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多