Swing: Creating a draggable component…?

后端 未结 2 2077
失恋的感觉
失恋的感觉 2020-12-03 04:49

I searched the web for examples of draggable Swing components, but I found either incomplete or non-working examples.

What I need is a Swing component

相关标签:
2条回答
  • 2020-12-03 05:29

    I propose a simple, but well-working solution, found out by myself ;)

    What do I do?

    • When mouse is pressed, I record the cursor's position on screen, and the component's position.
    • When mouse is dragged, I calculate the difference between new and old cursor's position on screen, and move the component by this difference.

    Tested with latest JDK 6 unter Linux (OpenSuse, KDE3),
    but hey, it's Java Swing, should work equally everywhere.

    Here goes the code:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.border.*;
    
    public class MyDraggableComponent
        extends JComponent {
    
      private volatile int screenX = 0;
      private volatile int screenY = 0;
      private volatile int myX = 0;
      private volatile int myY = 0;
    
      public MyDraggableComponent() {
        setBorder(new LineBorder(Color.BLUE, 3));
        setBackground(Color.WHITE);
        setBounds(0, 0, 100, 100);
        setOpaque(false);
    
        addMouseListener(new MouseListener() {
    
          @Override
          public void mouseClicked(MouseEvent e) { }
    
          @Override
          public void mousePressed(MouseEvent e) {
            screenX = e.getXOnScreen();
            screenY = e.getYOnScreen();
    
            myX = getX();
            myY = getY();
          }
    
          @Override
          public void mouseReleased(MouseEvent e) { }
    
          @Override
          public void mouseEntered(MouseEvent e) { }
    
          @Override
          public void mouseExited(MouseEvent e) { }
    
        });
        addMouseMotionListener(new MouseMotionListener() {
    
          @Override
          public void mouseDragged(MouseEvent e) {
            int deltaX = e.getXOnScreen() - screenX;
            int deltaY = e.getYOnScreen() - screenY;
    
            setLocation(myX + deltaX, myY + deltaY);
          }
    
          @Override
          public void mouseMoved(MouseEvent e) { }
    
        });
      }
    
    }
    
    public class Main {
    
      public static void main(String[] args) {
        JFrame f = new JFrame("Swing Hello World");
    
        // by doing this, we prevent Swing from resizing
        // our nice component
        f.setLayout(null);
    
        MyDraggableComponent mc = new MyDraggableComponent();
        f.add(mc);
    
        f.setSize(500, 500);
    
        f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        f.setVisible(true);
      }
    
    }
    
    0 讨论(0)
  • 2020-12-03 05:53

    Also, I found out that one could create an JInternalFrame inside an JFrame, but the problem is: you get always an annoying window title bar.

    To disable the title bar, sadly, a dirty workaround is necessary:

    public class MyDraggableComponent extends JInternalFrame {
    
      public MyDraggableComponent() {
        InternalFrameUI thisUI = getUI();
        if (thisUI instanceof BasicInternalFrameUI) {
          ((BasicInternalFrameUI) thisUI).setNorthPane(null);
        }
    
    }
    

    I really miss a method like "someInternalFrame.setWindowTitleBar(false)"...
    :'(

    0 讨论(0)
提交回复
热议问题