首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JLayeredPane和MouseAdapter问题

JLayeredPane和MouseAdapter问题
EN

Stack Overflow用户
提问于 2013-07-15 21:17:05
回答 1查看 1.3K关注 0票数 1

我目前正在尝试为一个名为Carcassone的游戏创建一个应用程序,但是我在将JLayeredPane与MouseAdapters结合使用时遇到了问题。

目前,我有一个JLayeredPane,它包含一个带有GridLayout的JPanel,用作游戏板。GridLayout的每个单元格都包含一个JPanel,其中包含一个JLabel,用于表示电路板上的图块。(一个空的磁贴就是一个带有黑色方块的JLabel )。

我在JLayeredPane中添加了一个自定义鼠标适配器(TileMouseAdapter),它允许用户在游戏板上移动磁贴(鼠标按下-拖动-释放)或旋转磁贴(鼠标单击)。(要测试单击“下一平铺”按钮并在出现的平铺上移动,单击“提交”按钮后,如果是有效移动,则平铺将不再可拖动)。在我添加下一部分之前,这一切都工作得很好。

现在,我想向屏幕顶部的JLayeredPane添加一个单独的JPanel。这一部分应该放置玩家可以放置在瓷砖上的游戏棋子。我还希望JPanel能够容纳游戏棋子,这样玩家就可以将棋子拖到瓷砖上。但是,当我创建此面板并将其添加到JLayeredPane中时,上一节中的鼠标适配器不再正常工作。例如,如果您单击磁贴的底部,它将不再识别您正在单击磁贴。如果您单击每个磁贴的上半部分,它将仅选择磁贴。此外,如果您单击磁贴的底部,有时它会选择下面的磁贴。即,似乎选择瓦片的机制似乎向上移动了大约半个瓦片。有人能想出这个问题的解释/可能的解决方法吗?谢谢!

下面的代码是我用来创建包含棋盘JPanel (myBoardPanel)和游戏棋子面板(makeMeeplePanel())的JLayeredPane的代码。

代码语言:javascript
复制
        private JLayeredPane makeBoardPanel() {
    JLayeredPane layeredPane = new JLayeredPane();
    layeredPane.setLayout(new BorderLayout());
    myBoardPanel = new CarcassoneBoardPanel(layeredPane);
    layeredPane.add(makeMeeplePanel(), BorderLayout.NORTH, JLayeredPane.DEFAULT_LAYER);
    layeredPane.add(myBoardPanel, BorderLayout.CENTER, JLayeredPane.DEFAULT_LAYER);

    TileMouseAdapter tileMouseAdapter = new TileMouseAdapter(layeredPane);
    //MeepleMouseAdapter meepleMouseAdapter = new MeepleMouseAdapter(layeredPane);

    layeredPane.addMouseListener(tileMouseAdapter);
    layeredPane.addMouseMotionListener(tileMouseAdapter);
    //layeredPane.addMouseListener(meepleMouseAdapter);
    //layeredPane.addMouseMotionListener(meepleMouseAdapter);
    return layeredPane; 
}

这是我为游戏板定制的鼠标适配器:

代码语言:javascript
复制
    package gui;
    import java.awt.Component;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import javax.swing.JLayeredPane;
    import javax.swing.JPanel;

    import tiles.*;

    public class TileMouseAdapter extends MouseAdapter {
private JLayeredPane myLayeredPane;
private CarcassoneBoardPanel myBoard;
private Tile dragLabel;
private JPanel clickedPanel;


public TileMouseAdapter(JLayeredPane layeredPane) {
    myLayeredPane = layeredPane;
    myBoard = (CarcassoneBoardPanel) layeredPane.getComponents()[1];
}

private void reset() {
    if (dragLabel != null) {
        myLayeredPane.remove(dragLabel);
        myLayeredPane.revalidate();
        myLayeredPane.repaint();
    }
    dragLabel = null;
    clickedPanel = null;
} 

@Override
public void mouseClicked(MouseEvent event) {
    clickedPanel = (JPanel) myBoard.getComponentAt(event.getPoint());
    if (clickedPanel == null) {
        reset();
        return;
    }
    Component[] components = clickedPanel.getComponents();
    if (!(components[0] instanceof Tile) || components[0] instanceof EmptyTile || !((Tile) components[0]).isDraggable()) {
        return;
    }

    dragLabel = (Tile) components[0];
    dragLabel.rotate();
    clickedPanel.revalidate();
    clickedPanel.repaint();
    reset();
}

@Override 
public void mousePressed(MouseEvent event) {
    clickedPanel = (JPanel) myBoard.getComponentAt(event.getPoint());
    System.out.println(event.getPoint());
    if (clickedPanel == null) {
        reset();
        return;
    }
    Component[] components = clickedPanel.getComponents();
    if (!(components[0] instanceof Tile) || (components[0] instanceof EmptyTile) || !((Tile) components[0]).isDraggable()) {
        return;
    }
    dragLabel = (Tile) components[0];
    clickedPanel.remove(dragLabel);
    clickedPanel.add(new EmptyTile(dragLabel.getRow(), dragLabel.getCol()));
    clickedPanel.revalidate();
    clickedPanel.repaint();

    int x = event.getPoint().x - dragLabel.getWidth() / 2;
    int y = event.getPoint().y - dragLabel.getHeight() / 2;
    dragLabel.setLocation(x, y);
    try {
        myLayeredPane.add(dragLabel, JLayeredPane.DRAG_LAYER);
        myLayeredPane.repaint();
    } catch (IllegalArgumentException e) {
        //TODO: deal with this? 
        //gives error for some unknown reason, but doesnt effect anything? ignore...dumb error cus jswing sucks
    }
}

@Override
public void mouseDragged(MouseEvent event) {
    if (dragLabel == null) {
        return;
    }
    int x = event.getPoint().x - dragLabel.getWidth() / 2;
    int y = event.getPoint().y - dragLabel.getHeight() / 2;
    dragLabel.setLocation(x, y);
    myLayeredPane.revalidate();
}

@Override
public void mouseReleased(MouseEvent event) {
    //TODO: make sure cannot place tile on already occupied panel...
    if (dragLabel == null || !dragLabel.isDraggable()) {
        return;
    }
    myLayeredPane.remove(dragLabel);
    myLayeredPane.revalidate();
    myLayeredPane.repaint();


    JPanel droppedPanel = (JPanel) myBoard.getComponentAt(event.getPoint());
    if (droppedPanel == null) {
        clickedPanel.removeAll();
        clickedPanel.add(dragLabel);
        clickedPanel.revalidate();
        reset();
        return;
    }

    dragLabel.setPosition(((Tile) droppedPanel.getComponents()[0]).getRow(), ((Tile) droppedPanel.getComponents()[0]).getCol());
    droppedPanel.removeAll();
    droppedPanel.add(dragLabel);
    droppedPanel.revalidate();
    reset();
}

}

如果您需要更多信息/代码,请让我知道。这是我第一次使用这个网站,所以很抱歉如果我没有提供足够的解释,等等…谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-15 22:33:00

你的问题在这里:

代码语言:javascript
复制
@Override
public void mouseClicked(MouseEvent event) {
    clickedPanel = (JPanel) myBoard.getComponentAt(event.getPoint());

event.getPoint()将返回一个相对于注册了鼠标侦听器的layeredPanePointmyBoard.getComponentAt()将在相对于myBoard组件的位置返回组件,该组件位于layeredPane.getComponents()[1]的分层窗格中。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17655179

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档