• category: swing folder: OutlineDragStroke title: JInternalFrameのリサイズ中に表示されるアウトラインを点線に変更する tags: [JInternalFrame, DesktopManager, JDesktopPane, JLayer] author: aterai pubdate: 2022-01-31T00:56:17+09:00 description: JInternalFrameのリサイズ中に表示されるアウトラインを点線に変更する image: https://drive.google.com/uc?id=1Y3cl7vxAZV2wJi_LJTA_1ove7_kicMum

概要

JInternalFrameのリサイズ中に表示されるアウトラインを点線に変更する

サンプルコード

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

解説

  • DefaultDesktopManager#beginResizingFrame(...)をオーバーライドしてJInternalFrameのリサイズが開始されたらドラッグスタイルをJDesktopPane.OUTLINE_DRAG_MODEに変更
  • DefaultDesktopManager#resizeFrame(...)をオーバーライドしてデフォルトのリサイズアウトラインを幅高さ0に変更して非表示化
    • 別途JLayerでアウトラインを描画するため、アウトラインの位置とサイズをRectangleに記憶してJDesktopPane#repaint()を実行
    • LayerUI#paint(...)をオーバーライドして点線で上記のRectangleを描画
  • DefaultDesktopManager#beginResizingFrame(...)をオーバーライドしてドラッグスタイルをJDesktopPane.LIVE_DRAG_MODEに戻す
    • 記憶したRectangleJInternalFrameをリサイズするため最後に一回super.resizeFrame(f, rubberBand.x, rubberBand.y, rubberBand.width, rubberBand.height)を実行する必要がある

参考リンク

コメント