質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.04%

JTableの文字のフォントやサイズを変更したい

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 6,394

score 67

いつもありがとうございます。
現在、JavaでGUIのメモ帳作りをしています。
ユーザーが指定(ドラッグ)した範囲の文字を変更できるようにしたいです。
入力された文字のフォントやサイズ、色などを変更するツールバーのようなもの(Wordのツールバーの簡易的なイメージです)を設置したいと考えているのですがなかなかうまくいきません。

というのも、おそらく私が作ろうとしているメモ帳は少し特殊で、テキスト入力を受ける付けるコンポーネントがJTextPaneクラスではなくJTableクラスのインスタンスだからだと思いました。
*メモ帳の仕様上、複数行・列にしたいため、JTextPaneではなく、JTableを使っています。

自力で調べた結果、JTextPaneの場合は親子関係にあるためJTextComponentのメソッドを使えばできることがわかったのですが、
JTableクラスからだと、JTextComponentのメソッドを呼び出せず・・・というところで立ち止まってしまいました。

JTableの文字のフォントやサイズを変更できるようにするにはどのようにすれば良いでしょうか?
JTextComponentに用意されているようなツールバーを作れるようなクラスはあるのでしょうか?

よろしくお願いします。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

JTable.setFontメソッドで変更できます。
ただし、セルの高さは自動で変わってくれないので合わせて変更する必要があります。


(追記)

セルに属性を持たせるのではなく、独自のCellRendererを作ってそこで制御するようにします。
下記の例では、特定のセルだけ、2行目の左から2列目だけ(つまり"d"だけ)フォントを変えています。

ご質問のようなことをするには、MyCellRendererクラスに2次元配列を用意して、そこにフォントなどの情報を持たせるようにすればできると思います。

import java.awt.Component;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

public final class App extends JFrame {

    private JTable table;

    public App() {
        setTitle("App");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        table = new JTable(new Object[][] {
            new Object[] { "a", "b" }, new Object[] { "c", "d" } },
            new Object[] { "col1", "col2" });
        table.setDefaultRenderer(Object.class, new MyCellRenderer());
        add(table);
    }

    static class MyCellRenderer extends DefaultTableCellRenderer {

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                                                       boolean hasFocus, int row, int column) {
            if (row == 1 && column == 1) {
                JLabel label = new JLabel(String.valueOf(value));
                label.setFont(new Font("monospace", Font.BOLD, 16));
                // 良くないやりかた:追記2を参照
                return label;
            }
            return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        }

    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                App app = new App();
                app.setSize(600, 200);
                app.setLocationRelativeTo(null);
                app.setVisible(true);
            }
        });
    }

}


(追記2)

JLabelをそのまま返すと選択状態が描画できなくなってしまうので、ダメでした。すみません。
super.getTableCellRendererComponentのコンポーネントに直接フォント変更で行けるはずです。
選択したセルをBOLDにするMyCellRendererを書いてみましたので、参考にしてください。

    static class MyCellRenderer extends DefaultTableCellRenderer {

        JTable table;
        Map<Point, Font> cellRendererMap;

        public MyCellRenderer(JTable table) {
            this.table = table;
            this.cellRendererMap =new HashMap<>();
        }

        void applyBoldToSelectedCells() {
            Font baseFont = table.getFont();
            int[] cols = table.getSelectedColumns();
            int[] rows = table.getSelectedRows();
            for (int row : rows) {
                for (int col : cols) {
                    Point k = new Point(col, row);
                    Font v = baseFont.deriveFont(Font.BOLD);
                    cellRendererMap.put(k, v);
                }
            }
            table.updateUI();
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                                                       boolean hasFocus, int row, int column) {
            Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            Point key = new Point(column, row);
            if (cellRendererMap.containsKey(key)) {
                Font font = cellRendererMap.get(key);
                c.setFont(font);
            }
            return c;
        }

    }


投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/09/18 01:29

    ご回答ありがとうございます。

    その方法は思いつきませんでした、なるほど・・・。argiusさんの方法で、フォントサイズとボールドについては解決しました。

    このタイミングでもう一度質問するのも気が引けるのですが、もしよろしければ質問をお受けしていただいてもよろしいでしょうか?

    フォントボタン(ファミリー名?明朝体など)と下線ボタンなのですが、うまく機能させることができませんでした。
    同様の手順でコードを書いていった時に、セルサイズボタンでいうところのgetSize2D()メソッドにあたる適切なメソッドがわかりませんでした。

    下線ボタンについてはMap attrsとして渡していたので、getAttributes()を使ったのですが、下線にすることはできても他と組み合わせることができませんでした。

    フォントボタンについてはgetName()、getFamily()、getFontName()などいろいろ試したのですが、フォントを変更することすらできませんでした。

    それぞれどのようなメソッドで受け取れば良いでしょうか?

    キャンセル

  • 2015/09/18 15:24

    その辺は私もやったこと無いので確実には分かりませんが。

    下線の方は、両方から取り出したMapを混ぜてみてください。
    map.putAllをすれば、片方のMapに集約できるはず。

    Map attrs1 = font1.getAttributes();
    Map attrs2 = font2.getAttributes();
    attrs1.putAll(attrs2);
    font1.deriveFont(attrs1);

    フォント名はMap attrsに設定するんだと思いますが、詳しくは分かりません。
    前述のサイト(Swing TIPS)に載っているかも知れませんので調べてみてください。

    キャンセル

  • 2015/09/25 22:42

    ご回答ありがとうございます。

    ご報告が遅くなり申し訳ございません。
    無事に下線とボールドなどの複合系の実装をすることができました。
    現在は、いよいよSaveとOpenボタンの実装にとりかかり始めています。
    シリアライズなど見慣れない言葉が多くまた手こずりそうですが、何とかメモ帳としての形にまで持っていけたらと思います。
    本当にありがとうございました。
    また機会があればよろしくお願いします。

    完成しましたら、こちらに報告しにきます。

    キャンセル

+1

やりたい事を伺っていると、JTableを使うよりもJEditorPaneを使ってHTMLでコンテンツを作る形の方がよさそうに思います。Java Swing Tips - てんぷらメモにサンプルコードがたくさんあるので、そちらを参考にされるとよいのではないでしょうか?

※JTableのフォント変更についても解説が色々あります。

参考: JEditorPaneのHTMLEditorKitにCSSを適用

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/09/04 00:04

    ご回答ありがとうございます。
    リンクに目を通してみましたが、よくわかりませんでした。プログラミング自体初心者でして、HTMLなどの他の言語は全くわかりません。まずはJavaをきっちりやろうと思っていたのですが、他の言語の勉強も並行してやらなければ今回のようにできることが限られてくるのでしょうか。

    キャンセル

  • 2015/09/04 00:24

    失礼しました。HTMLは今お使いのブラウザの表示に使われる言語なので、HTMLから学びはじめる方も非常に多い言語です。なので、もしかするとご存知かと思い、提示させていただきました。
    Javaはプログラミング言語ですが、今回のようにコンテンツを装飾する情報を表現するのに適した言語ではありません。コンピュータを扱う時に使用する言語にも適材適所があります。とはいえ、最初から全てをうまく進める必要もないので、JTableで文字の装飾を実現されるのが良いと思います。

    キャンセル

  • 2015/09/07 21:12

    ご回答ありがとうございます。
    そもそもJavaのプログラミングにHTMLを使えるということ自体知らなかったので、とても勉強になりました。
    JToggleButtonのボルドーの「B」を一部だけHTMLで太文字にしてみました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る