---
category: swing
folder: DragInternalFrameTranslucency
title: JInternalFrameがマウスドラッグで移動中はそのフレームを半透明に変更する
tags: [JInternalFrame, JDesktopPane, DesktopManager]
author: aterai
pubdate: 2022-01-17T05:22:52+09:00
description: JInternalFrameがマウスドラッグで移動中の場合はそのフレームを半透明に変更して背景が確認できるよう設定します。
image: https://drive.google.com/uc?id=190_fQzLU52FgANH4SrQqL-psTVSgQ0RS
---
* 概要 [#summary]
`JInternalFrame`がマウスドラッグで移動中の場合はそのフレームを半透明に変更して背景が確認できるよう設定します。

#download(https://drive.google.com/uc?id=190_fQzLU52FgANH4SrQqL-psTVSgQ0RS)

* サンプルコード [#sourcecode]
#code(link){{
JDesktopPane desktop = new JDesktopPane();
desktop.setDesktopManager(new DefaultDesktopManager() {
  @Override public void beginDraggingFrame(JComponent f) {
    setDraggingFrame(f);
    super.beginDraggingFrame(f);
  }

  @Override public void endDraggingFrame(JComponent f) {
    setDraggingFrame(null);
    super.endDraggingFrame(f);
    f.repaint();
  }

  @Override public void beginResizingFrame(JComponent f, int direction) {
    setDraggingFrame(f);
    desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
    super.beginResizingFrame(f, direction);
  }

  @Override public void endResizingFrame(JComponent f) {
    setDraggingFrame(null);
    desktop.setDragMode(JDesktopPane.LIVE_DRAG_MODE);
    super.endResizingFrame(f);
  }
});
}}

* 解説 [#explanation]
- `DesktopManager#beginDraggingFrame(...)`をオーバーライドしてマウスでドラッグ中の`JInternalFrame`を記憶
-- `DefaultDesktopManager`では`JInternalFrame#isDragging`を切り替えているが、このフィールドはパッケージプライベートなのでこのサンプルでは使用できない

- `JInternalFrame#paintComponent(...)`をオーバーライドして自身がドラッグ中の場合は半透明で描画する
-- 半透明化することで`JDesktop#setDragMode(JDesktopPane.OUTLINE_DRAG_MODE)`のアウトラインモードにしなくても移動中の背景が確認しやすくなる
#code{{
JInternalFrame frame = new JInternalFrame(title, true, true, true, true) {
  @Override protected void paintComponent(Graphics g) {
    // if (isDragging) { // JInternalFrame#isDragging: package private
    if (getDraggingFrame() == this) {
      ((Graphics2D) g).setComposite(
          AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .2f));
    }
    super.paintComponent(g);
  }
};
}}

- `DesktopManager#endDraggingFrame(...)`をオーバーライドしてマウスでドラッグ中の`JInternalFrame`の参照をクリアし、自身を再描画
-- `JDesktopPane.LIVE_DRAG_MODE`ではドラッグ移動終了後自動的に再描画は実行されないので、ここで`JInternalFrame.repaint()`を実行しないとフレームが半透明のままになってしまう

----
- 同様に`DesktopManager#beginResizingFrame(...)`、`DesktopManager#endResizingFrame(...)`をオーバーライドしてリサイズ中の`JInternalFrame`を半透明に変更することも可能
- このサンプルではリサイズ中の半透明と合わせて`JDesktop#setDragMode(...)`でリサイズ中開始時に`JDesktopPane.OUTLINE_DRAG_MODE`、リサイズ終了時に`JDesktopPane.LIVE_DRAG_MODE`に切り替えている
-- [[JInternalFrameのリサイズ中に表示されるアウトラインを点線に変更する>Swing/OutlineDragStroke]]

* 参考リンク [#reference]
- [[JInternalFrameを半透明にする>Swing/TransparentFrame]]
- [[JInternalFrameのリサイズ中に表示されるアウトラインを点線に変更する>Swing/OutlineDragStroke]]

* コメント [#comment]
#comment
#comment