在Java Swing窗口中移动对象

在Java Swing窗口中移动对象,java,swing,user-interface,java-2d,Java,Swing,User Interface,Java 2d,我这里的代码显示了一个带有四个千斤顶的摆动窗口。我想能够点击并移动窗口周围的千斤顶。我知道他们需要重新画,但我不知道该怎么做 我怎样才能让用户点击并移动卡片 package p2test; import javax.swing.*; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.awt.*; public c

我这里的代码显示了一个带有四个千斤顶的摆动窗口。我想能够点击并移动窗口周围的千斤顶。我知道他们需要重新画,但我不知道该怎么做

我怎样才能让用户点击并移动卡片

package p2test;
import javax.swing.*;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.awt.*;

public class main
{
    public static final int PERIMETER_BEVEL = 20;  //space between panel border and perimeter cards
    public static final int LEFT_PERIMETER_BEVEL = 98;
    public static final int INTERIOR_BEVEL = 5;                 //space between cards
    public static final int CARD_HEIGHT = 97;
    public static final int CARD_WIDTH = 73;    

    public static final int PANEL_HEIGHT = (2*PERIMETER_BEVEL) + (4*CARD_HEIGHT) + (3*INTERIOR_BEVEL);
    public static final int PANEL_WIDTH = (2*PERIMETER_BEVEL) + (14*CARD_WIDTH) + (13*INTERIOR_BEVEL);

public static final String   BACKGROUND_COLOR = "#64C866";  //window background color [hex]
public static final String   CARD_FOLDER = "cardImages";    //default folder containing images

public static final String [] RANKS = {  "jack"};
public static final ArrayList<String> ranks = new ArrayList<String>(Arrays.asList(RANKS));

public static void main(String[] args)
{
    JFrame window = new JFrame("deck");
    JPanel panel = new JPanel() {
        public void paintComponent(Graphics g) {                     //find each rank of card in increasing
            super.paintComponent(g);                                 //order as specified in the array. All
            File[] files = new File(CARD_FOLDER).listFiles();        //ranks appear in the same suit order in

          //the filesystem so suits will automatically  
          //be in order when printing in groups of four
          //cards.
            int counter = 0;
            for(String rank : ranks) {                              
                for(File filename : files) {                        
                    if(filename.getName().contains(rank)) {
                        new ImageIcon(filename.getPath()).paintIcon(this, g,
                            LEFT_PERIMETER_BEVEL + (counter/4) * (CARD_WIDTH + INTERIOR_BEVEL),
                            PERIMETER_BEVEL + (3-(counter%4)) * (CARD_HEIGHT + INTERIOR_BEVEL));
                        counter++;
                      //counter/4 keeps track of the correct column
                      //3-(counter%4) keeps track of the correct row
                      //in which to print the card image
                    }                                                
                }                                                    
            }            
        }

    };
    panel.setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
    window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    window.setBackground(Color.decode(BACKGROUND_COLOR));
    window.add(panel);
    window.setVisible(true);    
    window.pack();
}
}
包装测试;
导入javax.swing.*;
导入java.io.File;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.Collections;
导入java.awt.*;
公共班机
{
公共静态最终整型周长_斜角=20;//面板边框和周长卡之间的空间
公共静态最终int左_周长_斜角=98;
public static final int INTERIOR_斜角=5;//卡之间的空间
公共静态最终int卡_高度=97;
公共静态最终int卡_宽度=73;
公共静态最终整型面板高度=(2*周长斜面)+(4*卡片高度)+(3*内部斜面);
公共静态最终整型面板(宽度=(2*周长(斜面)+(14*卡片宽度)+(13*内部(斜面));
公共静态最终字符串BACKGROUND_COLOR=“#64C866”//窗口背景色[hex]
公共静态最终字符串CARD\u FOLDER=“cardImages”//包含图像的默认文件夹
公共静态最终字符串[]秩={“jack”};
public static final ArrayList ranks=新的ArrayList(Arrays.asList(ranks));
公共静态void main(字符串[]args)
{
JFrame窗户=新JFrame(“甲板”);
JPanel面板=新的JPanel(){
public void paintComponent(图g){//查找每一个等级的卡片,增加
super.paintComponent(g);//数组中指定的顺序。全部
File[]files=new File(CARD_FOLDER).listFiles();//等级以相同的顺序显示在
//文件系统将自动运行
//四人一组打印时要整齐
//卡片。
int计数器=0;
对于(字符串秩:秩){
对于(文件名:files){
if(filename.getName().contains(rank)){
新的ImageIcon(filename.getPath()).paintIcon(这个,g,
左周长斜面+(计数器/4)*(卡片宽度+内部斜面),
周长斜面+(3-(计数器%4))*(卡高度+内部斜面));
计数器++;
//计数器/4跟踪正确的列
//3-(计数器%4)跟踪正确的行
//在其中打印卡图像
}                                                
}                                                    
}            
}
};
面板。设置首选尺寸(新尺寸(面板宽度、面板高度));
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
窗口.背景(颜色.解码(背景色));
窗口。添加(面板);
window.setVisible(true);
window.pack();
}
}

我可以通过添加这个来移动卡片。 实现这一点的更好方法是遵循MadProgrammer和Andrew Thompson的建议

public static MouseInputAdapter mouseHandler = new MouseInputAdapter(){
    //internal JLabel displacement on mouse press for smooth dragging
    public int labelDisX;   
    //internal JLabel displacement on mouse press for smooth dragging
    public int labelDisY;                 
    public void mousePressed(MouseEvent e) {
        labelDisX = e.getX();
        labelDisY = e.getY();
        //move the card above all others
        e.getComponent().getParent().setComponentZOrder(e.getComponent(), 0); 
        //repaint so card moves above others
        e.getComponent().getParent().repaint();                               
    }
    public void mouseDragged (MouseEvent e) {
        JPanel panel = (JPanel) e.getComponent().getParent();
        //get preliminary new X coordinate
        int newX = e.getComponent().getX() + e.getX() - labelDisX; 
        //get preliminary new Y coordinate
        int newY = e.getComponent().getY() + e.getY() - labelDisY;  
        //here we check that the card is not
        //being moved off the panel. If the
        //user does try and do this then
        //make the new coordinates such that
        //the card is bounded by the panel's
        //edges [extra credit]
        if(newX > panel.getWidth() - CARD_WIDTH) {
            newX = panel.getWidth() - CARD_WIDTH;                             
        }                                                                     
        if(newY > panel.getHeight() - CARD_HEIGHT) {                          
            newY = panel.getHeight() - CARD_HEIGHT;                           
        }                                                                     
        if(newX < 0) { newX = 0; }                                            
        if(newY < 0) { newY = 0; }
        e.getComponent().setLocation(newX, newY);
    }
};
public static MouseInputAdapter mouseHandler=new MouseInputAdapter(){
//鼠标按下时的内部JLabel位移可实现平滑拖动
公共国际实验室;
//鼠标按下时的内部JLabel位移可实现平滑拖动
公共实验室;
公共无效鼠标按下(MouseEvent e){
labelDisX=e.getX();
labelDisY=e.getY();
//将卡移动到所有其他卡之上
e、 getComponent().getParent().setComponentZOrder(如getComponent(),0);
//重新绘制,使卡牌移动到其他卡牌之上
e、 getComponent().getParent().repaint();
}
公共无效鼠标标记(鼠标事件e){
JPanel面板=(JPanel)e.getComponent().getParent();
//获得新的X坐标
int newX=e.getComponent().getX()+e.getX()-labelDisX;
//获得新的Y坐标
int newY=e.getComponent().getY()+e.getY()-labelDisY;
//在这里,我们检查该卡是否正确
//正在从面板上移出。如果
//用户会尝试这样做
//使新坐标为
//该卡由面板的
//边缘[额外学分]
if(newX>panel.getWidth()-CARD_WIDTH){
newX=panel.getWidth()-卡片宽度;
}                                                                     
如果(newY>panel.getHeight()-CARD_HEIGHT){
newY=panel.getHeight()-卡片高度;
}                                                                     
如果(newX<0){newX=0;}
如果(newY<0){newY=0;}
e、 getComponent().setLocation(newX,newY);
}
};

同样,不要在
paintComponent
中加载资源,这会降低编程速度并消耗大量资源。您需要定义一个虚拟视图,通过该视图,您可以确定是否单击了给定对象,并通过更改该对象在该视图中的位置来移动它,并在屏幕上实现……您可能会发现并使用@MadProgrammer的sages建议,我注意到代码中提到了“行和列”。如果卡从不重叠,请考虑在<代码> JButton < /代码>中显示每一个,在<代码> GridLayout < /C>中。我在问答中使用了这项技术,它极大地简化了检测点击和移动物体的过程——正如在动画中看到的那样,移动爪子。抛开我的画质问题,我确实需要让它们重叠。我已经看过鼠标侦听器和鼠标运动侦听器,但我