添加到拖动图层后,鼠标拖动停止工作

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了添加到拖动图层后,鼠标拖动停止工作相关的知识,希望对你有一定的参考价值。

我正在尝试构建一个Scrabble游戏,以帮助您更熟悉构建GUI并练习一般的Java技能。该板主要由带有JPanels的JLayeredPane组成,包括电路板图像和电路板空间。我试图通过将tile添加到drag_layer然后从那里移动来将Tile对象(扩展JLabel)拖放到棋盘周围,类似于以下示例:dragging a jlabel around the screen。鼠标按下正在工作并正确地将图块添加到拖动图层,但在此之后,鼠标似乎完全停止了。我尝试在mouseDragged覆盖方法中打印“拖动”,但它甚至不打印。有两个相关的类 - Console和MouseInput,我将在下面展示,但如果你想拉动整个项目,我还会在最后添加到GitHub仓库的链接。

安慰:

public Console () throws IOException{
    // Create gameConsole
    gameConsole = new JFrame();
    final int frameWidth = 850;
    final int frameHeight = 950;
    gameConsole.setPreferredSize(new Dimension(frameWidth, frameHeight));
    gameConsole.setTitle("Scrabble");
    gameConsole.setLayout(new GridBagLayout());
    gameConsole.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    GridBagConstraints c = new GridBagConstraints();
    c.fill = GridBagConstraints.BOTH;
    c.ipadx = 810;
    c.ipady = 950;

    // Create center console panel and add to gameConsole
    centerConsole = new JPanel();
    centerConsole.setLayout(new BorderLayout());
    gameConsole.add(centerConsole,c);


    // Create layered pane that holds the board and playerbox
    gameContainer = new JLayeredPane();
    gameContainer.setBounds(0,0,810,950);
    gameContainer.addMouseListener(new MouseInput(gameContainer));
    gameContainer.addMouseMotionListener(new MouseInput(gameContainer));
    centerConsole.add(gameContainer, BorderLayout.CENTER);

    // Create board image label and add to JPanel
    BufferedImage scrabbleImage = ImageIO.read(Console.class.getResource("/board.jpg"));    
    JLabel background = new JLabel(new ImageIcon(scrabbleImage));
    boardImage = new JPanel();
    boardImage.setBounds(0, 0, 810, 810);
    boardImage.add(background);
    boardImage.setOpaque(true);


    // create JPanel with gridBagLayout
    boardGrid = new JPanel();
    boardGrid.setBounds(0, 3, 810, 810);
    boardGrid.setLayout(new GridBagLayout());
    boardGrid.setOpaque(false);

    // Create panels to add to boardGrid
    spaces = new BoardSpace [15][15];
    BoardSpace.setBoardSpaces(spaces);

    // Set grid constraints
    GridBagConstraints cGrid = new GridBagConstraints();
    for (int i = 0; i < 15; i++) {
        for (int j = 0; j < 15; j++) {
            // panel constraints
            cGrid.gridx = i;                // grid x location
            cGrid.gridy = j;                // grid y location
            cGrid.gridheight = 1;           // spans 1 row
            cGrid.gridwidth = 1;            // spans 1 column
            cGrid.weightx = 0.0;
            cGrid.weighty = 0.0;
            cGrid.fill = GridBagConstraints.BOTH;   // Resize veritically & horizontally

            // Set size of board space and add to grid
            spaces[i][j].setOpaque(false);
            spaces[i][j].setPreferredSize(new Dimension((int) Info.GRIDSIZE,(int) Info.GRIDSIZE));
            boardGrid.add(spaces[i][j], cGrid);
        }
    }

    // Add to layeredPane
    gameContainer.add(boardImage, new Integer(0),0);
    gameContainer.add(boardGrid, new Integer(1),0);


    // Create player box panel 
    playerPanel = new JPanel();
    playerPanel.setLayout(new GridBagLayout());
    playerBox = new JPanel();
    playerBox.setLayout(new GridLayout(1,7, 10, 0));

    // Create player box constraints
    GridBagConstraints cp = new GridBagConstraints();
    cp.ipadx = 50;
    cp.ipady = 50;

    // Create playerBox spaces
    playerSpaces = new BoardSpace [1][7];
    BoardSpace.setPlayerSpaces(playerSpaces);

    // Add playerSpaces to playerBox
    for (int j = 0; j < 7; j++) {
        // panel constraints
        cGrid.gridx = 0;                // grid x location
        cGrid.gridy = j;                // grid y location
        cGrid.gridheight = 1;           // spans 1 row
        cGrid.gridwidth = 1;            // spans 1 column
        cGrid.weightx = 0.0;
        cGrid.weighty = 0.0;
        cGrid.fill = GridBagConstraints.BOTH;   // Resize veritically & horizontally

        // Set size of board space and add to grid
        playerSpaces[0][j].setOpaque(false);
        playerSpaces[0][j].setPreferredSize(new Dimension((int) Info.GRIDSIZE,(int) Info.GRIDSIZE));
        playerBox.add(playerSpaces[0][j], cGrid);
    }

    // Add player box to south panel
    playerPanel.add(playerBox, cp);

    // Add player box to bottom of layeredPane
    playerPanel.setBounds(0,825,810,75);
    gameContainer.add(playerPanel, new Integer(0),0);

    gameConsole.pack();

    // Make gameConsole visible
    gameConsole.setVisible(true);
}

鼠标适配器:

public class MouseInput extends MouseAdapter {
/**
 * 
 */
private Component mouseArea;
private boolean dragging;
private Tile draggingTile;
private BoardSpace currentSpace;
private BoardSpace startingSpace;
private Component selectedObject;
Component [] panelObjects;
private JLayeredPane dragLayer;
private Point dragPoint;
private int dragWidth;
private int dragHeight;

public MouseInput(Component mouseArea) {
    // TODO Auto-generated constructor stub
    super();
    mouseArea = this.mouseArea;
}


void eventOutput(String eventDescription, MouseEvent e) {
    Point p = e.getPoint();
    System.out.println(eventDescription
            + " (" + p.getX() + "," + p.getY() + ")"
            + " detected on "
            + e.getComponent().getClass().getName()
            + "
");
}

public void mouseMoved(MouseEvent e) {
    //eventOutput("Mouse moved", e);
}

public void mouseDragged(MouseEvent e) {

    if (dragging) {
        System.out.println("Dragging");
    }

    if (!dragging) {
        return;
    } else {
        System.out.println("Dragging " + Tile.getLetter(draggingTile));
        int x = e.getPoint().x - dragWidth;
        int y = e.getPoint().y - dragHeight;
        draggingTile.setLocation(x, y);

        draggingTile.repaint();
    }
}


@Override
public void mouseClicked(MouseEvent e) {
    // TODO Auto-generated method stub
    //eventOutput("Mouse Clicked", e);
}


@Override
public void mouseEntered(MouseEvent e) {
    /*
    dragPoint = e.getPoint();
    selectedObject = e.getComponent().getComponentAt(dragPoint);
    // Get the current space

    while (!selectedObject.getClass().getSimpleName().equals("BoardSpace")) {
        try {
            dragPoint = selectedObject.getMousePosition();
            selectedObject = selectedObject.getComponentAt(dragPoint);
        } catch (NullPointerException illegalSpace){
            currentSpace = startingSpace;
            break;
        }
    }

    if (selectedObject.getClass().getSimpleName().equals("BoardSpace")) {
        currentSpace = (BoardSpace) selectedObject;
        System.out.println(BoardSpace.getID(currentSpace));
    } */
}


@Override
public void mouseExited(MouseEvent e) {
    // TODO Auto-generated method stub
    //eventOutput("Mouse Exited", e);
}


@Override
public void mousePressed(MouseEvent e) {
    dragLayer = (JLayeredPane) e.getSource();
    dragPoint = e.getPoint();
    selectedObject = e.getComponent().getComponentAt(dragPoint);

    // Get the current space
    while (!selectedObject.getClass().getSimpleName().equals("BoardSpace")) {
        try {
            dragPoint = selectedObject.getMousePosition();
            selectedObject = selectedObject.getComponentAt(dragPoint);
        } catch (NullPointerException illegalSpace){
            return;
        }
    }

    currentSpace = (BoardSpace) selectedObject;
    startingSpace = currentSpace;

    // If the boardspace has a tile, remove Tile from boardspace and add to dragging layer
    if (BoardSpace.Taken(currentSpace)) {
        // get dragging tile
        draggingTile = BoardSpace.getTile(currentSpace);
        dragging = true;

        // remove tile and repaint space
        BoardSpace.removeTile(currentSpace, draggingTile);
        currentSpace.revalidate();
        currentSpace.repaint();

        // Add tile to dragging layer
        dragWidth = draggingTile.getWidth() / 2;
        dragHeight = draggingTile.getHeight() / 2;
        int x = e.getPoint().x - dragWidth;
        int y = e.getPoint().y - dragHeight;

        draggingTile.setLocation(x, y);
        dragLayer.add(draggingTile, JLayeredPane.DRAG_LAYER);
        draggingTile.revalidate();
        draggingTile.repaint();

        System.out.println("Selected Tile " + Tile.getLetter(draggingTile));
    } else {
        return;
    }

}


@Override
public void mouseReleased(MouseEvent e) {
    /*
    // TODO Auto-generated method stub
    if (!BoardSpace.Taken(currentSpace)) {
        return;
    } else {
        dragging = false; 
        BoardSpace.setTile(currentSpace, draggingTile);
        draggingTile = null;
        currentSpace.repaint();
        currentSpace.revalidate();
    } */
  }

}

完整代码可以从:https://github.com/jowarren13/scrabble.git中提取

答案

所以在玩了一些之后,我发现每次调用一个新的鼠标操作(鼠标按下,鼠标拖动等),它都会实例化私有类变量的新实例,所以变量没有保持它们的设置值。为了解决这个问题,我使用这些附加变量创建了一个新类作为JLayeredPane的扩展,并使用我的新类作为分层游戏控制台。当一个tile在边界之外或在一个无效空间中释放时,仍在设计一些错误处理,但下面的代码至少让我在有效空间中移动tile。以下帖子有助于搞清楚:MouseListener in separate class not working。同样,可以从上面列出的git repo中提取完整代码。

BoardPane类:

package objects;

import java.awt.Component;
import java.awt.Point;

import javax.swing.JLayeredPane;

public class BoardPane extends JLayeredPane {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private boolean dragging;
    private Tile draggingTile;
    private BoardSpace currentSpace;
    private BoardSpace startingSpace;
    private Component selectedObject;
    Component [] panelObjects;
    private BoardPane dragLayer;
    private Point dragPoint;
    private int dragWidth;
    private int dragHeight;

    public BoardPane() {
        this.dragging = false;
        this.draggingTile = null;
        this.currentSpace = null;
        this.startingSpace = null;
        this.selectedObject = null;
        this.panelObjects = null;
        this.dragLayer = null;
        this.dragPoint = null;
        this.dragWidth = 51/2;
        this.dragHeight = 51/2;
    }

    public static void resetPane(BoardPane board) {
        board.dragging = false;
        board.draggingTile = null;
        board.currentSpace = null;
        board.startingSpace = null;
        board.selectedObject = null;
        board.panelObjects = null;
        board.dragLayer = null;
        board.dragPoint = null;
    }

    public static Boolean getDragStatus(BoardPane board) {
        return board.dragging;
    }

    public static void setDragStatus(BoardPane board, Boolean status) {
        board.dragging = status;
    }

    public static Tile getDragTile(BoardPane board) {
        return board.draggingTile;
    }

    public static void setDragTile(BoardPane board, Tile t) {
        board.draggingTile = t;
    }

    public static BoardSpace getCurrentSpace(BoardPane board) {
        return board.currentSpace;
    }

    public static void setCurrentSpace(BoardPane board, BoardSpace bs) {
        board.currentSpace = bs;
    }

    public static BoardSpace getStartingSpace(BoardPane board) {
        return board.startingSpace;
    }

    public static void setStartingSpace(BoardPane board, BoardSpace bs) {
        board.startingSpace = bs;
    }

    public static Component getSelectedObj(BoardPane board) {
        return board.selectedObject;
    }

    public static void setSelectedObj(BoardPane board, Component obj) {
        board.selectedObject = obj;
    }

    public static Component [] getPanelObjects(BoardPane board) {
        return board.panelObjects;
    }

    public static BoardPane getDragLayer(BoardPane board) {
        return board.dragLayer;
    }

    public static void setDragLayer(BoardPane board) {
        board.dragLayer = board;
    }

    public static void setPanelObjects(BoardPane board, Component [] obj) {
        board.panelObjects = obj;
    }

    public static Point getDragPoint (BoardPane board) {
        return board.dragPoint;
    }

    public static void setDragPoint(BoardPane board, Point p) {
        board.dragPoint = p;
    }

    public static int getDragWidth(BoardPane board) {
        return board.dragWidth;
    }

    public static int getDragHeight(BoardPane board) {
        return board.dragHeight;
    }

}

安慰:

package Main;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;

import objects.BoardPane;
import objects.BoardSpace;

import javax.imageio.ImageIO;

public class Console {
    private JFrame gameConsole; 
    private JPanel centerConsole;
    private BoardPane gameContainer;
    private JPanel playerPanel;
    private JPanel gamePanel;
    private JPanel north;
    private JPanel south;
    private JPanel east;
    private JPanel west;
    private JLayeredPane center;
    private JPanel splash;
    private JPanel playerBox;
    private JPanel boardGrid;
    private JPanel boardImage;
    private JButton start;
    private BoardSpace [][] spaces;
    private BoardSpace [][] playerSpaces;

    public Console () throws IOException{
        // Create gameConsole
        gameConsole = new JFrame();
        final int frameWidth = 850;
        final int frameHeight = 950;
        gameConsole.setPreferredSize(new Dimension(frameWidth, frameHeight));
        gameConsole.setTitle("Scrabble");
        gameConsole.setLayout(new GridBagLayout());
        gameConsole.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.BOTH;
        c.ipadx = 810;
        c.ipady = 950;

        // Create center console panel and add to gameConsole
        centerConsole = new JPanel();
        centerConsole.setLayout(new BorderLayout());
        gameConsole.add(centerConsole,c);


        // Create layered pane that holds the board and playerbox
        gameContainer = new BoardPane();
        gameContainer.setBounds(0,0,810,950);

        MouseInput mouseActions = new MouseInput();

        gameContainer.addMouseMotionListener(mouseActions);
        gameContainer.addMouseListener(mouseActions);
        centerConsole.add(gameContainer, BorderLayout.CENTER);

        // Create board image label and add to JPanel
        BufferedImage scrabbleImage = ImageIO.read(Console.class.getResource("/board.jpg"));    
        JLabel background = new JLabel(new ImageIcon(scrabbleImage));
        boardImage = new JPanel();
        boardImage.setBounds(0, 0, 810, 815);
        boardImage.add(background);
        boardImage.setOpaque(true);


        // create JPanel with gridBagLayout
        boardGrid = new JPanel();
        boardGrid.setBounds(0, 3, 810, 810);
        boardGrid.setLayout(new GridBagLayout());
        boardGrid.setOpaque(false);

        // Create panels to add to boardGrid
        spaces = new BoardSpace [15][15];
        BoardSpace.setBoardSpaces(spaces);

        // Set grid constraints
        GridBagConstraints cGrid = new GridBagConstraints();
        for (int i = 0; i < 15; i++) {
            for (int j = 0; j < 15; j++) {
                // panel constraints
                cGrid.gridx = i;                // grid x location
                cGrid.gridy = j;                // grid y location
                cGrid.gridheight = 1;           // spans 1 row
                cGrid.gridwidth = 1;            // spans 1 column
                cGrid.weightx = 0.0;
                cGrid.weighty = 0.0;
                cGrid.fill = GridBagConstraints.BOTH;   // Resize veritically & horizontally

                // Set size of board space and add to grid
                spaces[i][j].setOpaque(false);
                spaces[i][j].setPreferredSize(new Dimension((int) Info.GRIDSIZE,(int) Info.GRIDSIZE));
                boardGrid.add(spaces[i][j], cGrid);
            }
        }

        // Add to layeredPane
        gameContainer.add(boardImage, new Integer(0),0);
        gameContainer.add(boardGrid, new Integer(1),0);


        // Create player box panel 
        playerPanel = new JPanel();
        playerPanel.setLayout(new GridBagLayout());
        playerBox = new JPanel();
        playerBox.setLayout(new GridLayout(1,7, 10, 0));

        // Create player box constraints
        GridBagConstraints cp = new GridBagConstraints();
        cp.ipadx = 50;
        cp.ipady = 50;

        // 

以上是关于添加到拖动图层后,鼠标拖动停止工作的主要内容,如果未能解决你的问题,请参考以下文章

带有可拖动图层的 clearCanvas()

JavaFX窗口拖动

web切图的几个快捷键及总结

PS切图小技巧

arcgis10 空间参考与数据框不匹配?

python模拟鼠标拖动操作的方法