Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JLayeredPanel布局管理器自由移动对象_Java_Swing_Jpanel - Fatal编程技术网

Java JLayeredPanel布局管理器自由移动对象

Java JLayeredPanel布局管理器自由移动对象,java,swing,jpanel,Java,Swing,Jpanel,我有一个游戏板,有8块,我希望能够将它们移动到jpanel上的任何地方。目前,我只能做流或网格布局,但这并不能产生预期的结果。长期目标是能够独立单击一个工件并将其拖动到所需的位置。(包括在其他部件的顶部) 欢迎您提供任何建议或意见。。。(感谢装满鳗鱼的气垫船,Madschellet,peeskillet,Andrew Thompson,感谢他们早期的建议) 导入java.awt.Component; 导入java.awt.Container; 导入java.awt.Dimension; 导入ja

我有一个游戏板,有8块,我希望能够将它们移动到jpanel上的任何地方。目前,我只能做流或网格布局,但这并不能产生预期的结果。长期目标是能够独立单击一个工件并将其拖动到所需的位置。(包括在其他部件的顶部)

欢迎您提供任何建议或意见。。。(感谢装满鳗鱼的气垫船,Madschellet,peeskillet,Andrew Thompson,感谢他们早期的建议)

导入java.awt.Component;
导入java.awt.Container;
导入java.awt.Dimension;
导入java.awt.FlowLayout;
导入java.awt.Image;
导入java.awt.Point;
导入java.awt.event.MouseEvent;
导入java.awt.event.MouseListener;
导入java.awt.event.MouseMotionListener;
导入javax.swing.ImageIcon;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JLayeredPane;
导入javax.swing.JPanel;
公共类FireflyGameBoard扩展JFrame实现MouseListener,
鼠标移动
{
JLayeredPane layeredPane;
JPanel游戏板;
//JPanel背景;
JLabel游戏机;
内部调整;
内部调整;
图像图标;
图像背景;
字符串Rimagepath=“/Users/yournamehere/Documents/workspace/MotionGraphicsTest/resources/”;
公众萤火虫游戏板()
{
尺寸板尺寸=新尺寸(1920、1080);
bgicon=新图像图标(Rimagepath+“Backdroptest.png”);
bg=bgicon.getImage();
ImagePanel背景=新建ImagePanel(新建ImageIcon(Rimagepath
+“Backdroptest.png”).getImage();
//为此应用程序使用分层窗格
layeredPane=新的JLayeredPane();
getContentPane().add(layeredPane);
layeredPane.setPreferredSize(boardSize);
layeredPane.addMouseListener(此);
layeredPane.addMouseMotionListener(此);
//将棋盘添加到分层窗格
gameBoard=新图像面板(bg);
layeredPane.add(背景,JLayeredPane.DEFAULT_层);
layeredPane.add(游戏板,JLayeredPane.MODAL_层);
gameBoard.setLayout(新的FlowLayout());
gameBoard.setPreferredSize(boardSize);
gameBoard.setBounds(0,0,boardSize.width,boardSize.height);
//对于(int i=0;i<64;i++)
// {
//JPanel square=newjpanel(newborderlayout());
//游戏板。添加(方形);
//
////square.setBackground(空);
// }
//在黑板上加几块
JLabel片段=新JLabel(新图像图标(Rimagepath+“alliance.png”);
游戏板。添加(块);
工件=新的JLabel(新的图像图标(Rimagepath+“piece2.png”);
游戏板。添加(块);
工件=新的JLabel(新的图像图标(Rimagepath+“piece3.png”);
游戏板。添加(块);
工件=新的JLabel(新的图像图标(Rimagepath+“piece4.png”);
游戏板。添加(块);
工件=新的JLabel(新的图像图标(Rimagepath+“reaper.png”);
游戏板。添加(块);
工件=新的JLabel(新的图像图标(Rimagepath+“piece6.png”);
游戏板。添加(块);
工件=新的JLabel(新的图像图标(Rimagepath+“piece7.png”);
游戏板。添加(块);
工件=新的JLabel(新的图像图标(Rimagepath+“piece8.png”);
游戏板。添加(块);
}
@凌驾
公共无效鼠标按下(MouseEvent e)
{
gamePiece=null;
Component c=gameBoard.findComponentAt(e.getX(),e.getY());
if(JPanel的c实例)
返回;
Point parentLocation=c.getParent().getLocation();
xAdjustment=parentLocation.x-e.getX();
yAdjustment=parentLocation.y-e.getY();
游戏片=(JLabel)c;
设置位置(e.getX()+xaadjustment,e.getY()+yaadjustment);
gamePiece.setSize(gamePiece.getWidth(),gamePiece.getHeight());
layeredPane.add(gamePiece,JLayeredPane.DRAG_层);
}
//把棋子四处移动
@凌驾
公共无效鼠标标记(MouseEvent me)
{
如果(游戏片==null)
返回;
setLocation(me.getX()+xaadjustment,me.getY()+yaadjustment);
}
//把棋子放回棋盘上
@凌驾
公共无效MouseEvent(MouseEvent e)
{
如果(游戏片==null)
返回;
游戏件。设置可见(假);
Component c=gameBoard.findComponentAt(e.getX(),e.getY());
if(JLabel的c实例)
{
容器父级=c.getParent();
父。删除(0);
添加(游戏件);
}
其他的
{
容器父项=(容器)c;
添加(游戏件);
}
游戏件。设置可见(真);
}
@凌驾
公共无效mouseClicked(MouseEvent e)
{
}
@凌驾
public void mouseMoved(MouseEvent e)
{
}
@凌驾
公共无效鼠标事件(鼠标事件e)
{
}
@凌驾
公共无效mouseExited(MouseEvent e)
{
}
公共静态void main(字符串[]args)
{
JFrame frame=新的FireflyGameBoard();
frame.setDefaultCloseOperation(在关闭时处理);
frame.pack();
frame.setresizeable(true);
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
}

另外,这不是学校的作业,我的g/f是一个狂热的棋盘游戏玩家,我想让她成为一些她最喜欢的游戏的数字版本……

拖放是一项严肃的工作。当做得好的时候,它会非常棒,但是要为一些严肃的繁重工作和设计工作做好准备

一种方法是尝试生成自包含的工作单元,即工件负责管理其自身的阻力,单元/网格负责管理下降

拖拉/单件
棋子
是一个可移动的游戏棋子,可以拖动到新位置

工件本身负责管理用于初始化拖动过程的
DragGestureRecognizer

因为我想在文章中显示一个图标,所以我选择覆盖
JLabel
,因为它提供了这方面的核心功能

import java.awt.Container;
import java.awt.Cursor;
import java.awt.Point;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.image.BufferedImage;
import javax.swing.JLabel;

public class PieceLabel extends JLabel {
    private DragGestureHandler dragGestureHandler;
    private DragGestureRecognizer dgr;

    public PieceLabel() {
        setHorizontalAlignment(CENTER);
        setVerticalAlignment(CENTER);
    }

    @Override
    public void addNotify() {
        super.addNotify();
        if (dgr == null) {
            dragGestureHandler = new DragGestureHandler(this);
            dgr = DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_MOVE, dragGestureHandler);
        }
    }

    @Override
    public void removeNotify() {
        if (dgr != null) {
            dgr.removeDragGestureListener(dragGestureHandler);
            dragGestureHandler = null;
        }
        dgr = null;
        super.removeNotify();
    }

    public static class DragGestureHandler implements DragGestureListener, DragSourceListener {

        private PieceLabel piece;
        private Container parent;

        public DragGestureHandler(PieceLabel child) {
            this.piece = child;
        }

        public PieceLabel getPiece() {
            return piece;
        }

        protected void setParent(Container parent) {
            this.parent = parent;
        }

        protected Container getParent() {
            return parent;
        }

        @Override
        public void dragGestureRecognized(DragGestureEvent dge) {
            // When the drag begins, we need to grab a reference to the
            // parent container so we can return it if the drop
            // is rejected
            Container parent = getPiece().getParent();
            setParent(parent);
            // Remove the panel from the parent.  If we don't do this, it
            // can cause serialization issues.  We could over come this
            // by allowing the drop target to remove the component, but that's
            // an argument for another day
            parent.remove(getPiece());
            // Update the display
            parent.invalidate();
            parent.repaint();
            // Create our transferable wrapper
            Transferable transferable = new PieceTransferable(getPiece());
            // Start the "drag" process...
            DragSource ds = dge.getDragSource();
            //            ds.startDrag(dge, Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR), transferable, this);
            BufferedImage image = BoardDrag.createBufferedImage(piece.getIcon(), piece);
            Point pp = piece.getLocation();
            Point dp = dge.getDragOrigin();
            int x = image.getWidth() / 2;
            int y = image.getHeight() / 2;
            ds.startDrag(dge, Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR), image, new Point(x, y), transferable, this);
        }

        @Override
        public void dragEnter(DragSourceDragEvent dsde) {
        }

        @Override
        public void dragOver(DragSourceDragEvent dsde) {
        }

        @Override
        public void dropActionChanged(DragSourceDragEvent dsde) {
        }

        @Override
        public void dragExit(DragSourceEvent dse) {
        }

        @Override
        public void dragDropEnd(DragSourceDropEvent dsde) {
            // If the drop was not sucessful, we need to
            // return the component back to it's previous
            // parent
            if (!dsde.getDropSuccess()) {
                getParent().add(getPiece());
                getParent().invalidate();
                getParent().repaint();
            }
        }
    }

}
放置/单元/网格 单元/网格就是这样,它在整个网格/bo中构成一个元素
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Point;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.image.BufferedImage;
import javax.swing.JLabel;

public class PieceLabel extends JLabel {
    private DragGestureHandler dragGestureHandler;
    private DragGestureRecognizer dgr;

    public PieceLabel() {
        setHorizontalAlignment(CENTER);
        setVerticalAlignment(CENTER);
    }

    @Override
    public void addNotify() {
        super.addNotify();
        if (dgr == null) {
            dragGestureHandler = new DragGestureHandler(this);
            dgr = DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_MOVE, dragGestureHandler);
        }
    }

    @Override
    public void removeNotify() {
        if (dgr != null) {
            dgr.removeDragGestureListener(dragGestureHandler);
            dragGestureHandler = null;
        }
        dgr = null;
        super.removeNotify();
    }

    public static class DragGestureHandler implements DragGestureListener, DragSourceListener {

        private PieceLabel piece;
        private Container parent;

        public DragGestureHandler(PieceLabel child) {
            this.piece = child;
        }

        public PieceLabel getPiece() {
            return piece;
        }

        protected void setParent(Container parent) {
            this.parent = parent;
        }

        protected Container getParent() {
            return parent;
        }

        @Override
        public void dragGestureRecognized(DragGestureEvent dge) {
            // When the drag begins, we need to grab a reference to the
            // parent container so we can return it if the drop
            // is rejected
            Container parent = getPiece().getParent();
            setParent(parent);
            // Remove the panel from the parent.  If we don't do this, it
            // can cause serialization issues.  We could over come this
            // by allowing the drop target to remove the component, but that's
            // an argument for another day
            parent.remove(getPiece());
            // Update the display
            parent.invalidate();
            parent.repaint();
            // Create our transferable wrapper
            Transferable transferable = new PieceTransferable(getPiece());
            // Start the "drag" process...
            DragSource ds = dge.getDragSource();
            //            ds.startDrag(dge, Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR), transferable, this);
            BufferedImage image = BoardDrag.createBufferedImage(piece.getIcon(), piece);
            Point pp = piece.getLocation();
            Point dp = dge.getDragOrigin();
            int x = image.getWidth() / 2;
            int y = image.getHeight() / 2;
            ds.startDrag(dge, Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR), image, new Point(x, y), transferable, this);
        }

        @Override
        public void dragEnter(DragSourceDragEvent dsde) {
        }

        @Override
        public void dragOver(DragSourceDragEvent dsde) {
        }

        @Override
        public void dropActionChanged(DragSourceDragEvent dsde) {
        }

        @Override
        public void dragExit(DragSourceEvent dse) {
        }

        @Override
        public void dragDropEnd(DragSourceDropEvent dsde) {
            // If the drop was not sucessful, we need to
            // return the component back to it's previous
            // parent
            if (!dsde.getDropSuccess()) {
                getParent().add(getPiece());
                getParent().invalidate();
                getParent().repaint();
            }
        }
    }

}
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetContext;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import javax.swing.JComponent;
import javax.swing.JPanel;

public class Cell extends JPanel {
    private DropTarget dropTarget;
    private DropHandler dropHandler;

    public Cell() {
        setLayout(new BorderLayout());
    }

    @Override
    public void addNotify() {
        super.addNotify();
        if (dropHandler == null) {
            dropHandler = new DropHandler();
        }
        if (dropTarget == null) {
            dropTarget = new DropTarget(this, DnDConstants.ACTION_MOVE, dropHandler, true);
        }
    }

    @Override
    public void removeNotify() {
        if (dropTarget != null) {
            dropTarget.removeDropTargetListener(dropHandler);
        }
        dropTarget = null;
        dropHandler = null;
        super.removeNotify();
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(48, 48);
    }

    public class DropHandler implements DropTargetListener {

        @Override
        public void dragEnter(DropTargetDragEvent dtde) {
            // Determine if can actual process the contents comming in.
            // You could try and inspect the transferable as well, but
            // There is an issue on the MacOS under some circumstances
            // where it does not actually bundle the data until you accept the
            // drop.
            if (dtde.isDataFlavorSupported(PieceDataFlavor.SHARED_INSTANCE)) {
                dtde.acceptDrag(DnDConstants.ACTION_MOVE);
            } else {
                dtde.rejectDrag();
            }
        }

        @Override
        public void dragOver(DropTargetDragEvent dtde) {
        }

        @Override
        public void dropActionChanged(DropTargetDragEvent dtde) {
        }

        @Override
        public void dragExit(DropTargetEvent dte) {
        }

        @Override
        public void drop(DropTargetDropEvent dtde) {
            boolean success = false;
            // Basically, we want to unwrap the present...
            if (dtde.isDataFlavorSupported(PieceDataFlavor.SHARED_INSTANCE)) {
                Transferable transferable = dtde.getTransferable();
                try {
                    Object data = transferable.getTransferData(PieceDataFlavor.SHARED_INSTANCE);
                    if (data instanceof PieceLabel) {
                        PieceLabel piece = (PieceLabel) data;
                        DropTargetContext dtc = dtde.getDropTargetContext();
                        Component component = dtc.getComponent();
                        if (component instanceof JComponent) {
                            Container parent = piece.getParent();
                            if (parent != null) {
                                parent.remove(piece);
                            }
                            ((JComponent) component).add(piece);
                            success = true;
                            dtde.acceptDrop(DnDConstants.ACTION_MOVE);
                            invalidate();
                            repaint();
                        } else {
                            success = false;
                            dtde.rejectDrop();
                        }
                    } else {
                        success = false;
                        dtde.rejectDrop();
                    }
                } catch (Exception exp) {
                    success = false;
                    dtde.rejectDrop();
                    exp.printStackTrace();
                }
            } else {
                success = false;
                dtde.rejectDrop();
            }
            dtde.dropComplete(success);
        }
    }

}
import java.awt.datatransfer.DataFlavor;

public class PieceDataFlavor extends DataFlavor {
    public static final PieceDataFlavor SHARED_INSTANCE = new PieceDataFlavor();

    public PieceDataFlavor() {
        super(PieceLabel.class, null);
    }

}
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;

public class PieceTransferable implements Transferable {
    private final DataFlavor[] flavors = new DataFlavor[]{PieceDataFlavor.SHARED_INSTANCE};
    private final PieceLabel piece;

    public PieceTransferable(PieceLabel piece) {
        this.piece = piece;
    }

    @Override
    public DataFlavor[] getTransferDataFlavors() {
        return flavors;
    }

    @Override
    public boolean isDataFlavorSupported(DataFlavor flavor) {
        // Okay, for this example, this is over kill, but makes it easier
        // to add new flavor support by subclassing
        boolean supported = false;
        for (DataFlavor mine : getTransferDataFlavors()) {
            if (mine.equals(flavor)) {
                supported = true;
                break;
            }
        }
        return supported;
    }

    public PieceLabel getPanel() {
        return piece;
    }

    @Override
    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
        Object data = null;
        if (isDataFlavorSupported(flavor)) {
            data = getPanel();
        } else {
            throw new UnsupportedFlavorException(flavor);
        }
        return data;
    }

}
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class BoardPane extends JPanel {

    public BoardPane() {
        setLayout(new GridLayout(8, 8));
        int index = 0;
        for (int row = 0; row < 8; row++) {
            for (int col = 0; col < 8; col++) {
                Cell cell = new Cell();
                if (index % 2 == 0) {
                    cell.setBackground(Color.WHITE);
                } else {
                    cell.setBackground(Color.BLACK);
                }
                add(cell);
                index++;
            }
            index++;
        }
        try {
            PieceLabel label = new PieceLabel();
            BufferedImage image = ImageIO.read(getClass().getResource("/Piece01.png"));
            label.setIcon(new ImageIcon(image));
            setCellPiece(label, 0, 0);
        } catch (IOException ex) {
            Logger.getLogger(BoardDrag.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void setCellPiece(PieceLabel label, int row, int col) {
        int index = (row * 8) + col;
        Cell cell = (Cell) getComponent(index);
        cell.removeAll();
        cell.add(label);
    }

}