Swing/CustomDecoratedFrame のバックアップの現在との差分(No.5)
TITLE:JFrameのタイトルバーなどの装飾を独自のものにカスタマイズする
Posted by aterai at 2010-01-18
JFrameのタイトルバーなどの装飾を独自のものにカスタマイズする
JFrameのタイトルバーなどを非表示にして独自に描画し、これに移動リサイズなどの機能も追加します。-
category: swing
folder: CustomDecoratedFrame
title: JFrameのタイトルバーなどの装飾を独自のものにカスタマイズする
tags: [JFrame, MouseListener, MouseMotionListener, JPanel, JLabel, ContentPane, Transparent]
author: aterai
pubdate: 2010-01-18T11:27:29+09:00
description: JFrameのタイトルバーなどを非表示にして独自に描画し、これに移動リサイズなどの機能も追加します。
image:
hreflang:
href: https://java-swing-tips.blogspot.com/2010/05/custom-decorated-titlebar-jframe.html lang: en
概要
JFrame
のタイトルバーなどを非表示にして独自に描画し、これに移動リサイズなどの機能も追加します。
- &jnlp;
- &jar;
- &zip;
Screenshot
Advertisement
サンプルコード
#spanend
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
class ResizeWindowListener extends MouseAdapter {
private Rectangle startSide = null;
private final JFrame frame;
public ResizeWindowListener(JFrame frame) {
this.frame = frame;
}
#spanadd
#spanend
@Override public void mousePressed(MouseEvent e) {
startSide = frame.getBounds();
}
#spanadd
#spanend
@Override public void mouseDragged(MouseEvent e) {
if(startSide==null) return;
if (startSide == null) return;
Component c = e.getComponent();
if(c==topleft) {
if (c == topleft) {
startSide.y += e.getY();
startSide.height -= e.getY();
startSide.x += e.getX();
startSide.width -= e.getX();
}else if(c==top) {
} else if (c == top) {
startSide.y += e.getY();
startSide.height -= e.getY();
}else if(c==topright) {
} else if (c == topright) {
startSide.y += e.getY();
startSide.height -= e.getY();
startSide.width += e.getX();
}else if(c==left) {
} else if (c == left) {
startSide.x += e.getX();
startSide.width -= e.getX();
}else if(c==right) {
} else if (c == right) {
startSide.width += e.getX();
}else if(c==bottomleft) {
} else if (c == bottomleft) {
startSide.height += e.getY();
startSide.x += e.getX();
startSide.width -= e.getX();
}else if(c==bottom) {
} else if (c == bottom) {
startSide.height += e.getY();
}else if(c==bottomright) {
} else if (c == bottomright) {
startSide.height += e.getY();
startSide.width += e.getX();
}
frame.setBounds(startSide);
}
}
解説
上記のサンプルではタイトルバーを、setUndecorated(true)で非表示にし、移動可能にしたJPanelを追加してタイトルバーにしています。 リサイズは、Swing - Undecorated and resizable dialogやBasicInternalFrameUI.java、MetalRootPaneUI#MouseInputHandlerなどを参考にして、周辺にそれぞれ対応するリサイズカーソルを設定したJLabelを配置しています。- - JDK 1.7.0 の場合、JFrameの背景色を透明(frame.setBackground(new Color(0,0,0,0)))にし、ContentPaneの左右上の角をクリアして透明にしています。
解説
上記のサンプルではJFrame
の元のタイトルバーをsetUndecorated(true)
で非表示にし、マウスドラッグで移動可能にしたJPanel
を追加してタイトルバーの代わりにしています。
参考リンク
- Swing - Undecorated and resizable dialog
- JWindowをマウスで移動
- JInternalFrameをJFrameとして表示する
- マウスドラッグでのフレームのリサイズはSwing - Undecorated and resizable dialogや
BasicInternalFrameUI.java
、MetalRootPaneUI#MouseInputHandler
などを参考にして、周辺にそれぞれ対応するリサイズカーソルを設定したJLabel
を配置して実行 -
JDK 1.7.0
の場合JFrame#setBackground(new Color(0x0, true))
でJFrame
の背景色を透明化、かつContentPane
の左右上の角をクリアして透明化 - JRootPaneにリサイズのための装飾を設定するのように
JRootPane#setWindowDecorationStyle(JRootPane.PLAIN_DIALOG)
を使用してリサイズする方法もある
コメント
- blogspotで、指摘されていたように、このサンプルを1.6.0_xx+WebStartで実行すると、画面の外にフレームをドラッグすることが出来なかったのですが、JREのバージョンを 1.7.0 にすると、WebStartで起動しても画面外に移動可能になっているみたいです。もしかしてデュアルディスプレイでも移動できるようになっているのかも?(確認してないですが...) -- aterai
#spanend #spanadd // package example; #spanend #spanadd import java.awt.*; #spanend #spanadd import java.awt.event.*; #spanend #spanadd import javax.swing.*; #spanend #spanadd #spanend #spanadd public class MainPanel { #spanend private static final Color BG_COLOR = Color.ORANGE; public JComponent makeTitleBar() { JLabel label = new JLabel("Title", SwingConstants.CENTER); label.setOpaque(true); label.setForeground(Color.WHITE); label.setBackground(BG_COLOR); DragWindowListener dwl = new DragWindowListener(); label.addMouseListener(dwl); label.addMouseMotionListener(dwl); #spanadd #spanend JPanel title = new JPanel(new BorderLayout()); title.setBorder(BorderFactory.createMatteBorder(0, 2, 2, 2, BG_COLOR)); title.add(label); title.add(makeCloseButton(), BorderLayout.EAST); return title; } #spanadd #spanend public JComponent makeUI() { return new JScrollPane(new JTree()); } #spanadd #spanend private static JButton makeCloseButton() { JButton button = new JButton(new CloseIcon()); button.setContentAreaFilled(false); button.setFocusPainted(false); button.setBorder(BorderFactory.createEmptyBorder()); button.setOpaque(true); button.setBackground(BG_COLOR); button.addActionListener(e -> { JComponent b = (JComponent) e.getSource(); Container c = b.getTopLevelAncestor(); if (c instanceof Window) { Window w = (Window) c; w.dispatchEvent(new WindowEvent(w, WindowEvent.WINDOW_CLOSING)); } }); return button; } #spanadd #spanend public static void main(String[] args) { EventQueue.invokeLater(MainPanel::createAndShowGUI); } #spanadd #spanend public static void createAndShowGUI() { JFrame frame = new JFrame(); frame.setUndecorated(true); #spanadd #spanend MainPanel demo = new MainPanel(); JRootPane root = frame.getRootPane(); root.setWindowDecorationStyle(JRootPane.PLAIN_DIALOG); root.setBorder(BorderFactory.createMatteBorder(2, 4, 4, 4, BG_COLOR)); JLayeredPane layeredPane = root.getLayeredPane(); Component c = layeredPane.getComponent(1); if (c instanceof JComponent) { JComponent orgTitlePane = (JComponent) c; orgTitlePane.removeAll(); orgTitlePane.setLayout(new BorderLayout()); orgTitlePane.add(demo.makeTitleBar()); } frame.setMinimumSize(new Dimension(300, 120)); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); #spanadd #spanend try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); Toolkit.getDefaultToolkit().beep(); } #spanadd #spanend frame.getContentPane().add(demo.makeUI()); frame.setSize(320, 240); frame.setLocationRelativeTo(null); frame.setVisible(true); } #spanadd } #spanend #spanadd #spanend #spanadd class DragWindowListener extends MouseAdapter { #spanend private final Point startPt = new Point(); private Window window; @Override public void mousePressed(MouseEvent me) { if (window == null) { Object o = me.getSource(); if (o instanceof Window) { window = (Window) o; } else if (o instanceof JComponent) { window = SwingUtilities.windowForComponent(me.getComponent()); } } startPt.setLocation(me.getPoint()); } #spanadd #spanend @Override public void mouseDragged(MouseEvent me) { if (window != null) { Point pt = new Point(); pt = window.getLocation(pt); int x = pt.x - startPt.x + me.getX(); int y = pt.y - startPt.y + me.getY(); window.setLocation(x, y); } } #spanadd } #spanend #spanadd #spanend #spanadd class CloseIcon implements Icon { #spanend @Override public void paintIcon(Component c, Graphics g, int x, int y) { Graphics2D g2 = (Graphics2D) g.create(); g2.translate(x, y); g2.setPaint(Color.WHITE); g2.drawLine(4, 4, 11, 11); g2.drawLine(4, 5, 10, 11); g2.drawLine(5, 4, 11, 10); g2.drawLine(11, 4, 4, 11); g2.drawLine(11, 5, 5, 11); g2.drawLine(10, 4, 4, 10); g2.dispose(); } #spanadd #spanend @Override public int getIconWidth() { return 16; } #spanadd #spanend @Override public int getIconHeight() { return 16; } #spanadd } #spanend #spanadd
参考リンク
- Swing - Undecorated and resizable dialog
- JWindowをマウスで移動
- JInternalFrameをJFrameとして表示する
- JRootPaneにリサイズのための装飾を設定する