Java麻将游戏-帮助实现手部重组,将JLabels从我拖动所选棋子的位置移开

Java麻将游戏-帮助实现手部重组,将JLabels从我拖动所选棋子的位置移开,java,swing,user-interface,drag,Java,Swing,User Interface,Drag,我目前正在制作一个java麻将游戏,我正在开发GUI。我有一个JPanel,它包含一个jLabel数组,每个jLabel都有一个自定义鼠标侦听器 我想要的是实施某种方式来重组你的手。例如,您刚刚绘制了一个平铺,您希望将其放在最左侧,以便在手中保留一些组织 我已经可以拖动磁贴了,但我希望在释放磁贴时,磁贴能捕捉到位,然后每隔一个磁贴向下移动一次。如果我把它放在最左边,每一块瓷砖都会向右移动。因此,该计划需要某种方式来识别已移动的磁贴,并确定磁贴的位置。我希望能得到一些关于如何实施此操作的指导,或者

我目前正在制作一个java麻将游戏,我正在开发GUI。我有一个JPanel,它包含一个jLabel数组,每个jLabel都有一个自定义鼠标侦听器

我想要的是实施某种方式来重组你的手。例如,您刚刚绘制了一个平铺,您希望将其放在最左侧,以便在手中保留一些组织

我已经可以拖动磁贴了,但我希望在释放磁贴时,磁贴能捕捉到位,然后每隔一个磁贴向下移动一次。如果我把它放在最左边,每一块瓷砖都会向右移动。因此,该计划需要某种方式来识别已移动的磁贴,并确定磁贴的位置。我希望能得到一些关于如何实施此操作的指导,或者我需要更改/添加/研究什么

这是我的鼠标侦听器类,如果需要任何其他信息,请告诉我

package mahjongCode;

import java.awt.Component;
import java.awt.Cursor;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class DragAndDropListener extends MouseAdapter{
    private Point startPoint;
    private Component draggedObject;
    private JPanel panel;
    private JLabel[] handTiles;

    public DragAndDropListener(JPanel panel, JLabel[] handTiles){
        this.panel = panel;
        this.handTiles = handTiles;
    }
    @Override
    public void mousePressed(MouseEvent e){
        panel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        draggedObject = (Component) e.getSource();
        startPoint = SwingUtilities.convertPoint(draggedObject, e.getPoint(), 
                                                    draggedObject.getParent());
    }

    @Override
    public void mouseDragged(MouseEvent e){
        Point location = SwingUtilities.convertPoint(draggedObject, e.getPoint(), 
                                                        draggedObject.getParent());
        Point locTrans = location.getLocation();
        locTrans.translate(draggedObject.getParent().getX(), draggedObject.getParent().getY());
        if(draggedObject.getParent().getBounds().contains(locTrans)){
            Point newLocation = draggedObject.getLocation();
            newLocation.translate(location.x - startPoint.x, location.y - startPoint.y);
            newLocation.x = Math.max(newLocation.x, 0);
            newLocation.x = Math.min(newLocation.x, draggedObject.getParent().getWidth() - draggedObject.getWidth());
            newLocation.y = Math.max(newLocation.y, 0);
            newLocation.y = Math.min(newLocation.y, draggedObject.getParent().getHeight() - draggedObject.getHeight());
            draggedObject.setLocation(newLocation);
            panel.repaint();
            startPoint = location;
        }
    }

    @Override 
    public void mouseReleased(MouseEvent e){
        panel.setCursor(null);
        startPoint = null;
        draggedObject = null;
    }

    public void makeDraggable(Component component){
        component.addMouseListener(this);
        component.addMouseMotionListener(this);
    }

}

由于您有一系列JLabel,您已经完成了解决方案的一半!我最近才回答了一个问题

你可能会发现这是有益的

至于“捕捉到位”,如果您正在基于阵列标记绘制瓷砖的手,则捕捉将为您完成,因为它们将在捕捉后绘制到位

我对麻将知之甚少,尽管我认为这些牌与乌诺牌中的牌相似,因为你不受设定值的限制。如果是这种情况,ArrayList可能非常有用。你可以读一些关于这个问题的意见


编辑:

我知道有几种方法可以解决这个问题,可能还有更多: 如果每个平铺都获得了框架/屏幕/窗格的相对部分,则可以获得其x坐标的值(平铺上的红线),当您向左拖动鼠标(蓝色箭头,红色圆点)时,越过绿色箭头,自动将该平铺向左移动一个

如果在本例中,当鼠标移动超过固定宽度时,有最大数量的平铺(如4),则可以基于该预定值直接交换平铺

也许我能看到的最简单的方法是:

当鼠标释放拖放(我假设是点击拖动)时,获取鼠标最后一个已知位置的坐标,然后系统地将位置与每个索引进行比较,直到获得位置,然后以这种方式进行处理


由于本例中的X值比所有其他值都小,因此它被放置在arraylist的前面。arraylist位置确定每个平铺的绘制位置。在此处释放鼠标时,选定的平铺将保存在局部变量中,然后所有平铺将向右移动一个插槽以适应新的更改,最后,选定的平铺位置将根据数组索引0设置为(150100)

太棒了,谢谢,不过我想知道我该怎么去弄清楚把瓷砖放在哪里?我可以直观地将瓷砖放置到位,但程序如何知道我将其放置在第1点和第6点?是的,瓷砖的处理方式与uno卡一样。例如,假设瓷砖的宽度为50像素。测试鼠标位置是否大于或小于瓷砖绝对位置的50%,加上宽度的50%。图片和更新的答案。哇,这真是太棒了。非常感谢你!程序知道您通过一个函数将其放入插槽1中,该函数根据X坐标或布尔值确定它。粗略地说,您可以将代码定向到“将磁贴放入缓冲区插槽,将所有磁贴向下移动一个,将缓冲区磁贴放入插槽0”,或者您可以将代码定向到“交换这两个磁贴”,这两种方法都可以满足您的要求,但是,一种方法更有效,需要的调用更少。