如何为 JTextArea 实例中的选定文本设置粗体字体样式

How to set bold font style for selected text in JTextArea instance

我想为 JTextArea 实例中的选定文本设置粗体字体样式。

我这样试过:

textArea.getSelectedText().setFont(new Font("sansserif",Font.BOLD, 12));

但是不行。我也试过 JTextPaneJEditorPane 而不是 JTextArea 但没有效果。

我该怎么做?

您可以使用类似于更改颜色的 JTextPane 组件,如以下答案所述:How to set font color for selected text in jTextArea.

例如:

import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.WindowConstants;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;

public class BoldSelected {
    public static void main(final String[] args) {
        new BoldSelected().launchGui();
    }

    private void launchGui() {
        final String title = "Set bold font style for selected text in JTextArea instance";
        final JFrame frame = new JFrame("Stack Overflow: " + title);
        frame.setBounds(100, 100, 800, 600);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        final JTextPane textPane = new JTextPane();
        textPane.setText(title + ".");
        final Style style = textPane.addStyle("Bold", null);
        StyleConstants.setBold(style, true);
        textPane.getStyledDocument().setCharacterAttributes(4, 33, style, false);
        frame.getContentPane().add(textPane);
        frame.setVisible(true);
    }
}

您必须在 JTextPane 上设置插入符号侦听器以侦听何时选择了部分或全部文本。

这是我创建的 GUI。

这是代码:

package com.ggl.testing;

import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;

public class JTextPaneTest implements Runnable {

    private JTextPane textPane;

    private StyledDocument styledDocument;

    public static void main(String[] args) throws BadLocationException {
        SwingUtilities.invokeLater(new JTextPaneTest());
    }

    public JTextPaneTest() throws BadLocationException {
        this.styledDocument = new DefaultStyledDocument();
        this.styledDocument.insertString(0, displayText(), null);
        addStylesToDocument(styledDocument);
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("JTextPane Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);

        textPane = new JTextPane(styledDocument);
        textPane.addCaretListener(new SelectedText());
        textPane.setPreferredSize(new Dimension(250, 125));
        JScrollPane scrollPane = new JScrollPane(textPane);

        frame.add(scrollPane);
        frame.pack();
        frame.setVisible(true);
    }

    private String displayText() {
        return "This is some sample text.  Pick part of the text to select "
                + "by double clicking on a word.";
    }

    private void addStylesToDocument(StyledDocument styledDocument) {
        Style def = StyleContext.getDefaultStyleContext().getStyle(
                StyleContext.DEFAULT_STYLE);
        Style s = styledDocument.addStyle("bold", def);
        StyleConstants.setBold(s, true);
    }

    private class SelectedText implements CaretListener {

        @Override
        public void caretUpdate(CaretEvent event) {
            int dot = event.getDot();
            int mark = event.getMark();
            if (dot != mark) {
                if (dot < mark) {
                    int temp = dot;
                    dot = mark;
                    mark = temp;
                }
                boldSelectedText(mark, dot);
            }
        }

        private void boldSelectedText(int mark, int dot) {
            try {
                int length = dot - mark;
                String s = styledDocument.getText(mark, length);
                styledDocument.remove(mark, length);
                styledDocument.insertString(mark, s,
                        styledDocument.getStyle("bold"));
            } catch (BadLocationException e) {
                e.printStackTrace();
            }
        }

    }

}

I want to set bold font style for selected text in JTextArea instance.

您不能为 JTextArea 执行此操作。您需要使用 JTextPane.

然后就可以使用StyledEditorKit提供的默认Action了。创建一个 JButtonJMenuItem 来执行此操作:

JButton boldButton = new JButton( new StyledEditorKit.BoldAction() );
JMenuItem boldMenuItem = new JMenuItem( new StyledEditorKit.BoldAction() );

将按钮或菜单项添加到框架中。然后用户可以点击 button/menu 项,在选中文本后将其加粗。这是大多数编辑器的工作方式。还可以给Action加个加速,这样Action就可以直接用键盘调用了。

阅读有关 Text Component Features 的 Swing 教程部分,了解更多信息和工作示例。

简介

@Freek de Bruijn 和@Gilbert Le Blanc 已经发布了有关如何做您想做的事情的(有用的)答案,但其中 none 解释了您尝试做的事情的原因做不工作。这不是

的答案

How can I do that?

但是

的解释

But it does not work.

编辑: @camickr 发布了我认为正确的方法。

回答

来自关于 JTextArea 的教程:

You can customize text areas in several ways. For example, although a given text area can display text in only one font and color, you can set which font and color it uses.

(引号中的所有重点都是我的)和

If you want the text area to display its text using multiple fonts or other styles, you should use an editor pane or text pane.

这是因为JTextArea使用PlainDocument(参见this):

PlainDocument provides a basic container for text where all the text is displayed in the same font.

但是,JTextPane 使用 DefaultStyledDocument:

a container for styled text in no particular format.