Swing/CustomDecoratedFrame のバックアップの現在との差分(No.1)
TITLE:JFrameのタイトルバーなどを独自のものにカスタマイズする
Posted by terai 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
#screenshot
サンプルコード
#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;
}
public void mousePressed(MouseEvent e) {
#spanadd
#spanend
@Override public void mousePressed(MouseEvent e) {
startSide = frame.getBounds();
}
public void mouseDragged(MouseEvent e) {
if(startSide==null) return;
#spanadd
#spanend
@Override public void mouseDragged(MouseEvent e) {
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などを参考にして、周辺にそれぞれ対応するリサイズカーソルを設定したJLabelを配置しています。- - JDK 1.7.0 の場合、JFrameの背景色を透明(frame.setBackground(new Color(0,0,0,0)))にし、ContentPaneの左右上の角をクリアして透明にしています。
解説
上記のサンプルではJFrame
の元のタイトルバーをsetUndecorated(true)
で非表示にし、マウスドラッグで移動可能にしたJPanel
を追加してタイトルバーの代わりにしています。
参考リンク
- Swing - Undecorated and resizable dialog
- マウスドラッグでのフレームのリサイズは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)
を使用してリサイズする方法もある
コメント
#spanend
#spanadd
// package example;
#spanend
#spanadd
#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にリサイズのための装飾を設定する