是否将 JLabel 添加到 JPanel “隐藏"?JPanel? [英] Does adding a JLabel to a JPanel "hide" the JPanel?

查看:33
本文介绍了是否将 JLabel 添加到 JPanel “隐藏"?JPanel?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

基本上我希望 JPanel 注册事件,而 JPanel 只在 JPanel 顶部显示文本.此外,面板具有背景颜色.

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

解决方案

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

1) JLayeredPane 包含所有内容并有一个 MouseAdapter,它被添加为 MouseListener 和 MouseMotionListener.

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 获取鼠标所在的点 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,那么它在 JLayeredPane 内的偏移量必须用于在调用 findComponentAt(p) 之前更正位置 Point, p 因为 MouseAdapter 将返回相对于 JLayeredPane 的点而不是董事会 JPanel.

例如:

import java.awt.*;导入 java.awt.event.*;导入 java.awt.image.BufferedImage;导入 javax.swing.*;公共类国际象棋2 {私有静态无效 createAndShowUI() {JFrame frame = new JFrame("Chess 2");frame.getContentPane().add(new Chess2Gui().getMainComponent());frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);框架.pack();frame.setLocationRelativeTo(null);frame.setVisible(true);}公共静态无效主(字符串 [] args){java.awt.EventQueue.invokeLater(new Runnable() {公共无效运行(){createAndShowUI();}});}}类 Chess2Gui {私有静态最终 int RANKS = 8;私有静态最终 int 文件 = 8;私有静态最终颜色 DARK_COLOR = new Color(0, 100, 0);私有静态最终颜色 LIGHT_COLOR = new Color(200, 200, 200);私有静态最终颜色 DARK_PIECE_COLOR = Color.black;私有静态最终 int SQR_WIDTH = 80;私有静态最终 int PIECE_WIDTH = 60;私有静态最终维度 SQR_SIZE = 新维度(SQR_WIDTH,SQR_WIDTH);私人 JLayeredPane mainLayeredPane = new JLayeredPane();私人 JPanel 板 = new JPanel(new GridLayout(RANKS, FILES));private JPanelSquare[][] jPanelSquareGrid = new JPanelSquare[RANKS][FILES];公共 Chess2Gui() {for (int rank = 0; rank 

If I have a few JPanels in a GridLayout, each one with a MouseAdapter, and then create JLabels (with text) and add to each one of the JPanels. Note the JLabels have no listeners. If I render this and try to click on a JPanel, or, ultimately try to click on the JLabel, will the MouseAdapter register that as an event?

Basically I want the JPanels to register events and the JPanels to just display text on-top of the JPanels. Also, the panels have background color.

If the JLabel does "hide" the events from registering, how can I go around this?

解决方案

The top component will get the mouse click. How much the JLabel will cover will depend on its size and on the JPanel's layout manager. One way is to give the listener to the JLabel (as has also been mentioned above), but another way to do it is as I describe below, and while perhaps not the best way, it worked well for me:

1) A JLayeredPane holds everything and has a MouseAdapter that is added as a MouseListener and MouseMotionListener.

2) A JPanel, called "board", that uses GridLayout(8, 8) and is the exact size as the JLayeredPane is added to the layered pane's bottom layer, or to be precise, the JLayeredPane.DEFAULT_LAYER.

3) This JPanel holds 64 other small JPanel squares in the GridLayout (actually the squares extend from JPanel), and each uses GridBagLayout.

4) The chess pieces are JLabels and are held by the JPanel squares.

5) In the MouseAdapter mousePressed method, I get the Point, p, that the mouse is located at via e.getPoint (if e is the MouseEvent object passed to the method). I then find out which square holds this point by calling findComponentAt(p) on the board JPanel. I then check to see if this square holds a piece. If so, the piece is removed from the square and added directly to the JLayeredPane's JLayeredPane.DRAG_LAYER.

6) If a chess piece is held in the JLayeredPane's JLayeredPane.DRAG_LAYER the MouseAdapter's mouseDragged method will control the piece's location.

7) On mouseRelease, I again find out which square holds the mouse's location or Point by the same technique as above, using findComponentAt(p) and if it is a valid square, I remove the chess piece from the JLayeredPane's JLayeredPane.DRAG_LAYER and place it in the square. If it's off the board or not a valid square, I return the chess piece to the original location.

Note that if the board JPanel doesn't completely fill the JLayeredPane, then its offset within the JLayeredPane must be used to correct the location Point, p before calling findComponentAt(p) since the MouseAdapter will return Points relative to the JLayeredPane not the board JPanel.

For example:

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;
    }

}

这篇关于是否将 JLabel 添加到 JPanel “隐藏"?JPanel?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆