Swing/ComputeTitleWidth のバックアップ(No.2)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/ComputeTitleWidth へ行く。
- 1 (2018-02-15 (木) 14:23:42)
- 2 (2018-08-29 (水) 18:33:19)
- 3 (2019-05-22 (水) 19:35:38)
- 4 (2020-08-22 (土) 18:32:02)
- 5 (2022-01-25 (火) 22:40:46)
- category: swing folder: ComputeTitleWidth title: JInternalFrameのタイトル文字列幅を取得し、その値でJDesktopIconの幅を調整する tags: [JInternalFrame, JDesktopIcon, DesktopManager, NimbusLookAndFeel] author: aterai pubdate: 2017-08-21T16:35:32+09:00 description: JInternalFrameのタイトル文字列幅を取得し、その値をアイコン化した場合のJDesktopIconの幅として適用します。 image: https://drive.google.com/uc?id=1cfeEsnoOvSxcwzNqjqckcWIhkgDaGxzfRA
概要
JInternalFrame
のタイトル文字列幅を取得し、その値をアイコン化した場合のJDesktopIcon
の幅として適用します。
Screenshot
Advertisement
サンプルコード
JDesktopPane desktop = new JDesktopPane();
desktop.setDesktopManager(new DefaultDesktopManager() {
@Override public void iconifyFrame(JInternalFrame f) {
Rectangle r = this.getBoundsForIconOf(f);
r.width = f.getDesktopIcon().getPreferredSize().width;
f.getDesktopIcon().setBounds(r);
super.iconifyFrame(f);
}
});
desktop.add(createFrame("looooooooooooong title #", 1));
desktop.add(createFrame("#", 0));
//...
JInternalFrame f = new JInternalFrame(t + i, true, true, true, true);
f.setDesktopIcon(new JInternalFrame.JDesktopIcon(f) {
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
String title = f.getTitle();
Font font = getFont();
if (Objects.nonNull(font)) {
FontMetrics fm = getFontMetrics(font);
int titleW = SwingUtilities.computeStringWidth(fm, title);
// @see javax/swing/plaf/basic/BasicInternalFrameTitlePane.java
// Handler#minimumLayoutSize(Container)
// Calculate width.
int buttonsW = 22;
if (f.isClosable()) {
buttonsW += 19;
}
if (f.isMaximizable()) {
buttonsW += 19;
}
if (f.isIconifiable()) {
buttonsW += 19;
}
Insets i = getInsets();
// 2: Magic number of gap between icons
d.width = buttonsW + i.left + i.right + titleW + 2 + 2 + 2;
// 27: Magic number for NimbusLookAndFeel
d.height = Math.min(27, d.height);
System.out.println("BasicInternalFrameTitlePane: " + d.width);
}
return d;
}
// private void testWidth() {
// Dimension dim = getLayout().minimumLayoutSize(this);
// System.out.println("minimumLayoutSize: " + dim.width);
//
// int buttonsW = SwingUtils.stream(this)
// .filter(AbstractButton.class::isInstance)
// .mapToInt(c -> c.getPreferredSize().width)
// .sum();
// System.out.println("Total width of all buttons: " + buttonsW);
// }
});
View in GitHub: Java, Kotlin解説
JInternalFrame.JDesktopIcon#getPreferredSize()
メソッドをオーバーライドし、JInternalFrame
をアイコン化した場合の推奨サイズを変更- JInternalFrameをアイコン化した場合のサイズを変更する
JInternalFrame
のタイトル文字列を取得し、SwingUtilities.computeStringWidth(...)
で文字列幅を計算するJInternalFrame
ではSwingUtilities2.stringWidth(...)
メソッドなどで省略された場合などを考慮しているが、このサンプルでは無視する
ClosableButton
、MaximizableButton
、IconifiableButton
などの合計幅を計算するjavax/swing/plaf/basic/BasicInternalFrameTitlePane.java
のHandler#minimumLayoutSize(Container)
メソッドを参照して値を取得(22
+19
+19
+19
)JButton
を計算してgetPreferredSize().width
を合計しても値が異なる?
- 内余白を加算して推奨サイズを返す
super.getPreferredSize()
の値が初回とそれ以降で変化するため、このサンプルでは高さに固定値を使用
DefaultDesktopManager#iconifyFrame(JInternalFrame)
メソッドをオーバーライドして、JInternalFrame
をアイコン化した場合の実サイズを変更- 注:
- このサンプルは
NimbusLookAndFeel
のみ対応で、WindowsLookAndFeel
などには未対応
- このサンプルは
参考リンク
- JInternalFrameをアイコン化した場合のサイズを変更する
- JInternalFrame.JDesktopIcon (Java Platform SE 8)
- java - Set JInternalFrame minimised size - Stack Overflow