• category: swing folder: DragInternalFrameTranslucency title: JInternalFrameがマウスドラッグで移動中はそのフレームを半透明に変更する tags: [JInternalFrame, JDesktopPane, DesktopManager] author: aterai pubdate: 2022-01-17T05:20:08+09:00 description: image: https://drive.google.com/uc?id=190_fQzLU52FgANH4SrQqL-psTVSgQ0RS

概要

サンプルコード

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(...)をオーバーライドして自身がドラッグ中の場合は半透明で描画する
    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に切り替えてリサイズ中は完全透明にしている

参考リンク

コメント