且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在JLayeredPane中绘制出超过JPanels

更新时间:2023-12-05 23:25:04

这是一个简单的例子,显示如何(随机)拖放棋子从一个广场到另一个广场:

  import java.awt。*; 
import java.awt.event。*;
import java.util。*;
import javax.swing。*;

public class ChessBoard扩展JFrame实现MouseListener,MouseMotionListener
{
JLayeredPane layeredPane;
JPanel chessBoard;
JLabel棋子;
int x调整;
int y调整;

public ChessBoard()
{
尺寸boardSize = new Dimension(600,600);

//为此应用程序使用分层窗格

layeredPane = new JLayeredPane();
layeredPane.setPreferredSize(boardSize);
layeredPane.addMouseListener(this);
layeredPane.addMouseMotionListener(this);
getContentPane()。add(layeredPane);

//将棋盘添加到分层窗格

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

//为(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);
}
}

//向板子添加几块

ImageIcon duke = new ImageIcon(dukewavered.gif); //在这里添加一个图像

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

/ *
**将所选的棋子添加到拖动图层,以便可以移动
* /
public void mousePressed(MouseEvent e)
{
chessPiece = null;
组件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));
}

/ *
**围绕
* /
移动棋子public void mouseDragged(MouseEvent me)
{
if(chessPiece == null)return;

//拖动位置应该在棋盘的边界内

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()+ y调整;
int yMax = layeredPane.getHeight() - chessPiece.getHeight();
y = Math.min(y,yMax);
y = Math.max(y,0);

chessPiece.setLocation(x,y);
}

/ *
**将棋子放回棋盘上
* /
public void mouseReleased(MouseEvent e)
{
layeredPane.setCursor(null);

if(chessPiece == null)return;

//确保棋子不再涂在分层窗格上

chessPiece.setVisible(false);
layeredPane.remove(chessPiece);
chessPiece.setVisible(true);

//放置位置应在棋盘的边界内

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

组件c = chessBoard.findComponentAt(x,y);

if(c instanceof JLabel)
{
容器parent = c.getParent();
parent.remove(0);
parent.add(chessPiece);
parent.validate();
}
else
{
容器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);
}
}


I am working on developing a Chess game. I want to have the board Container utilize a GridLayout to display an 8x8 grid of JPanels. (This will make functions such as highlighting selected squares and valid moves much easier.) I would then like to add the pieces over this layer so that they may be dragged and dropped. I initially had the pieces showing by drawing them in the individual square JPanels, but figured that would be a problem when trying to drag-and-drop them later. I have since been trying to use a JLayeredPane as the main container, but have encountered several issues.

One is that once I've specified the GridLayout for the JLayeredPane, regardless of which Integer I use to specify the layer to add the JLabel or other kind of image to, the pieces get added to the grid, making their positions set and and distorting the whole board. I have read that using LayoutManagers can interfere with layer positioning on the JLayeredPane, so this isn't too surprising. (Although the Oracle demo program from the JLayeredPane tutorial seems to do this just fine: http://download.oracle.com/javase/tutorial/uiswing/examples/components/LayeredPaneDemo2Project/src/components/LayeredPaneDemo2.java)

However, I have also tried to put the grid of JPanels into its own JPanel, then add it to a low layer of the JLayeredPane, the idea being that I could add the drag & drop icons to separate, non-opaque JPanel on a higher layer of the JLayeredPane. When I do this however, after I simply have the grid JPanel inside the JLayeredPane (i.e. before the drag-and-drop layer is added), the grid will not display.

I also have tried overriding the paintComponent (and paint) methods of the JLayeredPane to draw the piece images, but they are hidden by the JPanels (I can see that they are indeed there by setting the JPanels to non-opaque) and as far as I can tell there is no option to set the layer of the graphics on the JLayeredPane. I have also tried using the glassPane of the frame to draw the pieces, but got undesired behavior there as well.

Any help explaining some of this behavior, or where I am going wrong, would be much appreciated!

Here is a simple example that shows how you might (randomly) drag and drop 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);
     }
}