24

ドラッグ可能なSwingコンポーネントの例をウェブで検索しましたが、不完全または機能しない例が見つかりました。

必要なのは、他のコンポーネント内でマウスによってドラッグできるSwingコンポーネントです。ドラッグされている間、目的地に「ジャンプ」するだけでなく、すでにその位置を変更しているはずです。

非標準のAPIがなくても機能する例をいただければ幸いです。

ありがとうございました。

4

2 に答える 2

38

私は、自分で見つけた、シンプルでありながらうまく機能するソリューションを提案します;)

私は何をしますか?

  • マウスを押すと、画面上のカーソルの位置とコンポーネントの位置を記録します。
  • マウスをドラッグすると、画面上の新旧のカーソル位置の差を計算し、この差でコンポーネントを移動します。

最新のJDK6unter Linux(OpenSuse、KDE3)でテストされて
いますが、Java Swingであり、どこでも同じように機能するはずです。

コードは次のとおりです。

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

}
于 2009-05-17T11:43:03.023 に答える
2

また、JFrame内にJInternalFrameを作成できることもわかりましたが、問題は、常に迷惑なウィンドウタイトルバーが表示されることです。

タイトルバーを無効にするには、悲しいことに、汚い回避策が必要です。

public class MyDraggableComponent extends JInternalFrame {

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

}

「someInternalFrame.setWindowTitleBar(false)」のようなメソッドが本当に恋しいです...
:'(

于 2009-05-18T09:28:20.037 に答える