java - Java 中用于拖动组件的 Swing 库

标签 java swing draggable

我正在尝试创建一种图形编辑器,允许用户创建美式足球比赛的图形描述。为此,用户应该能够执行以下操作:

1) 单击鼠标左键并移动图像

2) 更改图像(圆形、正方形和线条)

3) 重置所有对象的大小

理想情况下,我希望能够添加可调整的颜色和线条粗细,但这还很遥远。

现在,我所能做的就是创建 JButton,单击时循环显示图像。我想我想将其更改为 JComboBox,以便用户可以直接转到正确的图像。这是我的类:FBButton

import javax.swing.*;
import java.awt.event.*;

@SuppressWarnings("serial")
public class FBButton extends JButton implements ActionListener {
    ImageIcon SN, SL, SR, SC, CN, CL, CR, CC, IN;
    byte value = 0;
    FBMouseListener listener;

    public FBButton() {

        listener = new FBMouseListener();

        SN = new ImageIcon(this.getClass().getResource("square_null.png"));
        SL = new ImageIcon(this.getClass().getResource("square_left.png"));
        SR = new ImageIcon(this.getClass().getResource("square_right.png"));
        SC = new ImageIcon(this.getClass().getResource("square_line.png"));

        CN = new ImageIcon(this.getClass().getResource("circle_null.png"));
        CL = new ImageIcon(this.getClass().getResource("circle_left.png"));
        CR = new ImageIcon(this.getClass().getResource("circle_right.png"));
        CC = new ImageIcon(this.getClass().getResource("circle_line.png"));

        IN = new ImageIcon(this.getClass().getResource("invisible.png"));

        addActionListener(this);
    }

    public void actionPerformed(ActionEvent e) {
        value++;
        value %= 9;

        if (value == 1) {
            setIcon(SN);
        } else if (value == 2) {
            setIcon(SL);
        } else if (value == 3) {
            setIcon(SR);
        } else if (value == 4) {
            setIcon(SC);
        } else if (value == 5) {
            setIcon(CN);
        } else if (value == 6) {
            setIcon(CL);
        } else if (value == 7) {
            setIcon(CR);
        } else if (value == 8) {
            setIcon(CC);
        } else {
            setIcon(IN);
        }


    }

}

这些按钮有效并且可以找到图像。这是我的 FBPlayerFrame 类的代码

package swing;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class FBPlayerFrame extends JFrame {

    JPanel p = new JPanel();
    FBButton buttons[] = new FBButton[22];
    String choices[] = { "Hallo", "Bonjour", "Conichuwa" };
    JComboBox boxes[];
    JComboBox here = new JComboBox(choices);
    FBComboBox vince;

    Dimension dim = new Dimension(52, 52);

    public static void main(String[] args) {
        new FBPlayerFrame();
    }

    public FBPlayerFrame() {
        super("Football Start");
        setSize(400, 400);
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        p.setLayout(null);


        for (int i = 0; i < 4; i++) {
            buttons[i] = new FBButton();
            buttons[i].setPreferredSize(dim);
            buttons[i].setLocation(20, 40 + 60 * i);
            p.add(buttons[i]);


        }


        add(p);

        setVisible(true);
    }

}

本着保持具体的精神,我首先寻找的是在整个框架中左键单击并拖动 JButtons 或 JComboBoxes 的能力。如果可以在某个时候保存按钮的坐标,这也会对以后有所帮助,但现在没有必要。

我在 StackOverflow 和 youtube 上搜索了类似的问题,但很难找到能具体回答我的问题的内容。

更新:这是我的 FBMouseListener 代码

package swing;

import java.awt.Component;
import java.awt.Point;
import java.awt.event.*;
import javax.swing.event.MouseInputAdapter;

public class FBMouseListener extends MouseInputAdapter {
    Point location;
    MouseEvent pressed;

    public void mousePressed(MouseEvent me) {
        pressed = me;
        System.out.println("Found me");
    }

    public void mouseDragged(MouseEvent me) {
        Component component = me.getComponent();
        location = component.getLocation(location);
        int x = location.x - pressed.getX() + me.getX();
        int y = location.y - pressed.getY() + me.getY();
        System.out.println("(" + x + ", " + y + ")");
        component.setLocation(x, y);
    }
}

最佳答案

拖动组件的基本代码是:

public class DragListener extends MouseInputAdapter
{
    Point location;
    MouseEvent pressed;

    public void mousePressed(MouseEvent me)
    {
        pressed = me;
    }

    public void mouseDragged(MouseEvent me)
    {
        Component component = me.getComponent();
        location = component.getLocation(location);
        int x = location.x - pressed.getX() + me.getX();
        int y = location.y - pressed.getY() + me.getY();
        component.setLocation(x, y);
     }
}

您创建该类的单个实例,然后将其添加到您想要拖动的任何组件。

DragListener drag = new DragListener();
component.addMouseListener( drag );
component.addMouseMotionListener( drag );

您还可以查看Component Mover类(class)。它允许您拖动桌面上的窗口或面板中的组件。它提供了更多的拖动功能。

编辑:

我需要几行代码来测试这个解决方案:

JButton button = new JButton("hello");
button.setSize( button.getPreferredSize() );

DragListener drag = new DragListener();
button.addMouseListener( drag );
button.addMouseMotionListener( drag );

JPanel panel = new JPanel( null );
panel.add( button );

JFrame frame = new JFrame();
frame.add( panel );
frame.setSize(400, 400);
frame.setVisible( true );

将上述代码放入 main() 方法中,您就可以得到简单的代码来测试。

关于java - Java 中用于拖动组件的 Swing 库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47870238/

相关文章:

java - 为 Log4j 1.2 注册自定义 LoggerFactory 的正确方法?

java - 无法在 VS 代码上运行 Tomcat 服务器

javascript - 停止这个奇怪的 jQuery 故障

java - 在 Swing 应用程序启动期间,首次调用 JFrame 构造函数需要很长时间(因为 java.awt.Window())

java - Java游戏的键盘输入

java - 单击按钮后关闭 JFrame Java

java - JLabel setLocation 不起作用?

java - 如何将 StringTokenizer 与我的 jTable 一起使用

javascript - 类似于 Wufoo 的 Web 界面(可拖动元素、记住状态)

javascript - event.dataTransfer 和 event.originalEvent 在 dragstart 事件处理程序中始终为 null