• 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

概要

JInternalFrameがマウスドラッグで移動中の場合はそのフレームを半透明に変更して背景が確認できるよう設定します。

サンプルコード

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);
  }
});
View in GitHub: Java, Kotlin

解説

  • DesktopManager#beginDraggingFrame(...)をオーバーライドしてマウスでドラッグ中のJInternalFrameを記憶
    • DefaultDesktopManagerではJInternalFrame#isDraggingを切り替えているが、このフィールドはパッケージプライベートなのでこのサンプルでは使用できない
  • JInternalFrame#paintComponent(...)をオーバーライドして自身がドラッグ中の場合は半透明で描画する
    • 半透明化することでJDesktop#setDragMode(JDesktopPane.OUTLINE_DRAG_MODE)のアウトラインモードにしなくても移動中の背景が確認しやすくなる
      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に切り替えている

参考リンク

コメント