如何使用setFocusable(false)在JTextPane中突出显示文本



所以我有一个JTextPane基本上作为控制台。我把它放在JFrame的中心区域JTextField的南部区域。JTextField将获取它所拥有的文本,并在用户按enter时将其添加到JTextPane。为了使JTextPane不能被用户编辑,我必须使用setFocusable(false),因为使用setEditable(false)会阻止任何文本出现在JTextPane上。但是,虽然我不希望用户编辑窗格,但我仍然希望用户能够突出显示窗格中的文本,但我似乎找不到这样做的方法。

下面是一个示例,演示了我的意思

package resources;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.text.AttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
public class SampeTextPane extends JFrame
{
    public SampeTextPane()
    {
        setPreferredSize(new Dimension(350, 200));
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        JTextPane display = new JTextPane();
        display.setBorder(new EmptyBorder(5, 5, 5, 5));
        display.setMargin(new Insets(5, 5, 5, 5));
        display.setFocusable(false);
        appendToPane(display, "Example", Color.BLUE);
        JTextField field = new JTextField();
        field.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                appendToPane(display, field.getText(), Color.BLACK);
                field.setText("");
            }
        });
        add(display, BorderLayout.CENTER);
        add(field, BorderLayout.SOUTH);
        pack();
        setVisible(true);
    }
    private void appendToPane(JTextPane pane, String text, Color color)
    {
        StyleContext sc = StyleContext.getDefaultStyleContext();
        AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, color);
        aset = sc.addAttribute(aset, StyleConstants.Alignment, StyleConstants.ALIGN_JUSTIFIED);
        int len = pane.getDocument().getLength();
        pane.setCaretPosition(len);
        pane.setCharacterAttributes(aset, false);
        pane.replaceSelection(text + "n");
    }
    public static void main(String[] args)
    {
        new SampeTextPane();
    }
}

提前感谢您的帮助。

使用setEditable(false)阻止任何文本出现在JTextPane上。

你可以使JTextPane不可编辑,但你不能通过文本窗格更新文本。

你可以通过Document:

来更新文本
//int len = pane.getDocument().getLength();
//pane.setCaretPosition(len);
//pane.setCharacterAttributes(aset, false);
//pane.replaceSelection(text + "n");
try
{
    StyledDocument doc = pane.getStyledDocument();
    doc.insertString(doc.getLength(), text, aset);
}
catch(BadLocationException e) { System.out.println(e); }

另一个选项(尽管更复杂)是使用布尔标志来允许或不允许对文档进行更改,这里建议使用StanislavL。

在您的情况下,它可能看起来像:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.DocumentFilter;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
@SuppressWarnings("serial")
public class SampeTextPane extends JFrame {
    private boolean isApi = false;
    public SampeTextPane() {
        setPreferredSize(new Dimension(350, 200));
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        JTextPane display = new JTextPane();
        ((DefaultStyledDocument) display.getDocument()).setDocumentFilter(new DocFilter());
        display.setBorder(new EmptyBorder(5, 5, 5, 5));
        display.setMargin(new Insets(5, 5, 5, 5));
        // !! display.setFocusable(false);
        appendToPane(display, "Example", Color.BLUE);
        JTextField field = new JTextField();
        field.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                appendToPane(display, field.getText(), Color.BLACK);
                field.setText("");
            }
        });
        add(display, BorderLayout.CENTER);
        add(field, BorderLayout.SOUTH);
        pack();
        setVisible(true);
    }
    private void appendToPane(JTextPane pane, String text, Color color) {
        isApi = true;
        StyleContext sc = StyleContext.getDefaultStyleContext();
        AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground,
                color);
        aset = sc.addAttribute(aset, StyleConstants.Alignment, StyleConstants.ALIGN_JUSTIFIED);
        int len = pane.getDocument().getLength();
        String selection = pane.getSelectedText();
        if (selection == null) {
            pane.setCaretPosition(len);
            text += "n";
        }        
        pane.setCharacterAttributes(aset, false);
        pane.replaceSelection(text);
        isApi = false;
    }
    private class DocFilter extends DocumentFilter {
        @Override
        public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr)
                throws BadLocationException {
            if (isApi) {
                super.insertString(fb, offset, string, attr);
            }
        }
        @Override
        public void remove(FilterBypass fb, int offset, int length) throws BadLocationException {
            if (isApi) {
                super.remove(fb, offset, length);
            }
        }
        @Override
        public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs)
                throws BadLocationException {
            if (isApi) {
                super.replace(fb, offset, length, text, attrs);
            }
        }
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new SampeTextPane());
    }
}

相关内容

  • 没有找到相关文章

最新更新