Swing/CustomDecoratedFrame のバックアップ(No.29)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/CustomDecoratedFrame へ行く。
- 1 (2010-01-18 (月) 11:27:29)
- 2 (2010-10-04 (月) 18:16:48)
- 3 (2011-05-28 (土) 01:34:14)
- 4 (2011-09-06 (火) 21:27:18)
- 5 (2012-05-10 (木) 15:45:16)
- 6 (2012-08-14 (火) 13:55:29)
- 7 (2012-08-14 (火) 15:56:47)
- 8 (2013-01-02 (水) 14:42:05)
- 9 (2013-08-02 (金) 20:50:48)
- 10 (2013-09-11 (水) 00:36:52)
- 11 (2014-06-30 (月) 03:04:08)
- 12 (2014-11-01 (土) 00:46:09)
- 13 (2014-11-07 (金) 03:10:40)
- 14 (2014-11-08 (土) 01:41:12)
- 15 (2014-11-25 (火) 03:03:31)
- 16 (2014-12-02 (火) 01:47:50)
- 17 (2015-04-01 (水) 20:09:18)
- 18 (2015-04-03 (金) 16:07:28)
- 19 (2016-05-26 (木) 14:38:56)
- 20 (2016-09-29 (木) 17:14:32)
- 21 (2017-03-28 (火) 15:05:45)
- 22 (2017-10-27 (金) 16:26:13)
- 23 (2017-11-02 (木) 15:34:40)
- 24 (2018-01-31 (水) 20:25:08)
- 25 (2018-02-24 (土) 19:51:30)
- 26 (2018-11-24 (土) 17:06:17)
- 27 (2020-11-07 (土) 01:58:08)
- 28 (2022-08-20 (土) 22:15:25)
- 29 (2022-10-22 (土) 22:51:58)
- 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
のタイトルバーなどを非表示にして独自に描画し、これに移動リサイズなどの機能も追加します。
Screenshot
Advertisement
サンプルコード
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);
}
}
View in GitHub: Java, Kotlin解説
上記のサンプルではJFrame
の元のタイトルバーをsetUndecorated(true)
で非表示にし、マウスドラッグで移動可能にしたJPanel
を追加してタイトルバーの代わりにしています。
- マウスドラッグでのフレームのリサイズはSwing - Undecorated and resizable dialogや
BasicInternalFrameUI.java
、MetalRootPaneUI#MouseInputHandler
などを参考にして、周辺にそれぞれ対応するリサイズカーソルを設定したJLabel
を配置して実行 JDK 1.7.0
の場合JFrame
の背景色を透明(frame.setBackground(new Color(0x0, true))
)、かつContentPane
の左右上の角をクリアして透明化- JRootPaneにリサイズのための装飾を設定するのように、
JRootPane#setWindowDecorationStyle(JRootPane.PLAIN_DIALOG)
を使用してリサイズする方法もある
// package example;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MainPanel {
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);
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;
}
public JComponent makeUI() {
return new JScrollPane(new JTree());
}
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;
}
public static void main(String[] args) {
EventQueue.invokeLater(MainPanel::createAndShowGUI);
}
public static void createAndShowGUI() {
JFrame frame = new JFrame();
frame.setUndecorated(true);
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);
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
Toolkit.getDefaultToolkit().beep();
}
frame.getContentPane().add(demo.makeUI());
frame.setSize(320, 240);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class DragWindowListener extends MouseAdapter {
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());
}
@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);
}
}
}
class CloseIcon implements Icon {
@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();
}
@Override public int getIconWidth() {
return 16;
}
@Override public int getIconHeight() {
return 16;
}
}
参考リンク
- Swing - Undecorated and resizable dialog
- JWindowをマウスで移動
- JInternalFrameをJFrameとして表示する
- JRootPaneにリサイズのための装飾を設定する