Swing/FileChooserBottomAccessory のバックアップソース(No.1)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- バックアップ を表示
- Swing/FileChooserBottomAccessory へ行く。
--- category: swing folder: FileChooserBottomAccessory title: MetalLookAndFeelでJFileChooserの下部にコンポーネントを追加する tags: [JFileChooser, MetalLookAndFeel] author: aterai pubdate: 2017-08-14T15:32:42+09:00 description: MetalLookAndFeelを適用しているJFileChooserのファイルフィルタとボタンパネルの間にJComboBoxのような横長のコンポーネントを追加します。 image: https://drive.google.com/uc?export=view&id=1Nyb4wo_ryaaCsJEgpGBxbIlYazx3FQVFfw --- * 概要 [#summary] `MetalLookAndFeel`を適用している`JFileChooser`のファイルフィルタとボタンパネルの間に`JComboBox`のような横長のコンポーネントを追加します。 #download(https://drive.google.com/uc?export=view&id=1Nyb4wo_ryaaCsJEgpGBxbIlYazx3FQVFfw) * サンプルコード [#sourcecode] #code(link){{ class EncodingFileChooserUI extends MetalFileChooserUI { public final JComboBox<String> combo = new JComboBox<>( new String[] {"UTF-8", "UTF-16", "Shift_JIS", "EUC-JP"}); protected EncodingFileChooserUI(JFileChooser filechooser) { super(filechooser); } @Override public void installComponents(JFileChooser fc) { super.installComponents(fc); JPanel bottomPanel = getBottomPanel(); JLabel label = new JLabel("Encoding:") { @Override public Dimension getPreferredSize() { return SwingUtils.stream(bottomPanel) .filter(JLabel.class::isInstance).map(JLabel.class::cast) .findFirst() .map(JLabel::getPreferredSize) .orElse(super.getPreferredSize()); } }; label.setDisplayedMnemonic('E'); label.setLabelFor(combo); JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS)); panel.add(label); panel.add(combo); // 0: fileNamePanel // 1: RigidArea // 2: filesOfTypePanel bottomPanel.add(Box.createRigidArea(new Dimension(1, 5)), 3); bottomPanel.add(panel, 4); SwingUtils.stream(bottomPanel) .filter(JLabel.class::isInstance).map(JLabel.class::cast) .forEach(l -> { l.setHorizontalAlignment(SwingConstants.RIGHT); l.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); }); } } }} * 解説 [#explanation] - `JFileChooser#setAccessory(JComponent)`を使用すると`JFileChooser`の右側にコンポーネントが追加されるので、横長のコンポーネントを追加すると`JFileChooser`全体の幅が広がってしまう -- [[JFileChooserに画像プレビューを追加>Swing/PreviewAccessory]] - `BasicFileChooserUI#getBottomPanel()`メソッドでファイル名入力欄、ファイルフィルタ、ボタンなどを格納している下部パネルを取得し、「ファイルのタイプ(`T`)」パネルとボタンパネルの間に、`JComboBox`のような横長のコンポーネントを設定した別パネルを追加 -- `MetalFileChooserUI`の場合、`2`番目の`filesOfTypePanel`の後に`bottomPanel.add(Box.createRigidArea(vstrut5), 3); bottomPanel.add(encodingPanel, 4)`で追加 --- [https://docs.oracle.com/javase/jp/8/docs/api/java/awt/Container.html#add-java.awt.Component-int- Container#add(Component, int) (Java Platform SE 8)] -- `BasicFileChooserUI#getBottomPanel()`で取得できる`JPanel`内のレイアウトは、`LookAndFeel`ごとに大きく異なるため同じ方法は使用できない --- 例えば`WindowsLookAndFeel`では`BoxLayout.LINE_AXIS`、`MetalLookAndFeel`では`BoxLayout.Y_AXIS` -- `MetalFileChooserUI`では、`JLabel`を継承する`AlignedLabel`で最も長い文字列幅から推奨サイズを揃えているが、`private`のため、このサンプルでは使用できない --- もし`Encoding:`が、この最も長い文字列幅より長い場合は末尾が省略されてしまう * 参考リンク [#reference] - [[JFileChooserに画像プレビューを追加>Swing/PreviewAccessory]] - [https://docs.oracle.com/javase/jp/8/docs/api/java/awt/Container.html#add-java.awt.Component-int- Container#add(Component, int) (Java Platform SE 8)] * コメント [#comment] #comment #comment