• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JTextFieldを編集不可のJTextPaneに追加する
#navi(../)
#tags(JTextPane, JTextField, JScrollPane, Focus)
RIGHT:Posted by &author(aterai); at 2013-02-11
*JTextFieldを編集不可のJTextPaneに追加する [#e24a9325]
``JTextField``を空欄として編集不可にした``JTextPane``に追加します。
---
category: swing
folder: TextFieldOnReadOnlyTextPane
title: JTextFieldを編集不可のJTextPaneに追加する
tags: [JTextPane, JTextField, JScrollPane, Focus]
author: aterai
pubdate: 2013-02-11T00:11:13+09:00
description: JTextFieldを空欄として編集不可にしたJTextPaneに追加します。
image: https://lh4.googleusercontent.com/-N1aQ1F9Zrn8/UReetdvfWQI/AAAAAAAABdc/9J_2lkAgW0Y/s800/TextFieldOnReadOnlyTextPane.png
---
* 概要 [#summary]
`JTextField`を空欄として編集不可にした`JTextPane`に追加します。

-&jnlp;
-&jar;
-&zip;
#download(https://lh4.googleusercontent.com/-N1aQ1F9Zrn8/UReetdvfWQI/AAAAAAAABdc/9J_2lkAgW0Y/s800/TextFieldOnReadOnlyTextPane.png)

//#screenshot
#ref(https://lh4.googleusercontent.com/-N1aQ1F9Zrn8/UReetdvfWQI/AAAAAAAABdc/9J_2lkAgW0Y/s800/TextFieldOnReadOnlyTextPane.png)

**サンプルコード [#y583333f]
* サンプルコード [#sourcecode]
#code(link){{
void insertQuestion(final JTextPane textPane, String str) {
private static void insertQuestion(JTextPane textPane, String str) {
  Document doc = textPane.getDocument();
  try{
  try {
    doc.insertString(doc.getLength(), str, null);
    final int pos = doc.getLength();

    int pos = doc.getLength();
    System.out.println(pos);
    final JTextField field = new JTextField(4) {
    JTextField field = new JTextField(4) {
      @Override public Dimension getMaximumSize() {
        return getPreferredSize();
      }
    };
    field.setBorder(BorderFactory.createMatteBorder(0,0,1,0,Color.BLACK));
    field.addFocusListener(new FocusListener() {
    field.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.BLACK));
    field.addFocusListener(new FocusAdapter() {
      @Override public void focusGained(FocusEvent e) {
        try{
        try {
          Rectangle rect = textPane.modelToView(pos);
          rect.grow(0, 4);
          rect.setSize(field.getSize());
          // System.out.println(rect);
          // System.out.println(field.getLocation());
          textPane.scrollRectToVisible(rect);
        }catch(BadLocationException ex) {
          ex.printStackTrace();
        } catch (BadLocationException ex) {
          // should never happen
          RuntimeException wrap = new StringIndexOutOfBoundsException(
              ex.offsetRequested());
          wrap.initCause(ex);
          throw wrap;
        }
      }
      @Override public void focusLost(FocusEvent e) {}
    });
    Dimension d = field.getPreferredSize();
    int baseline = field.getBaseline(d.width, d.height);
    field.setAlignmentY(baseline/(float)d.height);
    field.setAlignmentY(baseline / (float) d.height);

    SimpleAttributeSet a = new SimpleAttributeSet();
    // MutableAttributeSet a = new SimpleAttributeSet();
    MutableAttributeSet a = textPane.getStyle(StyleContext.DEFAULT_STYLE);
    StyleConstants.setLineSpacing(a, 1.5f);
    textPane.setParagraphAttributes(a, true);

    textPane.insertComponent(field);
    doc.insertString(doc.getLength(), "\n", null);
  }catch(BadLocationException e) {
    e.printStackTrace();
  } catch (BadLocationException ex) {
    // should never happen
    RuntimeException wrap = new StringIndexOutOfBoundsException(
        ex.offsetRequested());
    wrap.initCause(ex);
    throw wrap;
  }
}
}}

**解説 [#kcf658d9]
上記のサンプルでは、編集不可にした``JTextPane``内の文字列中に、編集可能な空欄として``JTextField``を追加(``JTextPane#insertComponent(...)``を使用)しています。
* 解説 [#explanation]
上記のサンプルでは、編集不可状態の`JTextPane`内の文字列中に編集可能な`JTextField`を`JTextPane#insertComponent(...)`メソッドを使用して追加しています。

- ``JTextPane``
- `JTextPane`
-- 編集不可に設定
-- 行間を``1.5``倍に設定
-- 行間を`1.5`倍に設定
--- [[JEditorPaneやJTextPaneに行間を設定する>Swing/LineSpacing]]
- ``JTextField``
-- ``JTextField#getMaximumSize()``をオーバーライドして幅を制限
-- ``JTextFieldにMatteBorder``を設定して下線のみ表示
-- ``JTextField#setAlignmentY(...)``でベースラインを揃える
- `JTextField`
-- `JTextField#getMaximumSize()`をオーバーライドして幅を制限
-- `JTextField`に`MatteBorder`を設定して下線のみの空欄を表示
-- `JTextField#setAlignmentY(...)`でベースラインを揃える
--- [[JTextPaneに追加するコンポーネントのベースラインを揃える>Swing/InsertComponentBaseline]]
-- ``JTextField``に``FocusListener``を追加し、``TAB``キーなどで``Focus``が移動したら、その``JTextField``までスクロールするように設定
-- `JTextField`に`FocusListener`を追加してKBD{Tab}キーなどで`Focus`が移動したら、その`JTextField`までスクロールするように設定
--- [[FocusTraversalPolicyを使用してフォーカスを取得したコンポーネントまでスクロールする>Swing/AutoScrollOnFocus]]

//**参考リンク
**コメント [#b8c6c78c]
* 参考リンク [#reference]
- [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/JTextPane.html#insertComponent-java.awt.Component- JTextPane#insertComponent(Component) (Java Platform SE 8)]

* コメント [#comment]
#comment
#comment