如何设置优先级的鼠标监听器 [英] How can I set the priority mouse listener

查看:254
本文介绍了如何设置优先级的鼠标监听器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有列表和按钮的面板。列表设置 MouseAdapter mouseClick()。我添加到面板 MouseAdapter mousePressed() mouseReleased() MouseMotionAdapter mouseDragged



拖放仅在您点击面板时有效。



如何使拖动工作,即使我点击了列表?



简单的考试:

  public class DragTest extends JFrame {
private boolean drag;
私人点btnCoord;
private Point startPoint;

public DragTest(){
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(500,500);
setLayout(null);
final JPanel panel = new JPanel();
final JButton button = new JButton();
button.setText(Button);
button.setSize(30,60);
button.setLocation(50,50);
panel.setLayout(null);
setContentPane(panel);
panel.addMouseMotionListener(new MouseMotionAdapter(){
@Override
public void mouseDragged(MouseEvent e){
if(drag){
panel.setLocation(btnCoord。 x-(startPoint.xe.getX()),btnCoord.y-(startPoint.ye.getY()));
}
}
});
panel.addMouseListener(new MouseAdapter(){
@Override
public void mousePressed(MouseEvent e){
drag = true;
startPoint = e.getPoint() ;
btnCoord = panel.getLocation();
}

@Override
public void mouseReleased(MouseEvent e){
drag = false;
}
});
getContentPane()。add(button);
}

public static void main(String [] args){
JFrame frame = new DragTest();
frame.setVisible(true);
}
}

如果拖动面板,一切正常,如果启动拖拽按钮,然后按钮截取事件。

解决方案

上面的代码有很多错误...




  • 不要使用 null / 绝对 的LayoutManager 查看在容器内部放置组件

  • 不要在组件上调用 setSize JFrame (如果正确布局管理器已实现您可以简单地添加组件,并在 JFrame 上调用 pack()

  • 在EDT上创建和操作Swing组件。阅读更多关于 Swing中的并发

  • 您应该调用 revalidate() repaint()在容器中添加/删除可见容器中的组件。



我一直在使用我自己的一些 ComponentDrag API将允许我们通过 JComponent 或多个 JComponent s拖动Swing组件(绝对没有错误)你可以创建 JButton 并将其添加到<$($)

c $ c> JPanel :

  JButton button = new JButton(Text); 

JPanel panel1 = new JPanel(){
@Override
public Dimension getPreferredSize(){
return new Dimension(300,300);
}
};
panel1.add(button);

比创建一个 ComponentDrag 类的一个实例传递你的容器参数ie JFrame / JDialog JWindow 并注册可拖动组件,并在您的 JPanel 上调用 setName(Droppable)以允许拖放即可正确地,特别是跨多个JComponents等,你只能为 JPanel 等等,你想要删除Swing组件的能力:

  JFrame frame = ..; //访问setGlassPane同样适用于JDialog和JWindow 
frame.add(panel1);

ComponentDrag cd = new ComponentDrag(frame);
cd.registerComponent(button);
panel1.setName(Droppable); //需要拖放才能正常运行多个组件

,您的好消息:)。



以下是2个完整示例,供分析用途:



1)显示要移动 JButton 的逻辑,并使用 ComponentDrag 重新定位,并覆盖其 componentDropped 方法:



拖动前:



< img src =https://i.stack.imgur.com/44Bo6.pngalt =在此输入图像说明>



4拖到1位:



  import java.awt.Component; 
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class DragButtonsTest {

ArrayList< JButton> buttons = new ArrayList<>();

public DragButtonsTest(){
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

final JPanel panel = new JPanel(new GridLayout(2,2));

ComponentDrag cd = new ComponentDrag(frame){
@Override
protected void componentDropped(MouseEvent me){
HashMap< Integer,JButton> collisions = new HashMap<>();
JButton draggedButton =(JButton)me.getSource();

(JButton btn:buttons){//遍历所有按钮,并获取每个
的collsions的数量if(btn!= draggedButton){// dont chck button我们拖动
int col = checkPerPixelCollision(draggedButton,btn);
System.out.println(Button+ btn.getText());
System.out.println(col);
collisions.put(col,btn);
}
}

//允许获取最多碰撞的按钮
int maxCollisions = 0;
JButton intersectingButton = null;
for(Map.Entry< Integer,JButton>条目:collisions.entrySet()){
整数collisionCount = entry.getKey();
JButton button = entry.getValue();
if(collisionCount> maxCollisions){
maxCollisions = collisionCount;
intersectingButton = button;
}
}

boolean reLayout = false;

if(maxCollisions> 0){//检查是否有
System.out.println(Button+ draggedButton.getText()+与 + intersectingButton.getText());
System.out.println(Collisions:+ maxCollisions);
reLayout = true;
} else {
System.out.println(No change made);
reLayout = false;
}

ArrayList< JButton> tmpButtons =(ArrayList< JButton>)buttons.clone(); //创建按钮的克隆

if(reLayout){//一个按钮被移动,面板需要布局
buttons.clear(); //清除旧按钮

(JButton b:tmpButtons){//重新排序jbuttons
如果(b == intersectingButton){
按钮。新增(draggedButton);
} else if(b == draggedButton){
buttons.add(intersectingButton);
} else {
buttons.add(b);
}
}
panel.removeAll(); //删除所有按钮
(JButton btn:buttons){//遍历所有按钮,并获取每个
panel.add(btn); //根据arraylist重新添加按钮
}
panel.revalidate();
panel.repaint();
}
super.componentDropped(me);

}
}; (int i = 0; i< 4; i ++){
JButton b = new JButton(String.valueOf(i + 1));


panel.add(b);
buttons.add(b);
cd.registerComponent(b);
}

frame.add(panel);

frame.pack();
frame.setVisible(true);
}

public static void main(String [] args){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run (){
new DragButtonsTest();
}
});
}

public HashSet< String> getMask(JButton e){
HashSet< String> mask = new HashSet();
int像素,a;
BufferedImage bi = componentToImage(e); //获取当前图像

for(int i = 0; i< bi.getWidth(); i ++){//对于给定框中的每个(x,y) (int j = 0; j< bi.getHeight(); j ++){
pixel = bi.getRGB(i,j);
//获取像素的RGB值
a =(pixel>> 24)& 0xFF的;
if(a!= 0){//如果alpha不是0,它必须是透明以外的东西
mask.add((e.getX()+ i)+,+ (e.getY() - j)); //将绝对x和绝对y坐标添加到我们的集合
}
}
}
返回掩码; //返回我们的集合
}

public static BufferedImage componentToImage(Component component){
BufferedImage img = new BufferedImage(component.getWidth(),component.getHeight(),BufferedImage 。半透明);
图形g = img.getGraphics();
component.paintAll(g);
return img;
}

//如果对象a和对象b之间存在冲突,则返回true b $ b public int checkPerPixelCollision(JButton b,JButton b2){
// This方法检测到图像是否重叠。如果他们这样做,碰撞是可能的
int ax1 =(int)b2.getX();
int ay1 =(int)b2.getY();

int ax2 = ax1 +(int)b2.getWidth();
int ay2 = ay1 +(int)b2.getHeight();

int bx1 =(int)b.getX();
int by1 =(int)b.getY();

int bx2 = bx1 +(int)b.getWidth();

int by2 = by1 +(int)b.getHeight();

if(by2< ay1 || ay2< by1 || bx2< ax1 || ax2< bx1){
return 0; //碰撞是不可能的
} else {//碰撞是可能的。
//获取两个图像的掩码
HashSet< String> maskPlayer1 = getMask(b2);
HashSet< String> maskPlayer2 = getMask(b);
maskPlayer1.retainAll(maskPlayer2); //检查maskPlayer2中的像素是否与maskPlayer1中的像素相同
if(maskPlayer1.size()> 0){//如果是,至少存在一个像素相同的像素两个图像,因此
返回maskPlayer1.size();
}
}
return 0;
}
}

class ComponentDrag {

private MouseAdapter ma;
private ArrayList< JComponent> components = new ArrayList<>();
private int startingX,startingY;
private boolean autoLayout = true;
私有的最终JFrame容器;
私人JPanel glassPane;
boolean firstTime = true;
private JComponent lastClickedContainer;

public ComponentDrag(final JFrame container){
this.container = container;
glassPane = new JPanel();
glassPane.setOpaque(false);
glassPane.setLayout(null);
this.container.setGlassPane(glassPane);

new Timer(10,new AbstractAction(){
@Override
public void actionPerformed(ActionEvent ae){
if(container.isVisible()){
glassPane.setVisible(true);
((Timer)ae.getSource())stop();
}
}
})。

ma = new MouseAdapter(){
@Override
public void mousePressed(MouseEvent me){
super.mousePressed(me);
componentPressed(me);
}

@Override
public void mouseReleased(MouseEvent me){
super.mouseReleased(me);
componentDropped(me);
}

@Override
public void mouseDragged(MouseEvent me){
super.mouseDragged(me);
componentDragged(me);
}
};
}

public JComponent findDroppableUnderGlassPane(Point p,Container container,Component source){
JComponent c = null;
Component [] comps = container.getComponents(); (组件com:comps)
如果(com.getName()!= null){
if(com.getName()。equals(Droppable)&& comComponent JComponent){
if(com.contains(SwingUtilities.convertPoint(source,p,com))){
return(JComponent)com;
}
} else if(com instanceof Container){
findDroppableUnderGlassPane(p,(Container)com,source);
}
}
}
return c;
}

public boolean isAutoLayout(){
return autoLayout;
}

public void setAutoLayout(boolean autoLayout){
this.autoLayout = autoLayout;
}

protected void componentDropped(MouseEvent me){
firstTime = true;
组件droppedComponent =(Component)me.getSource();
droppedComponent.setCursor(null);

JComponent jc = findDroppableUnderGlassPane(me.getPoint(),container.getContentPane(),(Component)me.getSource());

if(jc!= null){
glassPane.removeAll();
glassPane.revalidate();
glassPane.repaint();

jc.add(droppedComponent);
System.out.println(从glasspane中删除并添加到:+ jc);

if(autoLayout){
if(lastClickedContainer!= null){
lastClickedContainer.revalidate();
lastClickedContainer.repaint();
}
droppedComponent.revalidate();
droppedComponent.repaint();
jc.revalidate();
jc.repaint();
}

} else {
glassPane.removeAll();
glassPane.revalidate();
glassPane.repaint();
if(lastClickedContainer!= null){
lastClickedContainer.add(droppedComponent);
lastClickedContainer.revalidate();
lastClickedContainer.repaint();
}
}
}

protected void componentPressed(MouseEvent me){
JComponent jc = findDroppableUnderGlassPane(me.getPoint(),container.getContentPane ),(Component)me.getSource());

if(jc!= null&& jc.getName()。equals(Droppable)){
lastClickedContainer = jc;
System.out.println(Pressed:+ lastClickedContainer);
}

boolean clickedRegisteredComponent = false;

组件clickedComponent =(Component)me.getSource();

(组件组件:ComponentDrag.this.components){
if(component.equals(clickedComponent)){
clickedRegisteredComponent = true;
break;
}
}

if(clickedRegisteredComponent){
startingX = me.getX();
startingY = me.getY();
clickedComponent.setCursor(new Cursor(Cursor.MOVE_CURSOR));
}
}

protected void componentDragged(MouseEvent me){
组件draggedComponent =(Component)me.getSource();

if(firstTime&& lastClickedContainer!= null){
firstTime = false;
lastClickedContainer.remove(draggedComponent);
lastClickedContainer.revalidate();
lastClickedContainer.repaint();
glassPane.add(draggedComponent);
glassPane.revalidate();
glassPane.repaint();
System.out.println(Removed from:+ lastClickedContainer +\\\
And added to glasspane for draging);
}

// MouseEvent将针对相对于触发组件的位置的每个拖动进行重试。
draggedComponent.setLocation((me.getX() - startingX)+ draggedComponent。 getLocation()。x,(me.getY() - startingY)+ draggedComponent.getLocation()。
}

void registerComponent(JComponent draggableComp){
draggableComp.addMouseListener(ma);
draggableComp.addMouseMotionListener(ma);
components.add(draggableComp);
}

void deregisterComponent(JComponent draggableComp){
draggableComp.removeMouseListener(ma);
draggableComp.removeMouseMotionListener(ma);
components.remove(draggableComp);
}
}

2)只需显示如何拖动2 JLabel s跨 JPanel s



之前拖动我标签拖动:





标签拖动后:



  import java.awt.BorderLayout; 
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

/ **
*
* @author David
* /
public class DragOverMultipleComponentsTest {

public DragOverMultipleComponentsTest {
createAndShowUI();
}

public static void main(String [] args){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run (){
new DragOverMultipleComponentsTest();
}
});
}

private void createAndShowUI(){
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


JLabel draggableLabel = new JLabel(< - Drag me);
JLabel draggableLabel2 = new JLabel(< - 拖动我);

JLabel labelPanel1 = new JLabel(drag'em here);
JPanel panel1 = new JPanel(){
@Override
public Dimension getPreferredSize(){
return new Dimension(300,300);
}
};
panel1.add(labelPanel1);
panel1.setName(Droppable);

JLabel labelPanel2 = new JLabel(drag'em here);
JPanel panel2 = new JPanel();
panel2.add(labelPanel2);
panel2.add(draggableLabel);
panel2.add(draggableLabel2);
panel2.setName(Droppable);

JSeparator js = new JSeparator(JSeparator.VERTICAL);

ComponentDrag cd = new ComponentDrag(frame);

cd.registerComponent(draggableLabel);
cd.registerComponent(draggableLabel2);

frame.add(panel1,BorderLayout.WEST);
frame.add(js);
frame.add(panel2,BorderLayout.EAST);

frame.pack();
frame.setVisible(true);
}
}
class ComponentDrag {

private MouseAdapter ma;
private ArrayList< JComponent> components = new ArrayList<>();
private int startingX,startingY;
private boolean autoLayout = true;
私有的最终JFrame容器;
私人JPanel glassPane;
boolean firstTime = true;
private JComponent lastClickedContainer;

public ComponentDrag(final JFrame container){
this.container = container;
glassPane = new JPanel();
glassPane.setOpaque(false);
glassPane.setLayout(null);
this.container.setGlassPane(glassPane);

new Timer(10,new AbstractAction(){
@Override
public void actionPerformed(ActionEvent ae){
if(container.isVisible()){
glassPane.setVisible(true);
((Timer)ae.getSource())stop();
}
}
})。

ma = new MouseAdapter(){
@Override
public void mousePressed(MouseEvent me){
super.mousePressed(me);
componentPressed(me);
}

@Override
public void mouseReleased(MouseEvent me){
super.mouseReleased(me);
componentDropped(me);
}

@Override
public void mouseDragged(MouseEvent me){
super.mouseDragged(me);
componentDragged(me);
}
};
}

public JComponent findDroppableUnderGlassPane(Point p,Container container,Component source){
JComponent c = null;
Component [] comps = container.getComponents(); (组件com:comps)
如果(com.getName()!= null){
if(com.getName()。equals(Droppable)&& comComponent JComponent){
if(com.contains(SwingUtilities.convertPoint(source,p,com))){
return(JComponent)com;
}
} else if(com instanceof Container){
findDroppableUnderGlassPane(p,(Container)com,source);
}
}
}
return c;
}

public boolean isAutoLayout(){
return autoLayout;
}

public void setAutoLayout(boolean autoLayout){
this.autoLayout = autoLayout;
}

protected void componentDropped(MouseEvent me){
firstTime = true;
组件droppedComponent =(Component)me.getSource();
droppedComponent.setCursor(null);

JComponent jc = findDroppableUnderGlassPane(me.getPoint(),container.getContentPane(),(Component)me.getSource());

if(jc!= null){
glassPane.removeAll();
glassPane.revalidate();
glassPane.repaint();

jc.add(droppedComponent);
System.out.println(从glasspane中删除并添加到:+ jc);

if(autoLayout){
if(lastClickedContainer!= null){
lastClickedContainer.revalidate();
lastClickedContainer.repaint();
}
droppedComponent.revalidate();
droppedComponent.repaint();
jc.revalidate();
jc.repaint();
}

} else {
glassPane.removeAll();
glassPane.revalidate();
glassPane.repaint();
if(lastClickedContainer!= null){
lastClickedContainer.add(droppedComponent);
lastClickedContainer.revalidate();
lastClickedContainer.repaint();
}
}
}

protected void componentPressed(MouseEvent me){
JComponent jc = findDroppableUnderGlassPane(me.getPoint(),container.getContentPane ),(Component)me.getSource());

if(jc!= null&& jc.getName()。equals(Droppable)){
lastClickedContainer = jc;
System.out.println(Pressed:+ lastClickedContainer);
}

boolean clickedRegisteredComponent = false;

组件clickedComponent =(Component)me.getSource();

(组件组件:ComponentDrag.this.components){
if(component.equals(clickedComponent)){
clickedRegisteredComponent = true;
break;
}
}

if(clickedRegisteredComponent){
startingX = me.getX();
startingY = me.getY();
clickedComponent.setCursor(new Cursor(Cursor.MOVE_CURSOR));
}
}

protected void componentDragged(MouseEvent me){
组件draggedComponent =(Component)me.getSource();

if(firstTime&& lastClickedContainer!= null){
firstTime = false;
lastClickedContainer.remove(draggedComponent);
lastClickedContainer.revalidate();
lastClickedContainer.repaint();
glassPane.add(draggedComponent);
glassPane.revalidate();
glassPane.repaint();
System.out.println(Removed from:+ lastClickedContainer +\\\
And added to glasspane for draging);
}

// MouseEvent将针对相对于触发组件的位置的每个拖动进行重试。
draggedComponent.setLocation((me.getX() - startingX)+ draggedComponent。 getLocation()。x,(me.getY() - startingY)+ draggedComponent.getLocation()。
}

void registerComponent(JComponent draggableComp){
draggableComp.addMouseListener(ma);
draggableComp.addMouseMotionListener(ma);
components.add(draggableComp);
}

void deregisterComponent(JComponent draggableComp){
draggableComp.removeMouseListener(ma);
draggableComp.removeMouseMotionListener(ma);
components.remove(draggableComp);
}
}


I have a panel with lists and buttons. The lists set MouseAdapter with mouseClick(). I added to the panel MouseAdapter with mousePressed() and mouseReleased() and MouseMotionAdapter with mouseDragged.

Drag and drop only works if you click on the panel.

How to make the drag work even if I clicked on the list?

Simple examlpe:

public class DragTest extends JFrame{
private boolean drag;
private Point btnCoord;
private Point startPoint;

public DragTest(){
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    setSize(500,500);
    setLayout(null);
    final JPanel panel = new JPanel();
    final JButton button = new JButton();
    button.setText("Button");
    button.setSize(30,60);
    button.setLocation(50, 50);
    panel.setLayout(null);
    setContentPane(panel);
    panel.addMouseMotionListener(new MouseMotionAdapter() {
        @Override
        public void mouseDragged(MouseEvent e) {
            if (drag){
                panel.setLocation(btnCoord.x-(startPoint.x-e.getX()),btnCoord.y-(startPoint.y-e.getY()));
            }
        }
    });
    panel.addMouseListener(new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent e) {
            drag = true;
            startPoint = e.getPoint();
            btnCoord = panel.getLocation();
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            drag = false;
        }
    });
    getContentPane().add(button);
}

public static void main(String[] args) {
    JFrame frame = new DragTest();
    frame.setVisible(true);
}
}

If you drag panel, all work fine, if start drag button, then button intercept event.

解决方案

The above code has many errors...

  • Dont use null/Absolute LayoutManager. Have a look at Laying Out Components Within a Container.
  • Dont call setSize on components and JFrame (if correct Layout Manager is implemented you can simply add components and call pack() on JFrame.
  • Create and manipulate Swing components on EDT. Read more on Concurrency in Swing.
  • You should call revalidate() and repaint() on container after adding/removing components from a visible container.

I have been working on my own little ComponentDrag API which will allow us to drag Swing components across a JComponent or over multiple JComponents. It is by no means error free though (especially the multiple components part just finished it today so you never know)

You would create JButton and add to JPanel:

    JButton button = new JButton("Text");

    JPanel panel1 = new JPanel() {
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(300, 300);
        }
    };
    panel1.add(button);

Than create an instance of ComponentDrag class by passing argument of you container i.e JFrame/JDialog or JWindow and register the draggable components and call setName("Droppable") on your JPanel to allow dragging and dropping to take place correctly especially across multiple JComponents etc, you would only do this for the JPanels etc that you want the ability to drop Swing components too:

    JFrame frame=..;//has access to setGlassPane same applies for JDialog and JWindow
    frame.add(panel1);

    ComponentDrag cd=new ComponentDrag(frame);
    cd.registerComponent(button);
    panel1.setName("Droppable");//needed for the dragging and dropping to work correctly especailly over multiple components

and your good to go :).

Here are 2 full examples for analysis purposes:

1) Show the logic to move JButtons and re-position the accordingly using ComponentDrag and overriding its componentDropped method:

Before drag:

After 4 dragged to 1 position:

import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class DragButtonsTest {

    ArrayList<JButton> buttons = new ArrayList<>();

    public DragButtonsTest() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final JPanel panel = new JPanel(new GridLayout(2, 2));

        ComponentDrag cd = new ComponentDrag(frame) {
            @Override
            protected void componentDropped(MouseEvent me) {
                HashMap<Integer, JButton> collisions = new HashMap<>();
                JButton draggedButton = (JButton) me.getSource();

                for (JButton btn : buttons) {//iterate through all buttons and get the number of collsions of each
                    if (btn != draggedButton) {//dont chck button we were dragging
                        int col = checkPerPixelCollision(draggedButton, btn);
                        System.out.println("Button " + btn.getText());
                        System.out.println(col);
                        collisions.put(col, btn);
                    }
                }

                //lets get the button which had most collisions
                int maxCollisions = 0;
                JButton intersectingButton = null;
                for (Map.Entry<Integer, JButton> entry : collisions.entrySet()) {
                    Integer collisionCount = entry.getKey();
                    JButton button = entry.getValue();
                    if (collisionCount > maxCollisions) {
                        maxCollisions = collisionCount;
                        intersectingButton = button;
                    }
                }

                boolean reLayout = false;

                if (maxCollisions > 0) {//check if there was any
                    System.out.println("Button " + draggedButton.getText() + " is intersecting more of Button " + intersectingButton.getText());
                    System.out.println("Collisions: " + maxCollisions);
                    reLayout = true;
                } else {
                    System.out.println("No change made");
                    reLayout = false;
                }

                ArrayList<JButton> tmpButtons = (ArrayList<JButton>) buttons.clone();//create clone of buttons

                if (reLayout) {//a button as moved and panel needs to be layed out
                    buttons.clear();//clear old buttons

                    for (JButton b : tmpButtons) {//re-order jbuttons
                        if (b == intersectingButton) {
                            buttons.add(draggedButton);
                        } else if (b == draggedButton) {
                            buttons.add(intersectingButton);
                        } else {
                            buttons.add(b);
                        }
                    }
                    panel.removeAll();//remove all buttons
                    for (JButton btn : buttons) {//iterate through all buttons and get the number of collsions of each
                        panel.add(btn);//re-add buttons according to arraylist
                    }
                    panel.revalidate();
                    panel.repaint();
                }
                super.componentDropped(me);

            }
        };

        for (int i = 0; i < 4; i++) {
            JButton b = new JButton(String.valueOf(i + 1));
            panel.add(b);
            buttons.add(b);
            cd.registerComponent(b);
        }

        frame.add(panel);

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new DragButtonsTest();
            }
        });
    }

    public HashSet<String> getMask(JButton e) {
        HashSet<String> mask = new HashSet<>();
        int pixel, a;
        BufferedImage bi = componentToImage(e); //gets the current image being shown

        for (int i = 0; i < bi.getWidth(); i++) { // for every (x,y) component in the given box, 
            for (int j = 0; j < bi.getHeight(); j++) {
                pixel = bi.getRGB(i, j); // get the RGB value of the pixel
                a = (pixel >> 24) & 0xff;
                if (a != 0) {  // if the alpha is not 0, it must be something other than transparent
                    mask.add((e.getX() + i) + "," + (e.getY() - j)); // add the absolute x and absolute y coordinates to our set
                }
            }
        }
        return mask;  //return our set
    }

    public static BufferedImage componentToImage(Component component) {
        BufferedImage img = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TRANSLUCENT);
        Graphics g = img.getGraphics();
        component.paintAll(g);
        return img;
    }

    // Returns true if there is a collision between object a and object b   
    public int checkPerPixelCollision(JButton b, JButton b2) {
        // This method detects to see if the images overlap at all. If they do, collision is possible
        int ax1 = (int) b2.getX();
        int ay1 = (int) b2.getY();

        int ax2 = ax1 + (int) b2.getWidth();
        int ay2 = ay1 + (int) b2.getHeight();

        int bx1 = (int) b.getX();
        int by1 = (int) b.getY();

        int bx2 = bx1 + (int) b.getWidth();

        int by2 = by1 + (int) b.getHeight();

        if (by2 < ay1 || ay2 < by1 || bx2 < ax1 || ax2 < bx1) {
            return 0; // Collision is impossible.
        } else { // Collision is possible.
            // get the masks for both images
            HashSet<String> maskPlayer1 = getMask(b2);
            HashSet<String> maskPlayer2 = getMask(b);
            maskPlayer1.retainAll(maskPlayer2);  // Check to see if any pixels in maskPlayer2 are the same as those in maskPlayer1
            if (maskPlayer1.size() > 0) {  // if so, than there exists at least one pixel that is the same in both images, thus
                return maskPlayer1.size();
            }
        }
        return 0;
    }
}

class ComponentDrag {

    private MouseAdapter ma;
    private ArrayList<JComponent> components = new ArrayList<>();
    private int startingX, startingY;
    private boolean autoLayout = true;
    private final JFrame container;
    private JPanel glassPane;
    boolean firstTime = true;
    private JComponent lastClickedContainer;

    public ComponentDrag(final JFrame container) {
        this.container = container;
        glassPane = new JPanel();
        glassPane.setOpaque(false);
        glassPane.setLayout(null);
        this.container.setGlassPane(glassPane);

        new Timer(10, new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                if (container.isVisible()) {
                    glassPane.setVisible(true);
                    ((Timer) ae.getSource()).stop();
                }
            }
        }).start();

        ma = new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent me) {
                super.mousePressed(me);
                componentPressed(me);
            }

            @Override
            public void mouseReleased(MouseEvent me) {
                super.mouseReleased(me);
                componentDropped(me);
            }

            @Override
            public void mouseDragged(MouseEvent me) {
                super.mouseDragged(me);
                componentDragged(me);
            }
        };
    }

    public JComponent findDroppableUnderGlassPane(Point p, Container container, Component source) {
        JComponent c = null;
        Component[] comps = container.getComponents();
        for (Component com : comps) {
            if (com.getName() != null) {
                if (com.getName().equals("Droppable") && com instanceof JComponent) {
                    if (com.contains(SwingUtilities.convertPoint(source, p, com))) {
                        return (JComponent) com;
                    }
                } else if (com instanceof Container) {
                    findDroppableUnderGlassPane(p, (Container) com, source);
                }
            }
        }
        return c;
    }

    public boolean isAutoLayout() {
        return autoLayout;
    }

    public void setAutoLayout(boolean autoLayout) {
        this.autoLayout = autoLayout;
    }

    protected void componentDropped(MouseEvent me) {
        firstTime = true;
        Component droppedComponent = (Component) me.getSource();
        droppedComponent.setCursor(null);

        JComponent jc = findDroppableUnderGlassPane(me.getPoint(), container.getContentPane(), (Component) me.getSource());

        if (jc != null) {
            glassPane.removeAll();
            glassPane.revalidate();
            glassPane.repaint();

            jc.add(droppedComponent);
            System.out.println("Removed from glasspane and added to: " + jc);

            if (autoLayout) {
                if (lastClickedContainer != null) {
                    lastClickedContainer.revalidate();
                    lastClickedContainer.repaint();
                }
                droppedComponent.revalidate();
                droppedComponent.repaint();
                jc.revalidate();
                jc.repaint();
            }

        } else {
            glassPane.removeAll();
            glassPane.revalidate();
            glassPane.repaint();
            if (lastClickedContainer != null) {
                lastClickedContainer.add(droppedComponent);
                lastClickedContainer.revalidate();
                lastClickedContainer.repaint();
            }
        }
    }

    protected void componentPressed(MouseEvent me) {
        JComponent jc = findDroppableUnderGlassPane(me.getPoint(), container.getContentPane(), (Component) me.getSource());

        if (jc != null && jc.getName().equals("Droppable")) {
            lastClickedContainer = jc;
            System.out.println("Pressed: " + lastClickedContainer);
        }

        boolean clickedRegisteredComponent = false;

        Component clickedComponent = (Component) me.getSource();

        for (Component component : ComponentDrag.this.components) {
            if (component.equals(clickedComponent)) {
                clickedRegisteredComponent = true;
                break;
            }
        }

        if (clickedRegisteredComponent) {
            startingX = me.getX();
            startingY = me.getY();
            clickedComponent.setCursor(new Cursor(Cursor.MOVE_CURSOR));
        }
    }

    protected void componentDragged(MouseEvent me) {
        Component draggedComponent = (Component) me.getSource();

        if (firstTime && lastClickedContainer != null) {
            firstTime = false;
            lastClickedContainer.remove(draggedComponent);
            lastClickedContainer.revalidate();
            lastClickedContainer.repaint();
            glassPane.add(draggedComponent);
            glassPane.revalidate();
            glassPane.repaint();
            System.out.println("Removed from: " + lastClickedContainer + " \nAnd added to glasspane for dragging");
        }

        //MouseEvent will refire on each drag with the position being relative to the firing Component
        draggedComponent.setLocation((me.getX() - startingX) + draggedComponent.getLocation().x, (me.getY() - startingY) + draggedComponent.getLocation().y);
    }

    void registerComponent(JComponent draggableComp) {
        draggableComp.addMouseListener(ma);
        draggableComp.addMouseMotionListener(ma);
        components.add(draggableComp);
    }

    void deregisterComponent(JComponent draggableComp) {
        draggableComp.removeMouseListener(ma);
        draggableComp.removeMouseMotionListener(ma);
        components.remove(draggableComp);
    }
}

2) Simply shows how to drag 2 JLabels across JPanels

Before Drag me label dragged:

After label dragged:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

/**
 *
 * @author David
 */
public class DragOverMultipleComponentsTest {

    public DragOverMultipleComponentsTest() {
        createAndShowUI();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new DragOverMultipleComponentsTest();
            }
        });
    }

    private void createAndShowUI() {
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        JLabel draggableLabel = new JLabel("<- Drag me");
        JLabel draggableLabel2 = new JLabel("<- Drag me too");

        JLabel labelPanel1 = new JLabel("Drag 'em here");
        JPanel panel1 = new JPanel() {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(300, 300);
            }
        };
        panel1.add(labelPanel1);
        panel1.setName("Droppable");

        JLabel labelPanel2 = new JLabel("Drag 'em here");
        JPanel panel2 = new JPanel();
        panel2.add(labelPanel2);
        panel2.add(draggableLabel);
        panel2.add(draggableLabel2);
        panel2.setName("Droppable");

        JSeparator js = new JSeparator(JSeparator.VERTICAL);

        ComponentDrag cd = new ComponentDrag(frame);

        cd.registerComponent(draggableLabel);
        cd.registerComponent(draggableLabel2);

        frame.add(panel1, BorderLayout.WEST);
        frame.add(js);
        frame.add(panel2, BorderLayout.EAST);

        frame.pack();
        frame.setVisible(true);
    }
}
class ComponentDrag {

    private MouseAdapter ma;
    private ArrayList<JComponent> components = new ArrayList<>();
    private int startingX, startingY;
    private boolean autoLayout = true;
    private final JFrame container;
    private JPanel glassPane;
    boolean firstTime = true;
    private JComponent lastClickedContainer;

    public ComponentDrag(final JFrame container) {
        this.container = container;
        glassPane = new JPanel();
        glassPane.setOpaque(false);
        glassPane.setLayout(null);
        this.container.setGlassPane(glassPane);

        new Timer(10, new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                if (container.isVisible()) {
                    glassPane.setVisible(true);
                    ((Timer) ae.getSource()).stop();
                }
            }
        }).start();

        ma = new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent me) {
                super.mousePressed(me);
                componentPressed(me);
            }

            @Override
            public void mouseReleased(MouseEvent me) {
                super.mouseReleased(me);
                componentDropped(me);
            }

            @Override
            public void mouseDragged(MouseEvent me) {
                super.mouseDragged(me);
                componentDragged(me);
            }
        };
    }

    public JComponent findDroppableUnderGlassPane(Point p, Container container, Component source) {
        JComponent c = null;
        Component[] comps = container.getComponents();
        for (Component com : comps) {
            if (com.getName() != null) {
                if (com.getName().equals("Droppable") && com instanceof JComponent) {
                    if (com.contains(SwingUtilities.convertPoint(source, p, com))) {
                        return (JComponent) com;
                    }
                } else if (com instanceof Container) {
                    findDroppableUnderGlassPane(p, (Container) com, source);
                }
            }
        }
        return c;
    }

    public boolean isAutoLayout() {
        return autoLayout;
    }

    public void setAutoLayout(boolean autoLayout) {
        this.autoLayout = autoLayout;
    }

    protected void componentDropped(MouseEvent me) {
        firstTime = true;
        Component droppedComponent = (Component) me.getSource();
        droppedComponent.setCursor(null);

        JComponent jc = findDroppableUnderGlassPane(me.getPoint(), container.getContentPane(), (Component) me.getSource());

        if (jc != null) {
            glassPane.removeAll();
            glassPane.revalidate();
            glassPane.repaint();

            jc.add(droppedComponent);
            System.out.println("Removed from glasspane and added to: " + jc);

            if (autoLayout) {
                if (lastClickedContainer != null) {
                    lastClickedContainer.revalidate();
                    lastClickedContainer.repaint();
                }
                droppedComponent.revalidate();
                droppedComponent.repaint();
                jc.revalidate();
                jc.repaint();
            }

        } else {
            glassPane.removeAll();
            glassPane.revalidate();
            glassPane.repaint();
            if (lastClickedContainer != null) {
                lastClickedContainer.add(droppedComponent);
                lastClickedContainer.revalidate();
                lastClickedContainer.repaint();
            }
        }
    }

    protected void componentPressed(MouseEvent me) {
        JComponent jc = findDroppableUnderGlassPane(me.getPoint(), container.getContentPane(), (Component) me.getSource());

        if (jc != null && jc.getName().equals("Droppable")) {
            lastClickedContainer = jc;
            System.out.println("Pressed: " + lastClickedContainer);
        }

        boolean clickedRegisteredComponent = false;

        Component clickedComponent = (Component) me.getSource();

        for (Component component : ComponentDrag.this.components) {
            if (component.equals(clickedComponent)) {
                clickedRegisteredComponent = true;
                break;
            }
        }

        if (clickedRegisteredComponent) {
            startingX = me.getX();
            startingY = me.getY();
            clickedComponent.setCursor(new Cursor(Cursor.MOVE_CURSOR));
        }
    }

    protected void componentDragged(MouseEvent me) {
        Component draggedComponent = (Component) me.getSource();

        if (firstTime && lastClickedContainer != null) {
            firstTime = false;
            lastClickedContainer.remove(draggedComponent);
            lastClickedContainer.revalidate();
            lastClickedContainer.repaint();
            glassPane.add(draggedComponent);
            glassPane.revalidate();
            glassPane.repaint();
            System.out.println("Removed from: " + lastClickedContainer + " \nAnd added to glasspane for dragging");
        }

        //MouseEvent will refire on each drag with the position being relative to the firing Component
        draggedComponent.setLocation((me.getX() - startingX) + draggedComponent.getLocation().x, (me.getY() - startingY) + draggedComponent.getLocation().y);
    }

    void registerComponent(JComponent draggableComp) {
        draggableComp.addMouseListener(ma);
        draggableComp.addMouseMotionListener(ma);
        components.add(draggableComp);
    }

    void deregisterComponent(JComponent draggableComp) {
        draggableComp.removeMouseListener(ma);
        draggableComp.removeMouseMotionListener(ma);
        components.remove(draggableComp);
    }
}

这篇关于如何设置优先级的鼠标监听器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆