前景色の変更

広告

スタイルの変更の最後として文字の前景色の変更を実装します。

変更点は下記の通りです。

protected JComboBox comboColor;  /* 前景色 */

protected String[] colorHTML = {"#000000", "#0000FF", "#00FF00",
  "#00FFFF", "#FF0000", "#FF00FF", "#FFFF00", "#FFFFFF"};

   ....

  /* 前景色用コンボボックス */
  DefaultComboBoxModel colorModel = new DefaultComboBoxModel();
  for (int i = 0 ; i < 8; i++){
    /* 色つきのラベルを作成する */
    StringBuffer sb = new StringBuffer();
    sb.append("<html><font color=\"");
    sb.append(colorHTML[i]);
    sb.append("\">■</font></html>");

    colorModel.addElement(new String(sb));
  }
  comboColor = new JComboBox(colorModel);
  comboColor.setMaximumSize(comboColor.getPreferredSize());
  comboColor.addActionListener(this);
  comboColor.setActionCommand("comboColor");
  toolBar.add(comboColor);

まず前景色選択用のコンボボックスを作成しています。色が分かるようにHTML付きラベルを使っています。

.....

}else if (actionCommand.equals("comboColor")){
  /* 前景色 */
  int col = comboColor.getSelectedIndex();
  int b = (col % 2) * 255;
  int g = ((col / 2) % 2) * 255;
  int r = ((col / 4) % 2) * 255;

  StyleConstants.setForeground(attr, new Color(r, g, b));

コンボボックスで色を選択した時の処理です。選択された項目のIndex番号から実際に表示する色のRGBの値を作成し、StyleConstantsクラスのsetForegroundメソッドを使って設定しています。

/* 前景色の状態表示 */
Color col = StyleConstants.getForeground(atrr);
int r = (col.getRed() / 255) * 4;
int g = (col.getGreen() / 255) * 2;
int b = col.getBlue() / 255;
comboColor.setSelectedIndex(r + g + b);

現在のキャレットの位置にある色情報をコンボボックスに反映させています。設定されているColorオブジェクトを読み出し、そこからRGBの値に分解して、コンボボックスのIndex番号に変更しています。Colorオブジェクトの読み出しにはStyleConstantsクラスのgetForegroundメソッドを使っています。

public static Color getForeground(AttributeSet a)

属性リストからフォアグラウンドカラーの設定を返します。

パラメータ:
  a - 属性セット
戻り値:
  色。デフォルトは Color.black

サンプル

では実際にサンプルで試して見ます。使い方は今までと同じです。

import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.awt.*;

public class TextPaneTest extends JFrame 
  implements ActionListener, CaretListener{

  protected JTextPane textPane;

  protected DefaultStyledDocument doc;
  protected StyleContext sc;

  protected JToolBar toolBar;

  protected JComboBox comboFonts;  /* Font選択 */
  protected JComboBox comboSizes;  /* Fontサイズ */
  protected JToggleButton toggleB; /* 強調 */
  protected JToggleButton toggleI; /* 斜体 */
  protected JToggleButton toggleU; /* アンダーライン */
  protected JToggleButton toggleS; /* 取り消し線 */
  protected JComboBox comboColor;  /* 前景色 */

  protected String currentFontName = "";
  protected int currentFontSize = 0;
  protected boolean flag = false;

  protected String[] colorHTML = {"#000000", "#0000FF", "#00FF00",
    "#00FFFF", "#FF0000", "#FF00FF", "#FFFF00", "#FFFFFF"};

  public static void main(String[] args){
    TextPaneTest test = new TextPaneTest();

    test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    test.setVisible(true);
  }

  TextPaneTest(){
    setTitle("TextPaneTest Test");
    setBounds( 10, 10, 500, 200);

    initToolbar();
    getContentPane().add(toolBar, BorderLayout.NORTH);

    textPane = new JTextPane();
    JScrollPane scroll = new JScrollPane(textPane, 
      JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, 
      JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

    getContentPane().add(scroll, BorderLayout.CENTER);

    sc = new StyleContext();
    doc = new DefaultStyledDocument(sc);

    textPane.setDocument(doc);

    /* CaretListenerをセット */
    textPane.addCaretListener(this);

    /* 初期文書の読み込み */
    initDocument();
  }

  protected void initDocument(){
    StringBuffer sb = new StringBuffer();
    sb.append("スタイル付きのテキストサンプルです。\n");
    sb.append("スタイルを変えて表示しています。");

    try{
      /* 文書を挿入する */
      doc.insertString(0, new String(sb), 
        sc.getStyle(StyleContext.DEFAULT_STYLE));
    }catch (BadLocationException ble){
      System.err.println("初期文書の読み込みに失敗しました。");
    }
  }

  protected void initToolbar(){
    toolBar = new JToolBar();
    toolBar.setLayout(new FlowLayout(FlowLayout.LEFT));

    /* フォント一覧の取得 */
    GraphicsEnvironment ge = 
      GraphicsEnvironment.getLocalGraphicsEnvironment();
    String familyName[] = ge.getAvailableFontFamilyNames();

    /* フォント選択用コンボボックス */
    comboFonts = new JComboBox(familyName);
    comboFonts.setMaximumSize(comboFonts.getPreferredSize());
    comboFonts.addActionListener(this);
    comboFonts.setActionCommand("comboFonts");
    toolBar.add(comboFonts);

    /* フォントサイズ選択用コンボボックス */
    comboSizes = new JComboBox(new String[] {"8", "9", "10", 
      "11", "12", "14", "16", "18", "20", "22", "24", "26", 
      "28", "36", "48", "72"});
    comboSizes.setMaximumSize(comboSizes.getPreferredSize());
    comboSizes.addActionListener(this);
    comboSizes.setActionCommand("comboSizes");
    toolBar.add(comboSizes);

    toolBar.addSeparator();

    /* 強調 選択用トグルボタン */
    toggleB = new JToggleButton("<html><b>B</b></html>");
    toggleB.setPreferredSize(new Dimension(26, 26));
    toggleB.addActionListener(this);
    toggleB.setActionCommand("toggleB");
    toolBar.add(toggleB);

    /* 斜体 選択用トグルボタン */
    toggleI = new JToggleButton("<html><i>I</i></html>");
    toolBar.add(toggleI);
    toggleI.addActionListener(this);
    toggleI.setActionCommand("toggleI");
    toggleI.setPreferredSize(new Dimension(26, 26));

    /* アンダーライン 選択用トグルボタン */
    toggleU = new JToggleButton("<html><u>U</u></html>");
    toolBar.add(toggleU);
    toggleU.addActionListener(this);
    toggleU.setActionCommand("toggleU");
    toggleU.setPreferredSize(new Dimension(26, 26));

    /* 取り消し線 選択用トグルボタン */
    toggleS = new JToggleButton("<html><s>S</s></html>");
    toolBar.add(toggleS);
    toggleS.addActionListener(this);
    toggleS.setActionCommand("toggleS");
    toggleS.setPreferredSize(new Dimension(26, 26));

    toolBar.addSeparator();

    /* 前景色用コンボボックス */
    DefaultComboBoxModel colorModel = new DefaultComboBoxModel();
    for (int i = 0 ; i < 8; i++){
      /* 色つきのラベルを作成する */
      StringBuffer sb = new StringBuffer();
      sb.append("<html><font color=\"");
      sb.append(colorHTML[i]);
      sb.append("\">■</font></html>");

      colorModel.addElement(new String(sb));
    }
    comboColor = new JComboBox(colorModel);
    comboColor.setMaximumSize(comboColor.getPreferredSize());
    comboColor.addActionListener(this);
    comboColor.setActionCommand("comboColor");
    toolBar.add(comboColor);
  }

  public void actionPerformed(ActionEvent e){
    if (flag){
      /* キャレット変更に伴うActionEventの場合はパスする */
      return;
    }

    String actionCommand = e.getActionCommand();
    MutableAttributeSet attr = new SimpleAttributeSet();

    if (actionCommand.equals("comboFonts")){
      /* フォント変更 */
      String fontName = comboFonts.getSelectedItem().toString();
      StyleConstants.setFontFamily(attr, fontName);
    }else if (actionCommand.equals("comboSizes")){
      /* フォントサイズ変更 */
      int fontSize = 0;
      try{
        fontSize = Integer.parseInt(comboSizes.
          getSelectedItem().toString());
      }catch (NumberFormatException ex){
        return;
      }

      StyleConstants.setFontSize(attr, fontSize);
    }else if (actionCommand.equals("toggleB")){
      /* 強調 */
      StyleConstants.setBold(attr, toggleB.isSelected());
    }else if (actionCommand.equals("toggleI")){
      /* 斜体 */
      StyleConstants.setItalic(attr, toggleI.isSelected());
    }else if (actionCommand.equals("toggleU")){
      /* アンダーライン */
      StyleConstants.setUnderline(attr, toggleU.isSelected());
    }else if (actionCommand.equals("toggleS")){
      /* 取り消し線 */
      StyleConstants.setStrikeThrough(attr, toggleS.isSelected());
    }else if (actionCommand.equals("comboColor")){
      /* 前景色 */
      int col = comboColor.getSelectedIndex();
      int b = (col % 2) * 255;
      int g = ((col / 2) % 2) * 255;
      int r = ((col / 4) % 2) * 255;

      StyleConstants.setForeground(attr, new Color(r, g, b));
    }else{
      return;
    }

    setAttributeSet(attr);
    textPane.requestFocusInWindow();
  }

  protected void setAttributeSet(AttributeSet attr) {
    /* 選択している文字のスタイルを変更する */

    int start = textPane.getSelectionStart();
    int end = textPane.getSelectionEnd();

    doc.setCharacterAttributes(start, end - start, attr, false);
  }

  public void caretUpdate(CaretEvent e){
    flag = true;

    int p = textPane.getSelectionStart();
    AttributeSet atrr = doc.getCharacterElement(p).getAttributes();

    String name = StyleConstants.getFontFamily(atrr);
    /* 変更前と同じ場合は無視する */
    if (!currentFontName.equals(name)){
      currentFontName = name;
      comboFonts.setSelectedItem(name);
    }

    int size = StyleConstants.getFontSize(atrr);
    /* 変更前と同じ場合は無視する */
    if (currentFontSize != size){
      currentFontSize = size;
      comboSizes.setSelectedItem(Integer.toString(size));
    }

    /* 強調/斜体/アンダーライン/取り消し線 の状態表示 */
    toggleB.setSelected(StyleConstants.isBold(atrr));
    toggleI.setSelected(StyleConstants.isItalic(atrr));
    toggleU.setSelected(StyleConstants.isUnderline(atrr));
    toggleS.setSelected(StyleConstants.isStrikeThrough(atrr));

    /* 前景色の状態表示 */
    Color col = StyleConstants.getForeground(atrr);
    int r = (col.getRed() / 255) * 4;
    int g = (col.getGreen() / 255) * 2;
    int b = col.getBlue() / 255;
    comboColor.setSelectedIndex(r + g + b);

    flag = false;
  }
}

実際に試した結果が下記となります。

( Written by Tatsuo Ikura )

プロフィール画像

著者 / TATSUO IKURA

これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。