---
category: swing
folder: OutlineDragStroke
title: JInternalFrameのリサイズ中に表示されるアウトラインを点線に変更する
tags: [JInternalFrame, DesktopManager, JDesktopPane, JLayer]
author: aterai
pubdate: 2022-01-31T01:00:12+09:00
description: JInternalFrameのリサイズ中に表示されるアウトラインを色反転の直線から点線に変更してJLayer上に描画します。
image: https://drive.google.com/uc?id=1Y3cl7vxAZV2wJi_LJTA_1ove7_kicMum
---
* 概要 [#summary]
`JInternalFrame`のリサイズ中に表示されるアウトラインを色反転の直線から点線に変更して`JLayer`上に描画します。

#download(https://drive.google.com/uc?id=1Y3cl7vxAZV2wJi_LJTA_1ove7_kicMum)

* サンプルコード [#sourcecode]
#code(link){{
Rectangle rubberBand = new Rectangle();
JDesktopPane desktop = new JDesktopPane();
desktop.setDesktopManager(new DefaultDesktopManager() {
  @Override public void beginResizingFrame(JComponent f, int direction) {
    desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
    super.beginResizingFrame(f, direction);
  }

  @Override public void resizeFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) {
    if (desktop.getDragMode() == JDesktopPane.OUTLINE_DRAG_MODE) {
      super.resizeFrame(f, newX, newY, 0, 0);
      rubberBand.setBounds(newX, newY, newWidth, newHeight);
      desktop.repaint();
    } else {
      super.resizeFrame(f, newX, newY, newWidth, newHeight);
    }
  }

  @Override public void endResizingFrame(JComponent f) {
    desktop.setDragMode(JDesktopPane.LIVE_DRAG_MODE);
    if (!rubberBand.isEmpty()) {
      super.resizeFrame(f, rubberBand.x, rubberBand.y, rubberBand.width, rubberBand.height);
      rubberBand.setBounds(0, 0, 0, 0);
    }
    super.endResizingFrame(f);
  }
});
add(new JLayer<>(desktop, new LayerUI<JDesktopPane>() {
  @Override public void paint(Graphics g, JComponent c) {
    super.paint(g, c);
    if (c instanceof JLayer) {
      JDesktopPane desktop = (JDesktopPane) ((JLayer<?>) c).getView();
      if (desktop.getDragMode() == JDesktopPane.OUTLINE_DRAG_MODE) {
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setPaint(Color.GRAY);
        g2.setStroke(makeDotStroke());
        g2.draw(rubberBand);
        g2.dispose();
      }
    }
  }
}));
}}

* 解説 [#explanation]
- `DefaultDesktopManager#beginResizingFrame(...)`をオーバーライドして`JInternalFrame`のリサイズが開始されたらドラッグスタイルを`JDesktopPane.OUTLINE_DRAG_MODE`に変更
- `DefaultDesktopManager#resizeFrame(...)`をオーバーライドしてデフォルトのリサイズアウトラインを幅高さ`0`に変更して非表示化
-- 別途`JLayer`でアウトラインを描画するため、アウトラインの位置とサイズを`Rectangle`に記憶して`JDesktopPane#repaint()`を実行
-- `LayerUI#paint(...)`をオーバーライドして点線で上記の`Rectangle`を描画
-- `DefaultDesktopManager#resizeFrame(...)`内でアウトラインは描画されているので`JLayer`を使用せずにここで描画も実行したいが、`Graphics g = JComponent.safelyGetGraphics(desktopPane)`などのメソッドがパッケージプライベートなので使用できない
- `DefaultDesktopManager#beginResizingFrame(...)`をオーバーライドしてドラッグスタイルを`JDesktopPane.LIVE_DRAG_MODE`に戻す
-- 記憶した`Rectangle`に`JInternalFrame`をリサイズするため最後に一回`super.resizeFrame(f, rubberBand.x, rubberBand.y, rubberBand.width, rubberBand.height)`を実行する必要がある

* 参考リンク [#reference]
- [[JInternalFrameがマウスドラッグで移動中はそのフレームを半透明に変更する>Swing/DragInternalFrameTranslucency]]

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