+++ /dev/null
-/*\r
- * font chooser\r
- *\r
- * Copyright(c) 2008 olyutorskii\r
- * $Id: FontChooser.java 956 2009-12-13 15:14:07Z olyutorskii $\r
- */\r
-\r
-package jp.sourceforge.jindolf;\r
-\r
-import java.awt.BorderLayout;\r
-import java.awt.Color;\r
-import java.awt.Container;\r
-import java.awt.Dimension;\r
-import java.awt.Font;\r
-import java.awt.Graphics;\r
-import java.awt.Graphics2D;\r
-import java.awt.GridBagConstraints;\r
-import java.awt.GridBagLayout;\r
-import java.awt.Insets;\r
-import java.awt.Rectangle;\r
-import java.awt.event.ActionEvent;\r
-import java.awt.event.ActionListener;\r
-import java.awt.event.ItemEvent;\r
-import java.awt.event.ItemListener;\r
-import java.awt.font.FontRenderContext;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.Rectangle2D;\r
-import java.io.IOException;\r
-import javax.swing.BorderFactory;\r
-import javax.swing.JButton;\r
-import javax.swing.JCheckBox;\r
-import javax.swing.JComboBox;\r
-import javax.swing.JComponent;\r
-import javax.swing.JLabel;\r
-import javax.swing.JList;\r
-import javax.swing.JPanel;\r
-import javax.swing.JScrollPane;\r
-import javax.swing.JTextField;\r
-import javax.swing.ListSelectionModel;\r
-import javax.swing.border.Border;\r
-import javax.swing.event.ListSelectionEvent;\r
-import javax.swing.event.ListSelectionListener;\r
-\r
-/**\r
- * 発言表示フォント選択パネル。\r
- */\r
-@SuppressWarnings("serial")\r
-public class FontChooser extends JPanel\r
- implements ListSelectionListener,\r
- ActionListener,\r
- ItemListener{\r
-\r
- private static final Integer[] POINT_SIZES = {\r
- 8, 10, 12, 16, 18, 24, 32, 36, 48, 72, // TODO これで十分?\r
- };\r
- private static final CharSequence PREVIEW_CONTENT;\r
-\r
- static{\r
- CharSequence resourceText;\r
- try{\r
- resourceText = Jindolf.loadResourceText("resources/preview.txt");\r
- }catch(IOException e){\r
- resourceText = "ABC";\r
- }\r
- PREVIEW_CONTENT = resourceText;\r
- }\r
-\r
- private FontInfo fontInfo;\r
- private FontInfo lastFontInfo;\r
-\r
- private final JList familySelector;\r
- private final JComboBox sizeSelector;\r
- private final JCheckBox isBoldCheck;\r
- private final JCheckBox isItalicCheck;\r
- private final JCheckBox useTextAntiAliaseCheck;\r
- private final JCheckBox useFractionalCheck;\r
- private final JLabel maxBounds;\r
- private final JTextField decodeName;\r
- private final FontPreview preview;\r
- private final JButton resetDefault;\r
-\r
- private boolean maskListener = false;\r
-\r
- /**\r
- * コンストラクタ。\r
- */\r
- public FontChooser(){\r
- this(FontInfo.DEFAULT_FONTINFO);\r
- return;\r
- }\r
-\r
- /**\r
- * コンストラクタ。\r
- * @param fontInfo 初期フォント設定\r
- * @throws NullPointerException 引数がnull\r
- */\r
- public FontChooser(FontInfo fontInfo)\r
- throws NullPointerException{\r
- super();\r
-\r
- if(fontInfo == null) throw new NullPointerException();\r
- this.fontInfo = fontInfo;\r
- this.lastFontInfo = fontInfo;\r
-\r
- Jindolf.logger().info(\r
- "デフォルトの発言表示フォントに"\r
- + this.fontInfo.getFont()\r
- + "が選択されました" );\r
- Jindolf.logger().info(\r
- "発言表示のアンチエイリアス指定に"\r
- + this.fontInfo.getFontRenderContext().isAntiAliased()\r
- + "が指定されました" );\r
- Jindolf.logger().info(\r
- "発言表示のFractional指定に"\r
- + this.fontInfo.getFontRenderContext().usesFractionalMetrics()\r
- + "が指定されました" );\r
-\r
- this.familySelector = new JList(FontUtils.createFontSet().toArray());\r
- this.familySelector.setVisibleRowCount(-1);\r
- this.familySelector\r
- .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\r
-\r
- this.sizeSelector = new JComboBox();\r
- this.sizeSelector.setEditable(true);\r
- this.sizeSelector.setActionCommand(ActionManager.CMD_FONTSIZESEL);\r
- for(Integer size : POINT_SIZES){\r
- this.sizeSelector.addItem(size);\r
- }\r
-\r
- this.isBoldCheck = new JCheckBox("ボールド");\r
- this.isItalicCheck = new JCheckBox("イタリック");\r
- this.useTextAntiAliaseCheck = new JCheckBox("アンチエイリアス");\r
- this.useFractionalCheck = new JCheckBox("サブピクセル精度");\r
-\r
- this.maxBounds = new JLabel();\r
-\r
- this.decodeName = new JTextField();\r
- this.decodeName.setEditable(false);\r
- this.decodeName.setMargin(new Insets(1, 4, 1, 4));\r
- this.decodeName.setComponentPopupMenu(new TextPopup());\r
- Monodizer.monodize(this.decodeName);\r
-\r
- this.preview = new FontPreview(PREVIEW_CONTENT, this.fontInfo);\r
-\r
- this.resetDefault = new JButton("出荷時に戻す");\r
- this.resetDefault.addActionListener(this);\r
-\r
- design(this);\r
- updateControlls();\r
- updatePreview();\r
-\r
- this.familySelector.addListSelectionListener(this);\r
- this.sizeSelector .addActionListener(this);\r
-\r
- this.isBoldCheck .addItemListener(this);\r
- this.isItalicCheck .addItemListener(this);\r
- this.useTextAntiAliaseCheck.addItemListener(this);\r
- this.useFractionalCheck .addItemListener(this);\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * GUIのデザイン、レイアウトを行う。\r
- * @param content コンテナ\r
- */\r
- private void design(Container content){\r
- GridBagLayout layout = new GridBagLayout();\r
- GridBagConstraints constraints = new GridBagConstraints();\r
-\r
- content.setLayout(layout);\r
-\r
- Border border;\r
- JPanel panel;\r
-\r
- JComponent fontPref = createFontPrefPanel();\r
-\r
- constraints.insets = new Insets(5, 5, 5, 5);\r
-\r
- constraints.weightx = 1.0;\r
- constraints.weighty = 0.0;\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
- constraints.fill = GridBagConstraints.BOTH;\r
- content.add(fontPref, constraints);\r
-\r
- constraints.weightx = 1.0;\r
- constraints.weighty = 1.0;\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
- constraints.fill = GridBagConstraints.BOTH;\r
- border = BorderFactory.createTitledBorder("プレビュー");\r
- panel = new JPanel();\r
- panel.add(this.preview);\r
- panel.setBorder(border);\r
- content.add(createPreviewPanel(), constraints);\r
-\r
- constraints.weightx = 1.0;\r
- constraints.weighty = 0.0;\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
- constraints.fill = GridBagConstraints.HORIZONTAL;\r
- content.add(createFontDecodePanel(), constraints);\r
-\r
- constraints.insets = new Insets(5, 5, 5, 5);\r
- constraints.weightx = 1.0;\r
- constraints.weighty = 0.0;\r
- constraints.gridwidth = 1;\r
- constraints.fill = GridBagConstraints.HORIZONTAL;\r
- content.add(this.maxBounds, constraints);\r
-\r
- constraints.weightx = 0.0;\r
- constraints.weighty = 0.0;\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
- constraints.fill = GridBagConstraints.HORIZONTAL;\r
- content.add(this.resetDefault, constraints);\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * フォント設定画面を生成する。\r
- * @return フォント設定画面\r
- */\r
- private JComponent createFontPrefPanel(){\r
- JPanel result = new JPanel();\r
-\r
- GridBagLayout layout = new GridBagLayout();\r
- GridBagConstraints constraints = new GridBagConstraints();\r
- result.setLayout(layout);\r
-\r
- Border border;\r
-\r
- constraints.insets = new Insets(0, 0, 0, 5);\r
- constraints.weightx = 1.0;\r
- constraints.weighty = 0.0;\r
- constraints.gridheight = GridBagConstraints.REMAINDER;\r
- constraints.fill = GridBagConstraints.BOTH;\r
- border = BorderFactory.createEmptyBorder(1, 1, 1, 1);\r
- this.familySelector.setBorder(border);\r
- JScrollPane familyScroller = new JScrollPane(this.familySelector);\r
- border = BorderFactory.createTitledBorder("フォントファミリ選択");\r
- JPanel familyPanel = new JPanel();\r
- familyPanel.setLayout(new BorderLayout());\r
- familyPanel.add(familyScroller, BorderLayout.CENTER);\r
- familyPanel.setBorder(border);\r
- result.add(familyPanel, constraints);\r
-\r
- constraints.insets = new Insets(0, 0, 0, 0);\r
- constraints.weightx = 0.0;\r
- constraints.gridheight = 1;\r
- constraints.fill = GridBagConstraints.HORIZONTAL;\r
- constraints.anchor = GridBagConstraints.WEST;\r
-\r
- border = BorderFactory.createTitledBorder("ポイントサイズ指定");\r
- JPanel panel = new JPanel();\r
- panel.add(this.sizeSelector);\r
- panel.setBorder(border);\r
- result.add(panel, constraints);\r
-\r
- constraints.anchor = GridBagConstraints.NORTHWEST;\r
- result.add(this.isBoldCheck, constraints);\r
- result.add(this.isItalicCheck, constraints);\r
- result.add(this.useTextAntiAliaseCheck, constraints);\r
- result.add(this.useFractionalCheck, constraints);\r
-\r
- return result;\r
- }\r
-\r
- /**\r
- * プレビュー画面を生成する。\r
- * @return プレビュー画面\r
- */\r
- private JComponent createPreviewPanel(){\r
- JPanel result = new JPanel();\r
-\r
- JScrollPane scroller = new JScrollPane(this.preview);\r
- scroller.getVerticalScrollBar().setUnitIncrement(8);\r
-\r
- Border border;\r
- border = BorderFactory.createTitledBorder("プレビュー");\r
- result.setBorder(border);\r
- result.setLayout(new BorderLayout());\r
- result.add(scroller, BorderLayout.CENTER);\r
-\r
- return result;\r
- }\r
-\r
- /**\r
- * フォントデコード名表示パネルを生成する。\r
- * @return フォントデコード名表示パネル\r
- */\r
- private JComponent createFontDecodePanel(){\r
- JPanel result = new JPanel();\r
-\r
- GridBagLayout layout = new GridBagLayout();\r
- GridBagConstraints constraints = new GridBagConstraints();\r
- result.setLayout(layout);\r
-\r
- constraints.weightx = 0.0;\r
- constraints.weighty = 0.0;\r
- constraints.gridwidth = 1;\r
- constraints.fill = GridBagConstraints.NONE;\r
- result.add(new JLabel("Font.deode() 識別名:"), constraints);\r
-\r
- constraints.weightx = 1.0;\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
- constraints.fill = GridBagConstraints.HORIZONTAL;\r
- result.add(this.decodeName, constraints);\r
-\r
- return result;\r
- }\r
-\r
- /**\r
- * フォント設定を返す。\r
- * @return フォント設定\r
- */\r
- public FontInfo getFontInfo(){\r
- return this.fontInfo;\r
- }\r
-\r
- /**\r
- * フォント設定を適用する。\r
- * @param newInfo 新設定\r
- * @throws NullPointerException 引数がnull\r
- */\r
- public void setFontInfo(FontInfo newInfo) throws NullPointerException{\r
- if(newInfo == null) throw new NullPointerException();\r
-\r
- FontInfo old = this.fontInfo;\r
- if(old.equals(newInfo)) return;\r
-\r
- this.fontInfo = newInfo;\r
-\r
- updateControlls();\r
- updatePreview();\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * 選択されたフォントを返す。\r
- * @return フォント\r
- */\r
- private Font getSelectedFont(){\r
- return this.fontInfo.getFont();\r
- }\r
-\r
- /**\r
- * 設定されたフォント描画設定を返す。\r
- * @return 描画設定\r
- */\r
- protected FontRenderContext getFontRenderContext(){\r
- return this.fontInfo.getFontRenderContext();\r
- }\r
-\r
- /**\r
- * フォント設定に合わせてプレビュー画面を更新する。\r
- */\r
- private void updatePreview(){\r
- this.preview.setFontInfo(this.fontInfo);\r
- return;\r
- }\r
-\r
- /**\r
- * フォント設定に合わせてGUIを更新する。\r
- */\r
- private void updateControlls(){\r
- this.maskListener = true;\r
-\r
- Font currentFont = getSelectedFont();\r
- FontRenderContext currentContext = getFontRenderContext();\r
-\r
- String defaultFamily = currentFont.getFamily();\r
- this.familySelector.setSelectedValue(defaultFamily, true);\r
-\r
- Integer selectedInteger = Integer.valueOf(currentFont.getSize());\r
- this.sizeSelector.setSelectedItem(selectedInteger);\r
- int sizeItems = this.sizeSelector.getItemCount();\r
- for(int index = 0; index <= sizeItems - 1; index++){\r
- Object sizeItem = this.sizeSelector.getItemAt(index);\r
- if(sizeItem.equals(selectedInteger)){\r
- this.sizeSelector.setSelectedIndex(index);\r
- break;\r
- }\r
- }\r
-\r
- this.isBoldCheck .setSelected(currentFont.isBold());\r
- this.isItalicCheck.setSelected(currentFont.isItalic());\r
-\r
- this.useTextAntiAliaseCheck\r
- .setSelected(currentContext.isAntiAliased());\r
- this.useFractionalCheck\r
- .setSelected(currentContext.usesFractionalMetrics());\r
-\r
- this.decodeName.setText(FontUtils.getFontDecodeName(currentFont));\r
- this.decodeName.setCaretPosition(0);\r
-\r
- Rectangle2D r2d = currentFont.getMaxCharBounds(currentContext);\r
- Rectangle rect = r2d.getBounds();\r
- String boundInfo = "最大文字寸法 : "\r
- + rect.width\r
- + " pixel幅 × "\r
- + rect.height\r
- + " pixel高";\r
- this.maxBounds.setText(boundInfo);\r
-\r
- this.maskListener = false;\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * {@inheritDoc}\r
- * ダイアログの表示・非表示。\r
- * ダイアログが閉じられるまで制御を返さない。\r
- * @param isVisible trueなら表示 {@inheritDoc}\r
- */\r
- @Override\r
- public void setVisible(boolean isVisible){\r
- if(isVisible){\r
- updateControlls();\r
- updatePreview();\r
- }\r
- this.lastFontInfo = this.fontInfo;\r
-\r
- super.setVisible(isVisible);\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * {@inheritDoc}\r
- * チェックボックス操作のリスナ。\r
- * @param event 操作イベント {@inheritDoc}\r
- */\r
- public void itemStateChanged(ItemEvent event){\r
- if(this.maskListener) return;\r
-\r
- Object source = event.getSource();\r
-\r
- if( source != this.isBoldCheck\r
- && source != this.isItalicCheck\r
- && source != this.useTextAntiAliaseCheck\r
- && source != this.useFractionalCheck ){\r
- return;\r
- }\r
-\r
- int style = 0 | Font.PLAIN;\r
- if(this.isBoldCheck.isSelected()){\r
- style = style | Font.BOLD;\r
- }\r
- if(this.isItalicCheck.isSelected()){\r
- style = style | Font.ITALIC;\r
- }\r
- Font newFont = getSelectedFont();\r
- if(newFont.getStyle() != style){\r
- newFont = newFont.deriveFont(style);\r
- }\r
-\r
- AffineTransform tx = getFontRenderContext().getTransform();\r
- boolean isAntiAliases = this.useTextAntiAliaseCheck.isSelected();\r
- boolean useFractional = this.useFractionalCheck .isSelected();\r
- FontRenderContext newContext =\r
- new FontRenderContext(tx, isAntiAliases, useFractional);\r
-\r
- FontInfo newInfo = new FontInfo(newFont, newContext);\r
- setFontInfo(newInfo);\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * フォントサイズ変更処理。\r
- */\r
- private void actionFontSizeSelected(){\r
- Object selected = this.sizeSelector.getSelectedItem();\r
- if(selected == null) return;\r
-\r
- Integer selectedInteger;\r
- if(selected instanceof Integer){\r
- selectedInteger = (Integer) selected;\r
- }else{\r
- try{\r
- selectedInteger = Integer.valueOf(selected.toString());\r
- }catch(NumberFormatException e){\r
- selectedInteger = Integer.valueOf(\r
- this.lastFontInfo.getFont().getSize()\r
- );\r
- }\r
- }\r
-\r
- if(selectedInteger.intValue() <= 0){\r
- selectedInteger =\r
- Integer.valueOf(this.lastFontInfo.getFont().getSize());\r
- }\r
-\r
- float fontSize = selectedInteger.floatValue();\r
- Font newFont = getSelectedFont().deriveFont(fontSize);\r
- FontInfo newInfo = this.fontInfo.deriveFont(newFont);\r
- setFontInfo(newInfo);\r
-\r
- int sizeItems = this.sizeSelector.getItemCount();\r
- for(int index = 0; index <= sizeItems - 1; index++){\r
- Object sizeItem = this.sizeSelector.getItemAt(index);\r
- if(sizeItem.equals(selectedInteger)){\r
- this.sizeSelector.setSelectedIndex(index);\r
- break;\r
- }\r
- }\r
-\r
- updateControlls();\r
- updatePreview();\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * {@inheritDoc}\r
- * ボタン操作及びフォントサイズ指定コンボボックス操作のリスナ。\r
- * @param event 操作イベント {@inheritDoc}\r
- */\r
- public void actionPerformed(ActionEvent event){\r
- if(this.maskListener) return;\r
-\r
- String cmd = event.getActionCommand();\r
- if(cmd.equals(ActionManager.CMD_FONTSIZESEL)){\r
- actionFontSizeSelected();\r
- }\r
-\r
- Object source = event.getSource();\r
- if(source == this.resetDefault){\r
- setFontInfo(FontInfo.DEFAULT_FONTINFO);\r
- }\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * {@inheritDoc}\r
- * フォントファミリリスト選択操作のリスナ。\r
- * @param event 操作イベント {@inheritDoc}\r
- */\r
- public void valueChanged(ListSelectionEvent event){\r
- if(this.maskListener) return;\r
-\r
- if(event.getSource() != this.familySelector) return;\r
- if(event.getValueIsAdjusting()) return;\r
-\r
- Object selected = this.familySelector.getSelectedValue();\r
- if(selected == null) return;\r
-\r
- String familyName = selected.toString();\r
- Font currentFont = getSelectedFont();\r
- int style = currentFont.getStyle();\r
- int size = currentFont.getSize();\r
-\r
- Font newFont = new Font(familyName, style, size);\r
- FontInfo newInfo = this.fontInfo.deriveFont(newFont);\r
-\r
- setFontInfo(newInfo);\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * フォントプレビュー画面用コンポーネント。\r
- */\r
- private static class FontPreview extends JComponent{\r
-\r
- private static final int MARGIN = 5;\r
-\r
- private final GlyphDraw draw;\r
-\r
- private FontInfo fontInfo;\r
-\r
- /**\r
- * コンストラクタ。\r
- * @param source 文字列\r
- * @param fontInfo フォント設定\r
- */\r
- public FontPreview(CharSequence source,\r
- FontInfo fontInfo ){\r
- super();\r
-\r
- this.fontInfo = fontInfo;\r
- this.draw = new GlyphDraw(source, this.fontInfo);\r
- this.draw.setFontInfo(this.fontInfo);\r
-\r
- this.draw.setPos(MARGIN, MARGIN);\r
-\r
- this.draw.setColor(Color.BLACK);\r
- setBackground(Color.WHITE);\r
-\r
- updateBounds();\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * サイズ更新。\r
- */\r
- private void updateBounds(){\r
- Rectangle bounds = this.draw.setWidth(Integer.MAX_VALUE);\r
- Dimension dimension = new Dimension(bounds.width + MARGIN * 2,\r
- bounds.height + MARGIN * 2 );\r
- setPreferredSize(dimension);\r
- revalidate();\r
- repaint();\r
- return;\r
- }\r
-\r
- /**\r
- * フォント設定の変更。\r
- * @param newFontInfo フォント設定\r
- */\r
- public void setFontInfo(FontInfo newFontInfo){\r
- this.fontInfo = newFontInfo;\r
- this.draw.setFontInfo(this.fontInfo);\r
-\r
- updateBounds();\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * {@inheritDoc}\r
- * 文字列の描画。\r
- * @param g {@inheritDoc}\r
- */\r
- @Override\r
- public void paintComponent(Graphics g){\r
- super.paintComponent(g);\r
- Graphics2D g2d = (Graphics2D) g;\r
- this.draw.paint(g2d);\r
- return;\r
- }\r
- }\r
-\r
-}\r