• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JFrameのタイトルバーなどの装飾を独自のものにカスタマイズする
#navi(../)
RIGHT:Posted by [[aterai]] at 2010-01-18
RIGHT:Posted by &author(aterai); at 2010-01-18
*JFrameのタイトルバーなどの装飾を独自のものにカスタマイズする [#wc20d97b]
JFrameのタイトルバーなどを非表示にして独自に描画し、これに移動リサイズなどの機能も追加します。

-&jnlp;
-&jar;
-&zip;

//#screenshot
#ref(http://lh3.ggpht.com/_9Z4BYR88imo/TQTKV1P7mYI/AAAAAAAAAV0/u4qjd-ItBYU/s800/CustomDecoratedFrame.png)

**サンプルコード [#da76e44b]
#code{{
class ResizeWindowListener extends MouseAdapter {
  private Rectangle startSide = null;
  private final JFrame frame;
  public ResizeWindowListener(JFrame frame) {
    this.frame = frame;
  }
  @Override public void mousePressed(MouseEvent e) {
    startSide = frame.getBounds();
  }
  @Override public void mouseDragged(MouseEvent e) {
    if(startSide==null) return;
    Component c = e.getComponent();
    if(c==topleft) {
      startSide.y += e.getY();
      startSide.height -= e.getY();
      startSide.x += e.getX();
      startSide.width -= e.getX();
    }else if(c==top) {
      startSide.y += e.getY();
      startSide.height -= e.getY();
    }else if(c==topright) {
      startSide.y += e.getY();
      startSide.height -= e.getY();
      startSide.width += e.getX();
    }else if(c==left) {
      startSide.x += e.getX();
      startSide.width -= e.getX();
    }else if(c==right) {
      startSide.width += e.getX();
    }else if(c==bottomleft) {
      startSide.height += e.getY();
      startSide.x += e.getX();
      startSide.width -= e.getX();
    }else if(c==bottom) {
      startSide.height += e.getY();
    }else if(c==bottomright) {
      startSide.height += e.getY();
      startSide.width += e.getX();
    }
    frame.setBounds(startSide);
  }
}
}}

**解説 [#dd2ca04c]
上記のサンプルではタイトルバーを、setUndecorated(true)で非表示にし、移動可能にしたJPanelを追加してタイトルバーにしています。
リサイズは、[http://forums.sun.com/thread.jspa?threadID=5254456 Swing - Undecorated and resizable dialog]やBasicInternalFrameUI.java、MetalRootPaneUI#MouseInputHandlerなどを参考にして、周辺にそれぞれ対応するリサイズカーソルを設定したJLabelを配置しています。
----
JDK 1.7.0 の場合、JFrameの背景色を透明(frame.setBackground(new Color(0,0,0,0)))にし、ContentPaneの左右上の角をクリアして透明にしています。

**参考リンク [#p98cd47e]
-[http://forums.sun.com/thread.jspa?threadID=5254456 Swing - Undecorated and resizable dialog]
-[[JWindowをマウスで移動>Swing/DragWindow]]
-[[JInternalFrameをJFrameとして表示する>Swing/InternalFrameTitleBar]]

**コメント [#nc60542a]
- [http://java-swing-tips.blogspot.com/2010/05/custom-decorated-titlebar-jframe.html blogspot]で、指摘されていたように、このサンプルを1.6.0_xx+WebStartで実行すると、画面の外にフレームをドラッグすることが出来なかったのですが、JREのバージョンを 1.7.0 にすると、WebStartで起動しても画面外に移動可能になっているみたいです。もしかしてデュアルディスプレイでも移動できるようになっているのかも?(確認してないですが...) -- [[aterai]] &new{2011-09-06 (火) 21:27:18};

#comment