用于在 Java 中拖动组件的 Swing 库

Posted

技术标签:

【中文标题】用于在 Java 中拖动组件的 Swing 库【英文标题】:Swing Library for Dragging Components in Java 【发布时间】:2018-05-31 21:37:02 【问题描述】:

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

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);
    


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

我已经在 *** 和 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);
    

【问题讨论】:

setBounds 和 repaint 应该可以帮到你。我记得几年前做过类似的事情,让我的按钮“可拖动”。 【参考方案1】:

拖动一个组件的基本代码是:

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 课程。它允许您拖动桌面上的窗口或面板中的组件。它提供了更多的拖动功能。

编辑:

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

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 还很陌生。我通常一直在用 C 进行编码,而 OOP 对我来说仍然很新。事实上,这是我对复杂代码的第一次尝试。我创建了一个名为FBDragListener 的新类,并且基本上复制了您的代码。然后,在FBButton 内部,我添加了一个新行,例如 ... FBDragListener listener public FBButton() listener = new FBDragListener() ... 我认为这会使按钮能够移动。我没有收到任何错误,但程序似乎功能相同[按钮在那里并且可点击,但无法移动]。 您阅读了提供的链接吗?您是否将侦听器添加到按钮?您的面板是否使用空布局? 我确实阅读了提供的链接,感谢您提供该工具。我仍在尝试合成它,但我感谢您为我采购它。我将侦听器添加到按钮并将 Jpanel p 更改为 p.setLayout(null) 。奇怪的是现在我的按钮根本没有显示,即使我使用 setLocation() 作为按钮。我将编辑我的问题以反映更新后的代码。 我忘了删除那个旧的尝试。我刚刚编辑了我的帖子以反映新的鼠标监听器。在 FBPlayerFrame 中,我在循环中设置了大小。您提供的代码我在名为FBMouseListener 的课程中​​使用,我尝试将其添加到FBButton。我一定是添加错了,因为我无法移动按钮。此外,一旦我将布局更改为null,我将无法再看到按钮,即使看起来我设置了大小和位置。

以上是关于用于在 Java 中拖动组件的 Swing 库的主要内容,如果未能解决你的问题,请参考以下文章

java Swing组件随着窗口拖动等比移动或等比放大

使组件对 Swing 中的拖动不那么敏感

Java Swing:轻量级和重量级组件的叠加组件?

从 UI 调整 java swing 组件的大小

请推荐漂亮的 Java Swing 组件库 [关闭]

java的swing组件的使用