Drawing in JLayeredPane outside JPanels

I am working on a chess game. I want the Container board to use GridLayout to display an 8x8 grid from JPanels. (This will make functions such as highlighting selected squares and actual moves much easier.) Then I would like to add fragments on top of this layer so that they can be dragged and dropped. At first, I had shapes depicting them, drawing them in a separate JPanels square, but thought this would be a problem when trying to drag them later. Since then, I have been trying to use JLayeredPane as the main container, but have encountered several problems.

One of them is that after I set the GridLayout for the JLayeredPane, no matter which Integer I use to specify the layer to add JLabel or another image, the pieces are added to the grid, making their positions set and distort the whole board . I read that using LayoutManagers can interfere with the positioning of a layer on a JLayeredPane, so this is not too surprising. (Although the Oracle demo from the JLayeredPane tutorial seems to do it very well: http://download.oracle.com/javase/tutorial/uiswing/examples/components/LayeredPaneDemo2Project/src/components/LayeredPaneDemo2.java )

However, I also tried to put the JPanels grid in my own JPanel and then add it to the low JLayeredPane, the idea is that I could add drag and drop icons for splitting, opaque JPanels at the higher JLayeredPane. However, when I do this, after I just have a JPanel mesh inside the JLayeredPane (i.e., before adding a drag layer), the mesh will not be displayed.

I also tried to override the JLayeredPane paintComponent (and paint) methods to paint the pieces, but they are hidden by JPanels (I see that they really exist by setting JPanels to opaque) and as far as I can tell, there is no way to set the graphics layer on JLayeredPane. I also tried using a glass frame to draw shapes, but there was also unwanted behavior there.

Any help explaining some of this behavior, or when I am wrong, will be greatly appreciated!

+6
source share
1 answer

Here is a simple example that shows how you can (accidentally) drag a โ€œchess pieceโ€ from one square to another:

import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; public class ChessBoard extends JFrame implements MouseListener, MouseMotionListener { JLayeredPane layeredPane; JPanel chessBoard; JLabel chessPiece; int xAdjustment; int yAdjustment; public ChessBoard() { Dimension boardSize = new Dimension(600, 600); // Use a Layered Pane for this this application layeredPane = new JLayeredPane(); layeredPane.setPreferredSize( boardSize ); layeredPane.addMouseListener( this ); layeredPane.addMouseMotionListener( this ); getContentPane().add(layeredPane); // Add a chess board to the Layered Pane chessBoard = new JPanel(); chessBoard.setLayout( new GridLayout(8, 8) ); chessBoard.setPreferredSize( boardSize ); chessBoard.setBounds(0, 0, boardSize.width, boardSize.height); layeredPane.add(chessBoard, JLayeredPane.DEFAULT_LAYER); // Build the Chess Board squares for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { JPanel square = new JPanel( new BorderLayout() ); square.setBackground( (i + j) % 2 == 0 ? Color.red : Color.white ); chessBoard.add( square ); } } // Add a few pieces to the board ImageIcon duke = new ImageIcon("dukewavered.gif"); // add an image here JLabel piece = new JLabel( duke ); JPanel panel = (JPanel)chessBoard.getComponent( 0 ); panel.add( piece ); piece = new JLabel( duke ); panel = (JPanel)chessBoard.getComponent( 15 ); panel.add( piece ); } /* ** Add the selected chess piece to the dragging layer so it can be moved */ public void mousePressed(MouseEvent e) { chessPiece = null; Component c = chessBoard.findComponentAt(e.getX(), e.getY()); if (c instanceof JPanel) return; Point parentLocation = c.getParent().getLocation(); xAdjustment = parentLocation.x - e.getX(); yAdjustment = parentLocation.y - e.getY(); chessPiece = (JLabel)c; chessPiece.setLocation(e.getX() + xAdjustment, e.getY() + yAdjustment); layeredPane.add(chessPiece, JLayeredPane.DRAG_LAYER); layeredPane.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); } /* ** Move the chess piece around */ public void mouseDragged(MouseEvent me) { if (chessPiece == null) return; // The drag location should be within the bounds of the chess board int x = me.getX() + xAdjustment; int xMax = layeredPane.getWidth() - chessPiece.getWidth(); x = Math.min(x, xMax); x = Math.max(x, 0); int y = me.getY() + yAdjustment; int yMax = layeredPane.getHeight() - chessPiece.getHeight(); y = Math.min(y, yMax); y = Math.max(y, 0); chessPiece.setLocation(x, y); } /* ** Drop the chess piece back onto the chess board */ public void mouseReleased(MouseEvent e) { layeredPane.setCursor(null); if (chessPiece == null) return; // Make sure the chess piece is no longer painted on the layered pane chessPiece.setVisible(false); layeredPane.remove(chessPiece); chessPiece.setVisible(true); // The drop location should be within the bounds of the chess board int xMax = layeredPane.getWidth() - chessPiece.getWidth(); int x = Math.min(e.getX(), xMax); x = Math.max(x, 0); int yMax = layeredPane.getHeight() - chessPiece.getHeight(); int y = Math.min(e.getY(), yMax); y = Math.max(y, 0); Component c = chessBoard.findComponentAt(x, y); if (c instanceof JLabel) { Container parent = c.getParent(); parent.remove(0); parent.add( chessPiece ); parent.validate(); } else { Container parent = (Container)c; parent.add( chessPiece ); parent.validate(); } } public void mouseClicked(MouseEvent e) {} public void mouseMoved(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public static void main(String[] args) { JFrame frame = new ChessBoard(); frame.setDefaultCloseOperation( DISPOSE_ON_CLOSE ); frame.setResizable( false ); frame.pack(); frame.setLocationRelativeTo( null ); frame.setVisible(true); } } 
+7
source

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


All Articles