6

私はチェスゲームの開発に取り組んでいます。ボード コンテナで GridLayout を使用して JPanels の 8x8 グリッドを表示したいと考えています。(これにより、選択した正方形や有効な動きを強調表示するなどの機能がはるかに簡単になります。) 次に、このレイヤーにピースを追加して、ドラッグ アンド ドロップできるようにしたいと思います。最初は個々の正方形の JPanels に描画して表示していましたが、後でドラッグ アンド ドロップしようとすると問題になると考えました。それ以来、JLayeredPane をメイン コンテナとして使用しようとしてきましたが、いくつかの問題が発生しました。

1 つは、JLayeredPane の GridLayout を指定すると、JLabel またはその他の種類の画像を追加するレイヤーを指定するために使用する整数に関係なく、ピースがグリッドに追加され、位置が設定され、歪むことです。ボード全体。LayoutManagers を使用すると、JLayeredPane でのレイヤーの配置が妨げられる可能性があることを読んだので、これはそれほど驚くべきことではありません。(ただし、JLayeredPane チュートリアルの Oracle デモ プログラムはこれをうまく行っているようです: http://download.oracle.com/javase/tutorial/uiswing/examples/components/LayeredPaneDemo2Project/src/components/LayeredPaneDemo2.java )

ただし、JPanels のグリッドを独自の JPanel に配置してから、それを JLayeredPane の下位レイヤーに追加しようとしました。ドラッグ アンド ドロップ アイコンを追加して、不透明でない JPanel を上位レイヤーに分離できるという考えです。 JLayeredPane のレイヤー。ただし、これを行うと、単にグリッド JPanel を JLayeredPane 内に配置した後 (つまり、ドラッグ アンド ドロップ レイヤーを追加する前) に、グリッドが表示されなくなります。

また、JLayeredPane の paintComponent (およびペイント) メソッドをオーバーライドしてピース画像を描画しようとしましたが、それらは JPanel によって隠されています (JPanels を非不透明に設定することで、それらが実際にそこにあることがわかります)。 JLayeredPane でグラフィックスのレイヤーを設定するオプションがないことがわかります。また、フレームのglassPaneを使用してピースを描画しようとしましたが、そこでも望ましくない動作が発生しました。

この動作の一部、またはどこが間違っているかを説明する助けがあれば、大歓迎です!

4

1 に答える 1

8

以下は、ある正方形から別の正方形に「チェスの駒」を (ランダムに) ドラッグ アンド ドロップする方法を示す簡単な例です。

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);
     }
}
于 2011-07-25T04:32:46.047 に答える