MetalLookAndFeelでJFileChooserの下部にコンポーネントを追加する
Total: 4041, Today: 2, Yesterday: 2
Posted by aterai at
Last-modified:
Summary
MetalLookAndFeelを適用しているJFileChooserのファイルフィルタとボタンパネルの間にJComboBoxのような横長のコンポーネントを追加します。
Screenshot

Advertisement
Source Code Examples
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));
});
}
}
View in GitHub: Java, KotlinDescription
JFileChooser#setAccessory(JComponent)を使用するとJFileChooserの右側にコンポーネントが追加されるので、横長のコンポーネントを追加するとJFileChooser全体の幅が広がってしまうBasicFileChooserUI#getBottomPanel()メソッドでファイル名入力欄、ファイルフィルタ、ボタンなどを格納している下部パネルを取得し、「ファイルのタイプ(T)」パネルとボタンパネルの間にJComboBoxのような横長のコンポーネントを設定した別パネルを追加MetalFileChooserUIの場合、2番目のfilesOfTypePanelの直後になるようbottomPanel.add(Box.createRigidArea(vstrut5), 3); bottomPanel.add(encodingPanel, 4)で追加BasicFileChooserUI#getBottomPanel()で取得できるJPanel内のレイアウトはLookAndFeelごとに大きく異なるため同じ方法は使用できない- 例えば
WindowsLookAndFeelではBoxLayout.LINE_AXIS、MetalLookAndFeelではBoxLayout.Y_AXIS
- 例えば
MetalFileChooserUIではJLabelを継承するAlignedLabelで最も長い文字列幅から推奨サイズを揃えているが、privateのためこのサンプルでは使用できない- Containerの子Componentを再帰的にすべて取得するでラベルを検索して推奨サイズを取得しているが、もし
Encoding:がこの最も長い文字列幅より長い場合は末尾が省略されてしまう
- Containerの子Componentを再帰的にすべて取得するでラベルを検索して推奨サイズを取得しているが、もし
JFileChooser#updateUI()メソッドをオーバーライドしてsuper.updateUI(); setUI(new EncodingFileChooserUI(this));などを実行した場合、AcceptAllファイルフィルタが重複追加されてしまうsetUI(...)の後でJFileChooser#resetChoosableFileFilters()を実行するか、super.updateUI()を実行しないことで回避可能- 個別のファイルフィルタ追加などの設定は
JFileChooser#updateUI()メソッド内で実施する
- 個別のファイルフィルタ追加などの設定は
Reference
- JFileChooserに画像プレビューを追加
- Containerの子Componentを再帰的にすべて取得する
- Container#add(Component, int) (Java Platform SE 8)