• category: swing folder: MaxWidthWrapOptionPane title: JOptionPaneに配置するJTextAreaの最大幅を指定してサイズ調整を行う tags: [JTextArea, JOptionPane, JScrollPane] author: aterai pubdate: 2016-04-04T00:35:06+09:00 description: JOptionPaneに配置するJTextAreaの最大幅を指定し、テキストが複数行になってもその幅を超えず、スクロールバーも表示されない高さまで拡張されるよう設定します。 image: https://lh3.googleusercontent.com/-wvgqUKEkJe8/VwE0eREDhVI/AAAAAAAAOSM/aEgf3UtLBX0g-u9CKBFg_8nCbt7-0CLngCCo/s800-Ic42/MaxWidthWrapOptionPane.png

概要

JOptionPaneに配置するJTextAreaの最大幅を指定し、テキストが複数行になってもその幅を超えず、スクロールバーも表示されない高さまで拡張されるよう設定します。

サンプルコード

private final JTextArea textArea = new JTextArea(1, 1) {
  @Override public void updateUI() {
    super.updateUI();
    setLineWrap(true);
    setWrapStyleWord(true);
    setEditable(false);
    setOpaque(false);
    //setBorder(BorderFactory.createLineBorder(Color.RED));
    setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
  }
  @Override public void setText(String t) {
    super.setText(t);
    try {
      setColumns(50);
      // https://docs.oracle.com/javase/8/docs/api/javax/swing/text/JTextComponent.html#modelToView-int-
      // i.e. layout cannot be computed until the component has been sized.
      // The component does not have to be visible or painted.
      setSize(super.getPreferredSize()); //setSize: looks like ugly hack...
      System.out.println(super.getPreferredSize());

      Rectangle r = modelToView(t.length());
      int rc = (int)(.5 + (r.y + r.height) / (float) getRowHeight());
      setRows(rc);
      System.out.format("Rows: %d%n", rc);
      System.out.println(super.getPreferredSize());
      if (rc == 1) {
        setSize(getPreferredSize());
        setColumns(1);
      }
    } catch (BadLocationException ex) {
      ex.printStackTrace();
    }
  }
};
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、JTextArea#setText(...)メソッドをオーバーライドして最大幅を固定したJTextAreaを作成し、これをJOptionPane#showMessageDialog(...)で表示しています。

  • 文字列がJTextArea#setColumns(50)で指定した最大幅を超えて複数行になる場合は、スクロールバーが表示されないようにJTextArea#setSize(super.getPreferredSize())JTextAreaの高さを調整
  • 文字列が一行以内になる場合は、JTextArea#setColumns(1)で幅を上書きして、文字列の幅がそのサイズになるよう設定
  • NimbusLookAndFeelMotifLookAndFeelで一行分のJTextAreaの幅設定ができない?
    • JTextAreaの内余白が影響している?
  • JTextArea#setText(...)時点でのサイズを設定し、ダイアログのリサイズは考慮しない

参考リンク

コメント