Does JLabel add “hide” JPanel to JPanel?

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

Basically, I want JPanels to log events and JPanels to just display text on top of JPanels. In addition, the panels have a background color.

If JLabel "hides" events from registration, how can I get around this?

0
source share
2 answers

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

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

2) A JPanel called a “board” that uses GridLayout (8, 8) and is the exact size, since the JLayeredPane is added to the lower level layer of the laminated panel or, to be precise, JLayeredPane.DEFAULT_LAYER.

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

4) Chess pieces are JLabels and are held by JPanel squares.

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

6) If a chess piece is held in JLayeredPane JLayeredPane.DRAG_LAYER, the mouseDragged MouseAdapter method will control the location of the fragment.

7) On mouseRelease, I will again find out which square contains the location of the mouse or point using the same procedure as above using findComponentAt (p), and if it is a valid square, I will remove the chess piece from the JLayeredPane JLayeredPane. DRAG_LAYER and put it in a square. If it is off the board or not a valid square, I return the chess piece to its original place.

Note that if the JPanel board does not completely fill the JLayeredPane, then its offset in the JLayeredPane should be used to correct the location of Point, p before calling findComponentAt (p), because the MouseAdapter will return points relative to the JLayeredPane, not the JPanel board.

For instance:

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 = px - PIECE_WIDTH/2; int y = py - PIECE_WIDTH/2; piece.setLocation(x, y); delta = new Point(px - x, py - 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 = px - delta.x; int y = py - 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 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; } } 
+9
source

JLabels without mouse listeners will not consume mouse events - they are passed to JPanel. Here is an example:

 public class LabelOnPanel { public static void main(String[] args) { final JPanel mainPanel = new JPanel(new BorderLayout()); mainPanel.add(new JLabel("This is a JLabel covering the entire panel")); mainPanel.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { JOptionPane.showMessageDialog(mainPanel, "Panel received click"); } }); JFrame frame = new JFrame(); frame.setBounds(100, 100, 300, 300); frame.add(mainPanel, BorderLayout.CENTER); frame.setVisible(true); } } 
0
source

Source: https://habr.com/ru/post/893474/


All Articles