Swing/EditTabTitle のバックアップの現在との差分(No.4)
TITLE:JTabbedPaneのタブタイトルを変更
JTabbedPaneのタブタイトルを変更
編集者:Terai Atsuhiro~
作成日:2006-03-27
更新日:2023-02-22 (水) 11:06:41
- category: swing folder: EditTabTitle title: JTabbedPaneのタブタイトルを変更 tags: [JTabbedPane, GlassPane, JTextField] author: aterai pubdate: 2006-03-27T01:01:49+09:00 description: JTabbedPaneのタブタイトルを直接編集します。 image: hreflang:
href: https://java-swing-tips.blogspot.com/2008/09/double-click-on-each-tab-and-change-its.html lang: en
概要
JTabbedPane
のタブタイトルを直接編集します。
Screenshot
Advertisement
概要
JTabbedPaneのタブタイトルを直接編集します。サンプルコード
#spanend
#spanadd
class EditableTabbedPane extends JTabbedPane {
#spanend
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);
}
};
#spandel
#screenshot
#spanend
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);
#spandel
**サンプルコード [#o93646f5]
#spanend
class EditableTabbedPane extends JTabbedPane {
private final MyGlassPane panel = new MyGlassPane();
private final JTextField editor = new JTextField();
private final JFrame frame;
private final FocusTraversalPolicy policy;
private FocusTraversalPolicy ftp;
private Rectangle rect;
public EditableTabbedPane(JFrame _frame) {
this.frame = _frame;
(中略)
panel.add(editor);
frame.setGlassPane(panel);
panel.setVisible(false);
}
class MyGlassPane extends JPanel{
public MyGlassPane() {
super((LayoutManager)null);
setOpaque(false);
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
if(rect==null || rect.contains(me.getPoint())) return;
renameTab();
}
});
}
}
private void initEditor() {
rect = getUI().getTabBounds(this, getSelectedIndex());
rect.setRect(rect.x+2, rect.y+2, rect.width-2, rect.height-2);
editor.setBounds(rect);
editor.setText(getTitleAt(getSelectedIndex()));
}
private void startEditing() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
initEditor();
ftp = frame.getFocusTraversalPolicy();
panel.setVisible(true);
editor.requestFocusInWindow();
frame.setFocusTraversalPolicy(policy);
}
});
}
private void cancelEditing() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.setFocusTraversalPolicy(ftp);
panel.setVisible(false);
}
});
}
private void renameTab() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.setFocusTraversalPolicy(ftp);
if(editor.getText().trim().length()>0) {
setTitleAt(getSelectedIndex(), editor.getText());
}
panel.setVisible(false);
}
});
}
}
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);
}
-&jnlp;
-&jar;
-&zip;
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, ""));
}
}
});
}
#spandel
**解説 [#t11e99b7]
#spanend
#spandel
Excel風にJTabbedPaneのタブタイトルを直接編集しています。
#spanend
@Override public void setVisible(boolean flag) {
super.setVisible(flag);
setFocusTraversalPolicyProvider(flag);
setFocusCycleRoot(flag);
}
}
#spanadd
}
#spanend
#spanadd
View in GitHub: Java, Kotlin解説
上記のサンプルでは、JTabbedPane
のタブタイトルをExcel
などのように直接編集できるよう設定しています。
- 操作方法
- ダブルクリック、またはリターンで編集開始
- 入力欄以外をクリック、またはリターンで確定
- Escでキャンセル
- 0文字で確定するとキャンセル扱い
編集が開始されると対象となるタブ上に
JTextField
をレイアウトしたGlassPane
を表示しています。このGlassPane
には編集中にフォーカス移動イベントが発生しないようにするためのFocusTraversalPolicy
などを追加しています。
参考リンク
- Cursorを砂時計に変更
- 操作方法
- マウスでタブをダブルクリック、またはタブを選択してEnterキーで編集開始
- 編集中に入力欄以外をクリック、またはEnterキーでタイトル文字列が確定
- 編集中はTabキーを押しても無視
- Escキーで編集をキャンセル
-
0
文字で確定した場合もキャンセル扱い
コメント
参考リンク
- Cursorを砂時計に変更
- JTabbedPaneのタブにJTextFieldを配置してタイトルを編集
-
JDK 6
で追加されたJTabbedPane#setTabComponentAt
メソッドで、タブにJTextField
を配置し、同様のことを行うサンプル
-
- Swing - Floating text field
-
JPopupMenu
にJTextField
を配置することで、同様のことを行うコードをKelVarnsonさんが投稿している
-