将 JLabel 添加到 JPanel 是否会“隐藏”JPanel?

2023-11-22

如果我在 GridLayout 中有几个 JPanel,每个 JPanel 都有一个 MouseAdapter,然后创建 JLabels(带有文本)并添加到每个 JPanel 中。请注意,JLabels 没有侦听器。 如果我渲染它并尝试单击 JPanel,或者最终尝试单击 JLabel,MouseAdapter 会将其注册为事件吗?

基本上,我希望 JPanel 注册事件,并且 JPanel 仅在 JPanel 顶部显示文本。此外,面板还有背景颜色。

如果 JLabel 确实“隐藏”了事件注册,我该如何解决这个问题?


顶部组件将获得鼠标点击。 JLabel 将覆盖的范围取决于其大小和 JPanel 的布局管理器。一种方法是将侦听器提供给 JLabel(如上所述),但另一种方法是如我下面所述,虽然可能不是最好的方法,但它对我来说效果很好:

1) JLayeredPane 包含所有内容并具有作为 MouseListener 和 MouseMotionListener 添加的 MouseAdapter。

2) 一个名为“board”的 JPanel,它使用 GridLayout(8, 8),其大小与添加到分层窗格底层的 JLayeredPane 的大小完全相同,或者更准确地说,是 JLayeredPane.DEFAULT_LAYER。

3)这个JPanel在GridLayout中保存了64个其他小JPanel方块(实际上这些方块是从JPanel扩展而来的),并且每个都使用GridBagLayout。

4) 棋子是JLabels,由JPanel 方块保存。

5) 在 MouseAdapter mousePressed 方法中,我通过 e.getPoint 获取鼠标所在的 Point, p(如果 e 是传递给该方法的 MouseEvent 对象)。然后,我通过调用 JPanel 板上的 findComponentAt(p) 来找出哪个方块包含该点。然后我检查这个方块是否能容纳一块。如果是这样,则将该块从正方形中移除并直接添加到 JLayeredPane 的 JLayeredPane.DRAG_LAYER 中。

6) 如果棋子被放置在 JLayeredPane 的 JLayeredPane.DRAG_LAYER 中,MouseAdapter 的 mouseDragged 方法将控制棋子的位置。

7) 在 mouseRelease 上,我再次使用与上面相同的技术,使用 findComponentAt(p) 找出哪个方块保存了鼠标的位置或点,如果它是有效的方块,我从 JLayeredPane 的 JLayeredPane.DRAG_LAYER 中删除棋子并放置它在广场上。如果棋子不在棋盘上或者不是有效的方格,我会将棋子放回原来的位置。

请注意,如果板 JPanel 没有完全填充 JLayeredPane,则在调用 findComponentAt(p) 之前必须使用其在 JLayeredPane 内的偏移量来更正位置 Point, p,因为 MouseAdapter 将返回相对于 JLayeredPane 而不是板 JPanel 的 Points 。

例如:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class Chess2 {
    private static void createAndShowUI() {
        JFrame frame = new JFrame("Chess 2");
        frame.getContentPane().add(new Chess2Gui().getMainComponent());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                createAndShowUI();
            }
        });
    }
}

class Chess2Gui {
    private static final int RANKS = 8;
    private static final int FILES = 8;
    private static final Color DARK_COLOR = new Color(0, 100, 0);
    private static final Color LIGHT_COLOR = new Color(200, 200, 200);
    private static final Color DARK_PIECE_COLOR = Color.black;
    private static final int SQR_WIDTH = 80;
    private static final int PIECE_WIDTH = 60;
    private static final Dimension SQR_SIZE = new Dimension(SQR_WIDTH, SQR_WIDTH);

    private JLayeredPane mainLayeredPane = new JLayeredPane();
    private JPanel board = new JPanel(new GridLayout(RANKS, FILES));
    private JPanelSquare[][] jPanelSquareGrid = new JPanelSquare[RANKS][FILES];

    public Chess2Gui() {
        for (int rank = 0; rank < RANKS; rank++) {
            for (int file = 0; file < FILES; file++) {
                Color bkgd = DARK_COLOR;
                if (rank % 2 == file % 2) {
                    bkgd = LIGHT_COLOR;
                } 
                jPanelSquareGrid[rank][file] = new JPanelSquare(rank, file, bkgd);
                jPanelSquareGrid[rank][file].setPreferredSize(SQR_SIZE);
                board.add(jPanelSquareGrid[rank][file]);
            }
        }
        board.setSize(board.getPreferredSize());
        board.setLocation(0, 0);
        mainLayeredPane.add(board, JLayeredPane.DEFAULT_LAYER);
        mainLayeredPane.setPreferredSize(board.getPreferredSize());

        ImageIcon icon = new ImageIcon(ImageUtils2.createImage(PIECE_WIDTH, DARK_PIECE_COLOR));
        JLabel chessPiece = new JLabel(icon, SwingConstants.CENTER);

        jPanelSquareGrid[1][3].add(chessPiece);

        MyMouseAdapter mouseAdapter = new MyMouseAdapter();
        mainLayeredPane.addMouseListener(mouseAdapter);
        mainLayeredPane.addMouseMotionListener(mouseAdapter);

    }

    public JComponent getMainComponent() {
        return mainLayeredPane;
    }

    private class MyMouseAdapter extends MouseAdapter {
        private JLabel piece = null;
        private Point delta = null;
        private int oldRank = -1;
        private int oldFile = -1;

        @Override
        public void mousePressed(MouseEvent e) {
            Point p = e.getPoint();
            Component c = board.getComponentAt(p);
            for (int rank = 0; rank < jPanelSquareGrid.length; rank++) {
                for (int file = 0; file < jPanelSquareGrid[rank].length; file++) {
                    if (jPanelSquareGrid[rank][file] == c) {
                        if (jPanelSquareGrid[rank][file].getChessPiece() != null) {

                            // the jPanelSquares are derived from JPanel but have a 
                            // few of their own methods
                            piece = jPanelSquareGrid[rank][file].getChessPiece();
                            jPanelSquareGrid[rank][file].remove(piece);
                            oldRank = rank;
                            oldFile = file;
                            mainLayeredPane.add(piece, JLayeredPane.DRAG_LAYER);
                            int x = p.x - PIECE_WIDTH/2;
                            int y = p.y - PIECE_WIDTH/2;
                            piece.setLocation(x, y);

                            delta = new Point(p.x - x, p.y - y);
                            board.revalidate();
                            mainLayeredPane.repaint();
                            return;
                        }
                    }
                }
            }

            oldFile = -1;
            oldRank = -1;
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            if (piece != null) {
                Point p = e.getPoint();
                int x = p.x - delta.x;
                int y = p.y - delta.y;
                piece.setLocation(x, y);
                mainLayeredPane.revalidate();
                mainLayeredPane.repaint();
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            if (piece != null) {
                JPanelSquare sqr = (JPanelSquare) board.getComponentAt(e.getPoint());
                mainLayeredPane.remove(piece);
                if (sqr == null || !validMove(sqr)) {
                    jPanelSquareGrid[oldRank][oldFile].add(piece);
                } else {
                    sqr.add(piece);
                }

                piece = null;
                delta = null;

                oldRank = -1;
                oldFile = -1;

                board.revalidate();
                mainLayeredPane.repaint();
            }
        }

        // just a pawn's moves
        private boolean validMove(JPanelSquare sqr) {
            int rank = sqr.getRank();
            int file = sqr.getFile();

            if (file != oldFile) {
                return false;
            }
            if (oldRank == 1 && (rank != 2 && rank != 3)) {
                return false;
            }
            if (oldRank != 1 && rank != oldRank + 1) {
                return false;
            }
            return true;
        }
    }
}

@SuppressWarnings("serial")
class JPanelSquare extends JPanel {
    private int rank;
    private int file;
    private JLabel chessPiece = null;

    public JPanelSquare(int rank, int file, Color bkgrnd) {
        this.rank = rank;
        this.file = file;
        setBackground(bkgrnd);
        setLayout(new GridBagLayout());
    }

    public int getRank() {
        return rank;
    }
    public int getFile() {
        return file;
    }

    @Override
    public Component add(Component c) {
        chessPiece = (JLabel)c;
        return super.add(c);
    }

    @Override
    public void remove(Component comp) {
        chessPiece = null;
        super.remove(comp);
    }

    public JLabel getChessPiece() {
        return chessPiece;
    }
}

class ImageUtils2 {

    public static BufferedImage createImage(int size, Color color) {
        BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = img.createGraphics();
        g2.setColor(color);
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
                    RenderingHints.VALUE_ANTIALIAS_ON);
        g2.fillOval(size/3, 0, size/3, size/3);
        g2.fillOval(size/4, size/4, size/2, 2*size/3);
        g2.fillOval(size/6, 2*size/3, 2*size/3, size/2);
        g2.dispose();
        return img;
    }

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

将 JLabel 添加到 JPanel 是否会“隐藏”JPanel? 的相关文章

  • 如何在Java 8中实现Elvis运算符?

    我有一个经典的 Elvis 运算符 案例 其中我调用每个可能返回 null 的方法并将它们链接在一起 thing nullableMethod1 a nullableMethod2 b nullableMethod3 在 Java 8 中
  • 设置 SWT Shell 的默认字体

    有没有办法为整个 Shell 设置默认字体 以便任何新控件都将使用相同的字体 看来现在我必须为我创建的每个控件设置字体 这导致了太多的冗余 默认使用的字体由平台选择 请参阅中的其他信息 类字体 SWT 标准小部件工具包 http book
  • 实现与扩展:何时使用?有什么不同?

    请用易于理解的语言进行解释或提供某些文章的链接 extends is for 延伸一类 implements is for 实施一个接口 接口和常规类之间的区别在于 在接口中您不能实现任何声明的方法 只有 实现 接口的类才能实现方法 C 中
  • 使用 Android WebViewClient 启用特定 SSL 协议

    我的应用程序使用WebViewClient与服务器建立 SSL 连接 服务器配置为仅接受 TLSv1 1 及以上协议 使用 Android 时 如何检查哪些 SSL 协议是 a 支持的和 b 默认启用的WebViewClient在设备上 如
  • 静态方法的 Java 内存模型

    我来自操作系统和 C 语言背景 在代码编译时 世界很简单 需要处理和理解堆栈 堆文本部分等 当我开始学习 Java 时 我确实了解 JVM 和垃圾收集器 我对静态方法感到很有趣 根据我的理解 类的所有实例都会在堆中创建 然后被清理 但是 对
  • @OneToMany 与 @JoinTable 错误

    我试图理解 OneToMany with JoinTable 对于这样的场景 我正在使用 JPA 2 1 Hibernate 5 0 4 和 Oracle 11 XE 当我打电话时userDao save user 下面的代码 我有 jav
  • firebase推送通知错误Spring Boot服务器端

    我正在尝试从 Spring Boot 服务器端发送通知到客户端 android 服务器运行良好 一切都很好 2020 09 01 08 13 07 691 INFO 18941 restartedMain e DevToolsPropert
  • RSA SignatureException:签名长度不正确

    我在签署 rsa 签名时遇到问题 我有一个用私钥加密的签名 然而 当我尝试使用公钥验证它时遇到问题 我得到以下异常 java security SignatureException Signature length not correct
  • 从关卡堆栈中获取相对比例的数学

    为这个可怕的标题道歉 我花了 10 分钟试图用一句话来解释这一点 但失败了 虽然提示这个问题的应用程序是用Java Android 编写的 但我认为它非常通用并且适用于任何语言 欢迎使用伪代码 或简单的英语 回复 我不确定是否应该标记所有通
  • C# 中的协变和逆变

    首先我要说的是 我是一名正在学习 C 编程的 Java 开发人员 因此 我会将我所知道的与我正在学习的进行比较 我已经使用 C 泛型几个小时了 我已经能够在 C 中重现我在 Java 中知道的相同内容 除了几个使用协变和逆变的示例 我正在读
  • 从 sbt 程序集运行 uber jar 会导致错误:无法找到或加载主类

    我有一个使用 sbt 程序集插件打包为 uber jar 的 Spark 作业 这build sbt指定一个可运行的 main 作为生成的 uber jar 的目标 mainClass in assembly Some com foo Ba
  • Java:使用 Java.util.concurrent 线程访问读取线程串行端口

    我正在尝试编写一个 Java 串行设备驱动程序并想使用 对我来说是新的 java util concurrent包裹 我有一种发送数据包然后等待 ACK 的方法 我打算有炭 接收在不同的线程中运行 如果接收线程收到 ACK 它应该使用发送数
  • HTTP PUT 在 Java 中上传文件

    Edit 我想我已经弄清楚如何执行二进制数据部分 仔细检查代码 但我很确定我做对了 现在 当我尝试按照中所述完成上传时遇到新错误Vimeo API 文档 http vimeo com api docs upload streaming Ed
  • 是否可以为 azure blob 存储中的给定目录生成具有写入权限的 SAS(共享访问签名)

    我们的 blob 存储帐户结构 容器名称 simple 在这个容器内我们有 blob aa one zip aa two zip bb ss zip bb dd zip 是否可以生成对aa 目录 有写权限 但对bb 目录 没有访问权限的SA
  • 如何使用云打印打印Android活动显示

    我正在尝试将 Google 云打印实现到应用程序中 遵循集成指南 https developers google com cloud print docs android 我试图通过打印 google com 来保持基本 单击我创建的打印按
  • 我们可以使用 for-each 循环来迭代 Iterator 类型的对象吗? [复制]

    这个问题在这里已经有答案了 如果我们执行以下操作 我们会收到错误 class FGH public static Iterator reverse List list Collections reverse list return list
  • 我们可以有虚假中断吗?

    我正在创建一个任务轮询器 每分钟都会查找任务 它看起来像这样 public class Poller private final ExecutorService e Executors newSingleThreadExecutor pub
  • 如果抛出RuntimeException,是否可以将其作为异常捕获?

    如果我有一个try抛出一个块RuntimException子类 可以是后续的catch块将其捕获为Exception 具体来说 public class MyAppException extends RuntimeException In
  • java.io.EOFException:没有更多可用数据 - 预期结束标记 关闭开始标记

    我正在使用 xmpp 开发一个聊天应用程序 根据我们的要求 我们有三台服务器 Apache Tomcat 7 ejabbered 2 1 11 和 mysql 5 5 to run xmppbot on tomcat used below
  • H2 用户定义的聚合函数 ListAgg 不能在第一个参数上使用 DISTINCT 或 TRIM()

    所以我有一个 DB2 生产数据库 我需要在其中使用可用的函数 ListAgg 我希望使用 H2 的单元测试能够正确测试此功能 不幸的是H2不直接支持ListAgg 但是 我可以创建一个用户定义的聚合函数 import java sql Co

随机推荐