JTabbedPaneのタブタイトルを変更
Total: 13128
, Today: 1
, Yesterday: 3
Posted by aterai at
Last-modified:
概要
JTabbedPane
のタブタイトルを直接編集します。
Screenshot
Advertisement
サンプルコード
class EditableTabbedPane extends JTabbedPane {
private final JComponent glassPane = new EditorGlassPane();
private final JTextField editor = new JTextField();
private final Action startEditing = new AbstractAction() {
@Override public void actionPerformed(ActionEvent e) {
getRootPane().setGlassPane(glassPane);
Rectangle rect = getBoundsAt(getSelectedIndex());
Point p = SwingUtilities.convertPoint(
EditableTabbedPane.this, rect.getLocation(), glassPane);
// rect.setBounds(p.x + 2, p.y + 2, rect.width - 4, rect.height - 4);
rect.setLocation(p);
rect.grow(-2, -2);
editor.setBounds(rect);
editor.setText(getTitleAt(getSelectedIndex()));
editor.selectAll();
glassPane.add(editor);
glassPane.setVisible(true);
editor.requestFocusInWindow();
}
};
private final Action cancelEditing = new AbstractAction() {
@Override public void actionPerformed(ActionEvent e) {
glassPane.setVisible(false);
}
};
private final Action renameTab = new AbstractAction() {
@Override public void actionPerformed(ActionEvent e) {
if (!editor.getText().trim().isEmpty()) {
setTitleAt(getSelectedIndex(), editor.getText());
//java 1.6.0 ---->
Component c = getTabComponentAt(getSelectedIndex());
if (c instanceof JComponent) {
((JComponent) c).revalidate();
}
//<----
}
glassPane.setVisible(false);
}
};
protected EditableTabbedPane() {
super();
editor.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 3));
editor.getInputMap(JComponent.WHEN_FOCUSED).put(
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "rename-tab");
editor.getActionMap().put("rename-tab", renameTab);
editor.getInputMap(JComponent.WHEN_FOCUSED).put(
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "cancel-editing");
editor.getActionMap().put("cancel-editing", cancelEditing);
addMouseListener(new MouseAdapter() {
@Override public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
startEditing.actionPerformed(
new ActionEvent(e.getComponent(), ActionEvent.ACTION_PERFORMED, ""));
}
}
});
getInputMap(JComponent.WHEN_FOCUSED).put(
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "start-editing");
getActionMap().put("start-editing", startEditing);
}
private class EditorGlassPane extends JComponent {
protected EditorGlassPane() {
super();
setOpaque(false);
setFocusTraversalPolicy(new DefaultFocusTraversalPolicy() {
@Override public boolean accept(Component c) {
return Objects.equals(c, editor);
}
});
addMouseListener(new MouseAdapter() {
@Override public void mouseClicked(MouseEvent e) {
// if (Objects.nonNull(rect) && !rect.contains(e.getPoint())) {
if (!editor.getBounds().contains(e.getPoint())) {
renameTab.actionPerformed(
new ActionEvent(e.getComponent(), ActionEvent.ACTION_PERFORMED, ""));
}
}
});
}
@Override public void setVisible(boolean flag) {
super.setVisible(flag);
setFocusTraversalPolicyProvider(flag);
setFocusCycleRoot(flag);
}
}
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、JTabbedPane
のタブタイトルをExcel
などのように直接編集できるよう設定しています。
編集が開始されると対象となるタブ上にJTextField
をレイアウトしたGlassPane
を表示しています。このGlassPane
には編集中にフォーカス移動イベントが発生しないようにするためのFocusTraversalPolicy
などを追加しています。
- 操作方法
- マウスでタブをダブルクリック、またはタブを選択してEnterキーで編集開始
- 編集中に入力欄以外をクリック、またはEnterキーでタイトル文字列が確定
- 編集中はTabキーを押しても無視
- Escキーで編集をキャンセル
0
文字で確定した場合もキャンセル扱い
参考リンク
- Cursorを砂時計に変更
- JTabbedPaneのタブにJTextFieldを配置してタイトルを編集
JDK 6
で追加されたJTabbedPane#setTabComponentAt
メソッドで、タブにJTextField
を配置し、同様のことを行うサンプル
- Swing - Floating text field
JPopupMenu
にJTextField
を配置することで、同様のことを行うコードをKelVarnsonさんが投稿している