如何在 Java 中分层绘制组件?
How to paint components in layers in Java?
我对我的应用程序的图形部分进行编码时遇到了很大的问题,我需要将一个组件放在彼此之上:
首先我有JFrame
(固定大小)
其中我有两个 JPanel
组件。我希望他们有彩色背景。
这是最简单的部分。
我想在其中一个 JPanel
组件上绘制固定形状 - 矩形、车道等。这里我有问题,我有两个 类:一个延伸JPanel
是这部分的背景,第二个扩展 JComponent
代表我绘制的元素(有几个元素)。我不知道如何在 JPanel
中绘制元素 - 我尝试了几种方法但没有任何结果。对我来说很重要的是 JComponents 应该只用这个 JPanel
绘制和连接,而不是整个框架。
最重要的是我想要移动的形状。当我只有框架时很容易,比方说矩形,因为我只改变位置并调用 repaint()
方法,但是如何做到这一点才能使移动形状连接到 JPanel
并位于 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
扩展 BlackRect
和 MovingRect
。
例如,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()
我对我的应用程序的图形部分进行编码时遇到了很大的问题,我需要将一个组件放在彼此之上:
首先我有
JFrame
(固定大小)其中我有两个
JPanel
组件。我希望他们有彩色背景。 这是最简单的部分。我想在其中一个
JPanel
组件上绘制固定形状 - 矩形、车道等。这里我有问题,我有两个 类:一个延伸JPanel
是这部分的背景,第二个扩展JComponent
代表我绘制的元素(有几个元素)。我不知道如何在JPanel
中绘制元素 - 我尝试了几种方法但没有任何结果。对我来说很重要的是 JComponents 应该只用这个JPanel
绘制和连接,而不是整个框架。最重要的是我想要移动的形状。当我只有框架时很容易,比方说矩形,因为我只改变位置并调用
repaint()
方法,但是如何做到这一点才能使移动形状连接到JPanel
并位于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
扩展 BlackRect
和 MovingRect
。
例如,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()