Java Swing 将 JPanel 添加到 JPanel

2023-12-24

情况

我目前正在尝试使用 Java 的 Swing 构建 2D 游戏。为此,我有我的主课Puzzle这是子类化JFrame。在我的框架中,我添加了我的主要内容JPanel它由几个组成JPanel添加在一起(每个都是一个新的部分)。

EDIT 2: PlayingField是我的模型,它将存储每件作品的当前位置。 人们可以用鼠标选择一块(计划是突出显示它)并用箭头键移动它,只要下一步(完整的单元格,因此大约 100 像素)不是另一个的位置件。截至目前,PlayingField由于碎片丢失,因此不存储任何数据。

private void createAndShowGui() {
    // The playing-field with a 4x6 grid.
    PlayingField field = new PlayingField(4, 6);
    JPanel mainPanel = new ComputerView(field);
    
    setTitle("Puzzle");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(400, 600);
    add(mainPanel);
    setVisible(true);
}

上面的方法将创建我的框架并添加主面板。以下方法是我的主面板,其中添加了几个JPanel到它自己。

public ComputerView(PlayingField field) {
    this.field = field;
    this.setLayout(null);

    JPanel topLeft = new GamingPiece(PlayingField.TOP_LEFT);
    add(topLeft);
    
    JPanel topRight = new GamingPiece(PlayingField.TOP_RIGHT);
    add(topRight);
    
    JPanel bottomLeft = new GamingPiece(PlayingField.BOTTOM_LEFT);
    add(bottomLeft);
}

Each GamingPiece或者更确切地说我的子JPanel正在绘制一个基本部分(我只绘制一个并旋转其他部分,因为所有部分都由相同的任意形状组成)。这GamingPiece类也是子类JPanel并调用JPanel#paintComponent()绘制该作品的方法。

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

    g2.setColor(Color.YELLOW);
    g2.fillPolygon(pieceX, pieceY, pieceX.length);
}

问题和我的疑问

因为我对 Java 还很陌生,所以我真的不知道如何正确地做到这一点。如果我通过创建一个新对象并将其添加到主面板来添加我的作品,它不会显示所有作品,只会显示最后添加的作品。有些甚至似乎不起作用,即使它们是唯一添加的(解释我的情况:我有相同任意形状的部分,只是旋转不同但使用Graphics2D#rotate()似乎工作不太好)。

我希望我能很好地解释我的情况和问题,让你们能够帮助我。提前致谢!

EDIT:

My Codes

拼图.java

package programming.schimmler;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import programming.schimmler.model.PlayingField;
import programming.schimmler.view.ComputerView;

public class Puzzle extends JFrame {
    
...
Invoking the createAndShowGui()
...
    
private void createAndShowGui() {
    // The playing-field with a 4x6 grid.
    PlayingField field = new PlayingField(4, 6);
    JPanel mainPanel = new ComputerView(field);
    
    setTitle("Puzzle");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(400, 600);
    add(mainPanel);
    setVisible(true);
    }
}

计算机视图.java

package programming.schimmler.view;

import java.util.HashSet;
import java.util.Set;

import javax.swing.JPanel;

import programming.schimmler.model.PlayingField;

public class ComputerView extends JPanel {

...
Instance variables
....

public ComputerView(PlayingField field) {
    this.field = field;
    this.setLayout(null);

    JPanel topLeft = new GamingPiece(PlayingField.TOP_LEFT);
    add(topLeft);
    
    JPanel topRight = new GamingPiece(PlayingField.TOP_RIGHT);
    add(topRight);
    
    JPanel bottomLeft = new GamingPiece(PlayingField.BOTTOM_LEFT);
    add(bottomLeft);
    }
}

GamingPiece.java

package programming.schimmler.view;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JPanel;

import programming.schimmler.model.PlayingField;

/**
 * 
 */
public class GamingPiece extends JPanel {

...

public GamingPiece(int type) {
    switch (type) {
    // Need to draw each polygon from different coordinates since rotating did not work yet.
    case PlayingField.TOP_LEFT:
        pieceX = new int[] { 100, 100, 300, 300, 200, 200, 100 };
        pieceY = new int[] { 100, 100, 100, 200, 200, 300, 300 };
        break;
    case PlayingField.TOP_RIGHT:
        pieceX = new int[] { 400, 400, 300, 300, 200, 200 };
        pieceY = new int[] { 0, 200, 200, 100, 100, 0 };
        break;
    case PlayingField.BOTTOM_LEFT:
        pieceX = new int[] { 0, 200, 200, 100, 100, 0 };
        pieceY = new int[] { 400, 400, 300, 300, 200, 200 };
        break;
    case PlayingField.BOTTOM_RIGHT:
        pieceX = new int[] { 400, 400, 300, 300, 200, 200 };
        pieceY = new int[] { 400, 200, 200, 300, 300, 400 };
        break;
    case PlayingField.SQUARE:
        pieceX = new int[] { 100, 300, 300, 100 };
        pieceY = new int[] { 100, 100, 300, 300 };
        break;
    }
    
    setLayout(null);
}

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

    g2.setColor(Color.YELLOW);
    g2.fillPolygon(pieceX, pieceY, pieceX.length);
    }
}

上面这些类是only与我的 GUI 交互的类,没有其他类参与。


你试图添加使事情变得过于复杂JPanel拼图给你JPanel拼图板。非矩形拼图的问题很快就会变得明显,例如TOP_LEFT形状,其右下侧有一个切口。当需要重叠拼图块时,为了将切掉的部分安装在一起,后来添加的拼图将遮挡之前绘制的拼图。

例如,如果您尝试将 TOP_LEFT 块 (A) 和 BOTTOM_RIGHT 块 (B) 嵌套在一起。

 AAAAAA BBB   
 AAAAAA BBB
 AAA BBBBBB
 AAA BBBBBB

你只会看到:

+---+------+
|AAA|   BBB|
|AAA|   BBB|
|AAA|BBBBBB|
|AAA|BBBBBB|
+---+------+

重叠区域将仅由其中一个面板绘制。 B 块的整个区域(包括空白区域)将绘制在第二块区域中,位于 A 块希望显示的内容之上。

您也许可以通过设置来解决这个问题JPanel保持透明,不打电话super.paintComponent()它将整个组件绘制为背景颜色。但你仍然需要在上面画出形状JPanel,并定位JPanel正确地放在父母身上JPanel.

忘记面板中的面板吧!只是draw父级上的碎片JPanel.

Example:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Puzzle {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(Puzzle::new);
    }

    private final static int shape_x[] = { -100, 100, 100, 0, 0, -100 };
    private final static int shape_y[] = { -100, -100, 0, 0, 100, 100 };

    public Puzzle() {
        JFrame frame = new JFrame("Puzzle");
        frame.setSize(600, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        View view = new View();
        frame.setContentPane(view);

        Shape l_shape = new Polygon(shape_x, shape_y, shape_x.length);
        view.pieces.add(new Piece(Color.YELLOW, l_shape,   0, 100, 100));
        view.pieces.add(new Piece(Color.GREEN,  l_shape, 180, 300, 300));
        view.pieces.add(new Piece(Color.RED,    l_shape,  65, 450, 145));

        frame.setVisible(true);
    }

}

@SuppressWarnings("serial")
class View extends JPanel {

    final List<Piece> pieces = new ArrayList<>();

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

        Graphics2D gc = (Graphics2D) g;
        for (Piece piece : pieces)
            piece.draw(gc);
    }
}

class Piece {
    final Color color;
    final Shape shape;
    final int angle;

    int x, y;   // Move pieces by by changing these

    Piece(Color color, Shape shape, int angle, int x, int y) {
        this.color = color;
        this.shape = shape;
        this.angle = angle;
        this.x = x;
        this.y = y;
    }

    void draw(Graphics2D gc) {
        AffineTransform tf = gc.getTransform();
        gc.translate(x, y);
        gc.rotate(Math.toRadians(angle));
        gc.setColor(color);
        gc.fill(shape);
        gc.setTransform(tf);
    }
}

请注意,这也是一个最小、完整且可验证的示例。最小:无package陈述;没有额外的HashSet and Set未使用的进口;除了展示 3 个游戏块外,不会尝试做任何事情。它是完整的:您可以编译并运行一个文件。它是可验证的:您可以运行它并看到它显示 3 个游戏块。

作为奖励,它显示Graphics2D.rotate()工作中,其中一个旋转 180°,另一个旋转角度不适合您的拼图,但有助于演示旋转效果很好。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java Swing 将 JPanel 添加到 JPanel 的相关文章

随机推荐

  • Javascript - 清除数组对象中的重复项

    你好 我有一个 javascript 数组对象 表示在给定国家 地区销售的商品数量 如下所示 var data c1 USA c2 Item1 c3 100 c1 Canada c2 Item1 c3 120 c1 Italy c2 Ite
  • 日期挑选和寻找差异

    我是使用 Netbeans 进行 Java 编程的新手 我已将 jCalendar 添加到我的 GUI 中以选择日期 我已在 jCalendar 按钮的 事件 gt 属性更改 代码中输入了这一行 Date date jcalendar1 g
  • 显示 scipy 树状图的簇标签

    我正在使用层次聚类来对词向量进行聚类 并且我希望用户能够显示显示聚类的树状图 然而 由于可能有数千个单词 我希望这个树状图被截断为一些合理的有价值的 每个叶子的标签是该簇中最重要的单词的字符串 我的问题是 根据文档 http student
  • ionic 2:在 3x3 表格中显示项目数组

    我有一个项目数组 我想在 3x3 表格中显示 如下所示 为了实现这一点 我将数组切成 3 个数组 每组 3 个 并显示如下
  • Android J2ME 或 Java SE 中使用的是哪个版本的 Java?

    Android J2ME 或 Java SE 中使用的是哪个版本的 Java 每个人都在这里 但让我稍微澄清一下整个过程 它是如何工作的 我们使用标准 J2SE 发行版中的普通 Java 编译器并生成 class 文件 也称为 Java V
  • 如何在 ASP.NET MVC4 表中执行简单的多项选择

    这是我的观点 model Affiliate div class box paint color 16 div class title h4 i class icon tasks i span Model CompanyName s Com
  • 以十六进制编码/解码字符串并返回

    给定一个可能包含任意字符 包括unicode字符 的字符串 如何将这个字符串转换为十六进制表示 然后反转得到这个字符串的十六进制 Use pack and unpack function hex2str hex return pack H
  • 在lua中表示unichar的方式是什么

    如果我需要以下 python 值 unicode char 0 gt gt gt unichr 0 u x00 我如何在Lua中定义它 没有一个 Lua 没有 Unicode 值的概念 Lua没有Unicode的概念at all 所有Lua
  • 使用 Java 创建 .eml(电子邮件)文件

    有人知道该怎么做吗 我获取了电子邮件的所有信息 正文 主题 发件人 收件人 抄送 密件抄送 并且需要从中生成 eml 文件 您可以使用以下代码创建 eml 文件 它可以与雷鸟以及其他电子邮件客户端一起正常工作 public static v
  • 如何从 Intellij IDEA 访问 cassandra 数据库

    我在2018年10月16日安装了intellij idea 2018 2 5 我正在尝试添加到面板 数据库 cassandra 为此 我转到 Intellij 中的 数据源和驱动程序 设置并添加 cassandra 的驱动程序 gt 图片来
  • 捕获图像,上传到 Firebase 并检索 Java Android Studio

    如果这可能是一个有简单解决方案的问题 我感到非常抱歉 我想做什么 从按钮捕获图像 将该图像上传到 Firebase 存储 在 ImageView 中检索该图像 到目前为止我遇到了什么麻烦 拍照 但当我单击勾号时崩溃 因此 没有任何内容被上传
  • 如何在黑莓手机中使用相机扫描图像?

    我已经开始了一个项目 我想在其中实现二维码扫描功能 举个例子 android 中的 ZXing 我想为黑莓操作系统 6 及更高版本实现 我想使用相机扫描实时图像 是否可以 如果是的话 那怎么可能呢 您必须使用条形码 API 它是针对 OS
  • 如何在 GAE 应用程序中执行异步 api 请求?

    我正在开发一个基于 GAE 和 python 2 7 13 的应用程序 我想做的是在处理程序内进行一堆异步 API 调用 像这样的东西 class MakeRequests webapp2 RequestHandler def post s
  • 根据页面位置更改背景颜色

    我只想根据滚动更改背景颜色 例如从红到蓝 该代码有效 但如何将灰色更改为颜色 http fiddle jshell net schmudde ffk6phq0 http fiddle jshell net schmudde ffk6phq0
  • 扩展图像字段以允许 pdf ( django )

    我的表单中有 ImageField 正如我发现的 它使用枕头来验证该文件实际上是一个图像 这部分很棒 但我也需要在此表单字段中允许 pdf 所以它应该检查文件是否是图像 如果不是 则检查它是否是pdf 然后加载并存储 如果 pdf 检查能够
  • 查找特定列中最后一行的更有效方法?

    我正在编写一个应用程序 它将把列从一张纸导入到另一张纸上 getLastRow 方法仅适用于整个工作表 但不能用于获取列的最后一行 存在请求此功能的问题 我在 Google Script Examples 的人员的 2D Array 库的帮
  • 将资源转换为 byte[]

    我在将图像资源转换为 byte 时遇到问题 例如 我有以下资源 pack application AppName component Assets Images sampleimage jpg 在我的程序中 如何将其转换为 byte 我尝试
  • 页面底部固定 div 停在给定位置的问题

    我们需要一个位于页面底部的页脚工具栏 并在页面滚动到某个区域下方时粘在该区域上 我们使用以下脚本实现了这一点 固定 div 位于页面底部并停止在给定位置 https stackoverflow com questions 5141425 f
  • 在 R 中绘制巨大的数据文件?

    我有一个大约有 2000 万行的输入文件 文件的大小约为1 2 G 无论如何我可以在R中绘制数据 有些列有类别 其中大多数是数字 我已经尝试使用大约 800K 行的一小部分输入文件的绘图脚本 但即使我有大约 8G 的 RAM 我似乎也无法绘
  • Java Swing 将 JPanel 添加到 JPanel

    情况 我目前正在尝试使用 Java 的 Swing 构建 2D 游戏 为此 我有我的主课Puzzle这是子类化JFrame 在我的框架中 我添加了我的主要内容JPanel它由几个组成JPanel添加在一起 每个都是一个新的部分 EDIT 2