Swing/DragWindow のバックアップの現在との差分(No.8)
TITLE:JWindowをマウスで移動
Posted by aterai at 2004-09-06
JWindowをマウスで移動
JWindowなどのタイトルバーのないフレームをマウスで移動します。- category: swing folder: DragWindow title: JWindowをマウスで移動 tags: [JWindow, JFrame, MouseListener, MouseMotionListener] author: aterai pubdate: 2004-09-06T00:58:19+09:00 description: JWindowなどのタイトルバーのないフレームをマウスで移動します。 image:
概要
JWindow
などのタイトルバーのないフレームをマウスで移動します。
- &jnlp;
- &jar;
- &zip;
Screenshot
Advertisement
サンプルコード
サンプルコード
public void createSplashScreen(String path) {
ImageIcon img = new ImageIcon(getClass().getResource(path));
DragWindowListener dwl = new DragWindowListener();
splashLabel = new JLabel(img);
splashLabel.addMouseListener(dwl);
splashLabel.addMouseMotionListener(dwl);
splashScreen = new JWindow(getFrame());
splashScreen.getContentPane().add(splashLabel);
splashScreen.pack();
splashScreen.setLocationRelativeTo(null);
}
#spanadd
#spanend
class DragWindowListener extends MouseAdapter {
private MouseEvent start;
//private Point loc;
private final Point startPt = new Point();
private Window window;
#spanadd
#spanend
@Override public void mousePressed(MouseEvent me) {
start = me;
startPt.setLocation(me.getPoint());
}
#spanadd
#spanend
@Override public void mouseDragged(MouseEvent me) {
if(window==null) {
if (window == null) {
window = SwingUtilities.windowForComponent(me.getComponent());
}
Point eventLocationOnScreen = me.getLocationOnScreen();
window.setLocation(eventLocationOnScreen.x - start.getX(),
eventLocationOnScreen.y - start.getY());
//loc = window.getLocation(loc);
//int x = loc.x - start.getX() + me.getX();
//int y = loc.y - start.getY() + me.getY();
//window.setLocation(x, y);
window.setLocation(eventLocationOnScreen.x - startPt.x,
eventLocationOnScreen.y - startPt.y);
// loc = window.getLocation(loc);
// int x = loc.x - start.getX() + me.getX();
// int y = loc.y - start.getY() + me.getY();
// window.setLocation(x, y);
}
}
View in GitHub: Java, Kotlin解説
JWindowや、setUndecorated(true)したJFrameのようにタイトルバーのないフレームをマウスのドラッグで移動します。実際はJWindowに、MouseMotionListenerなどを実装したコンポーネントを追加しています。解説
JWindow
やsetUndecorated(true)
したJFrame
のようにタイトルバーのないフレームをマウスのドラッグで移動します。実際はJWindow
自体にリスナーを設定するのではなく子コンポーネントにMouseMotionListener
などを追加しています。
上記のサンプルでは、Splash ScreenのJLabelにリスナーを追加し、これをJWindowに貼り付けてドラッグできるようにしています。
上記のサンプルではJLabel
にリスナーを追加し、これをJWindow
に配置してドラッグ可能にしています。
次に開くsetUndecorated(true)したJFrameでは、青いラベル部分をドラッグすることが出来ます。
- スプラッシュスクリーンの次に開く
JFrame
はJFrame#setUndecorated(true)
を設定してタイトルバーなどは非表示 - 代わりに青いラベル部分をドラッグ可能に設定
- マルチディスプレイなどで、別画面に移動できないバグ?を修正。
- ただし、Web Start のSandBox内では、以前と同じく画面の外に移動することができない?
- JNLP のセキュリティに all-permissions を設定する必要がある
- ただし、Web Start のSandBox内では、以前と同じく画面の外に移動することができない?
- マルチディスプレイなどで別画面に移動できないバグ?を修正
- ただし
Web Start
のSandBox
内では以前と同じく画面の外までは移動不可?-
JNLP
のセキュリティにall-permissions
を設定する必要がある
-
- ただし
-
Swing Tutorial
の FrameDemo2で試しても、同様?-
Look and feel decorated
: 画面外に移動不可 -
Window system decorated
: 画面外に移動可能
-
- Swing Tutorial の FrameDemo2で試しても、同様?
- "Look and feel decorated": 画面外に移動不可
- "Window system decorated": 画面外に移動可能
参考リンク
参考リンク
コメント
-
JLabel
無しでJFrame
を直接つかんで移動させようと,ソース中のDragWindowListener
をFrame
の引数に指定してaddMouseListener()
,addMouseMotionListener()
に追加してみたのですが,うまく動きませんでした。ラベルではなくフレームを直接つかんで移動させるにはどうすればよいのでしょうか? -- hshs-
frame.getContentPane().addMouseListener(dwl);...
と、ContentPane
かRootPane
にDragWindowListener
を追加するか、以下のようにDragWindowListener
を変更するのはどうでしょうか? -- aterai
-
コメント
- bloggerの方にコメントをもらって、調査、修正中だけど、dual-monitor 環境が無いのでテストしづらい…。 -- aterai
#spanend #spanadd import java.awt.*; #spanend #spanadd import java.awt.event.*; #spanend #spanadd import javax.swing.*; #spanend #spanadd public class MainPanel { #spanend public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { createAndShowGUI(); } }); } public static void createAndShowGUI() { DragWindowListener dwl = new DragWindowListener(); JFrame frame = new JFrame(); frame.setUndecorated(true); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.addMouseListener(dwl); frame.addMouseMotionListener(dwl); frame.setSize(320, 240); frame.setLocationRelativeTo(null); frame.setVisible(true); } #spanadd } #spanend #spanadd #spanend #spanadd class DragWindowListener extends MouseAdapter { #spanend private final Point startPt = new Point(); private Window window; #spanadd #spanend @Override public void mousePressed(MouseEvent me) { if (window == null) { Object o = me.getSource(); if (o instanceof Window) { window = (Window) o; } else if (o instanceof JComponent) { window = SwingUtilities.windowForComponent(me.getComponent()); } } startPt.setLocation(me.getPoint()); } #spanadd #spanend @Override public void mouseDragged(MouseEvent me) { if (window != null) { Point eventLocationOnScreen = me.getLocationOnScreen(); window.setLocation(eventLocationOnScreen.x - startPt.x, eventLocationOnScreen.y - startPt.y); } } #spanadd } #spanend #spanadd
- えーと、このソースは新たに
JPanel
を継承してるんですね、という事は結局、JFrame
自体をマウスドラッグでつかむことが出来ないということなんでしょうか? -- hshs-
JFrame
のContentPane
にJPanel
を継承したサンプルコンポーネントを追加してるだけです。必要ないなら上記のように削除して(どこを削除したかはこのページ上にある「編集された箇所をみる」などで調べてください)調査してみるのがお手軽なのでオススメです。JFrame
に追加したリスナーでJFrame
の移動を行うことは可能ですが、本当に「JFrame
自体をマウスドラッグでつかむことが出来ない」かどうかについては、内部での処理を追っていないのでよく分かりません。 -- aterai
-
- 返信ありがとうございます,最初のサンプル中の
createAndShowGUI()
内や,showFrame()
や,start(JFrame frame)
内などに,DragWindowListener dwl = new DragWindowListener();
とframe.addMouseListener(dwl);
とframe.addMouseMotionListener(dwl);
を入れて見たりしたのですが動作しないのですが,これは何故なんでしょうか?、何か必要な命令が足りないのでしょうか。 -- hshs- 失礼、見落としてました。自分の環境(
JDK 1.7.0_17
,Windows 7
)では、特に問題なく動作(Exception
なども出ていない)しています。環境と変更したソース自体をどこか(例えば https://gist.github.com/ とか)に投稿できますか? -- aterai
- 失礼、見落としてました。自分の環境(
- あっ、動作しないというのは「
JFrame
自体をマウスドラッグでつかむことが出来ない」という意味で,通常の動作は問題ないです,上記のように追加変更して見たら,ラベルの部分だけでなく真ん中のフレーム部分を,マウスでドラッグしてつかんで移動させられるのかなと思ったのですが,実際つかんで移動させようとすると,Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
が出てきてつかめなかったので....。GitHubのアカウントは持ってないですw,環境はJDK1.7.0_15
,win7
,64bit
,ソースは上の三行を追加してみただけです。 --- 「上の三行を追加してみただけ」だと
DragWindowListener
が新しくなっていない(コメントのDragWindowListener
になっていない)ので、NullPointerException
が発生していると考えて良さそうです(ソースコードの行とかが分からないので推測ですが)。src.zip
やリポジトリのDragWindowListener
も更新した(ついでに上記のコメントのDragWindowListener
もアップデート)ので、最新版で試してみてください。 -- aterai - 余談: gistってアカウント必要でしたっけ? -- aterai
- 「上の三行を追加してみただけ」だと
- gistってアカウント無しで投稿出来るんですね,知りませんでしたm(__)m,再UPしていただいた
src.zip
で上記の動作を確認できました。ありがとうございます。DragWindowListener
内部の追加されていたコードの意味が自分にはまだ理解できませんが,もっと勉強したいと思います。 -- hshs