获取 JTextPane 中选中文本的属性
Get attributes of selected text in JTextPane
我正在尝试了解如何获取 JTextPane 中某些选定文本的属性。
我发现最好的解决方案是使用 getInputAttributes() 和 CaretListener 来实现,但是我在这个实现上遇到了一些问题。
这是我的解决方案,显示了插入符号最后位置的文本属性,而不是插入符号的实际位置。我究竟做错了什么?请。
这是我的 SSCCE:
public class Testovani{
static JTextPane pane;
static JLabel label;
public static void main(String[] args) throws BadLocationException {
JFrame frame = new JFrame();
frame.setSize(350, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
pane = new JTextPane();
label = new JLabel();
pane.addCaretListener(new SelectionListener());
MutableAttributeSet attrs = new SimpleAttributeSet();
StyleConstants.setBold(attrs, true);
pane.getDocument().insertString(0, "\n", null);
pane.getDocument().insertString(0, "This is first row non bold", null);
pane.getDocument().insertString(0, "\n", null);
pane.getDocument().insertString(0, "This is second row bold", attrs);
pane.getDocument().insertString(0, "\n", null);
pane.getDocument().insertString(0, "This is third row bold", attrs);
pane.getDocument().insertString(0, "\n", null);
frame.add(pane);
frame.add(label, BorderLayout.SOUTH);
frame.setVisible(true);
}
private static class SelectionListener implements CaretListener{
@Override
public void caretUpdate(CaretEvent e) {
AttributeSet attrs =((StyledEditorKit)pane.getEditorKit()).getInputAttributes();
label.setText("Is bold: " + String.valueOf(StyleConstants.isBold(attrs)));
}
}}
我还有两个奖励问题。这种方法是用于选择还是仅用于插入符号的位置?还有什么 returns,如果有一个文本选择,其中一部分是粗体而第二部分不是?
其实选择属性是个复杂的问题,需要你了解业务需求。
假设选择了一段文本并且您需要选择字体大小。但
该片段有 3 段不同的文本,有 3 种不同的大小。
选择开始位置放在10pt文本的中间,然后一段12pt大小的文本和选择结束在14pt大小片段的中间。
您想要什么尺寸? 10、12、14 或(多个)?
最简单的方法是使用 inputAttributes。
默认情况下,属性是从插入符位置复制的,但当然您可以添加一个插入符侦听器,并在每次更新时根据您的业务逻辑检查并根据需要填充输入属性(处理具有不同属性的多个文本片段).
更新:
尝试将 AttributeSet attrs =((StyledEditorKit)pane.getEditorKit()).getInputAttributes();
包装在 SwingUtilities.invokeLater() 调用
中
获取选区的属性没有预期的行为,只是因为选区可以包含具有不同属性的字符元素。
您必须了解,getInputAttributes
returns textPane 为下一个输入计算的最佳属性与 getCharacterAttributes
returns 当前插入符位置的属性。在选择的情况下,插入符号是您结束选择的位置。如果您从左到右或从右到左选择文本,它可以是给定的 getSelectionStart
或 getSelectionEnd
。
无论如何,我建议您获取 JTextPane 的 StyledDocument,然后遍历从 getSelectionStart
到 getSelectionEnd
的字符元素:
for(int i=jtp.getSelectionStart(); i<jtp.getSelectionEnd(); i++) {
AttributeSet set = jtp.getStyledDocument().getCharacterElement(i).getAttributes();
//here, combine, analyse, do whatever you like with your AttributeSet
//You can use StyleConstants.xxx to analyse the attributes
}
我使用@Sharcoux 的解决方案并做了一处更改:我确保始终至少有一个字符可以迭代。当没有选择时,getSelectionStart() == getSelectionEnd()
。出于这个原因,我会稍微改变一下:
int iStart = jtp.getSelectionStart();
int iEnd = jtp.getSelectionEnd();
if(iStart > 0) iStart--;
else if(iEnd < jtp.getDocument().getEndPosition().getOffset()) iEnd++;
for(int i = iStart; i < iEnd; i++) {
AttributeSet set = jtp.getStyledDocument().getCharacterElement(i).getAttributes();
//here, combine, analyse, do whatever you like with your AttributeSet
//You can use StyleConstants.xxx to analyse the attributes
}
唯一没有改变的情况是文档完全为空时,在这种情况下 getInputAttributes
应该可以正常工作。
我正在尝试了解如何获取 JTextPane 中某些选定文本的属性。 我发现最好的解决方案是使用 getInputAttributes() 和 CaretListener 来实现,但是我在这个实现上遇到了一些问题。
这是我的解决方案,显示了插入符号最后位置的文本属性,而不是插入符号的实际位置。我究竟做错了什么?请。
这是我的 SSCCE:
public class Testovani{
static JTextPane pane;
static JLabel label;
public static void main(String[] args) throws BadLocationException {
JFrame frame = new JFrame();
frame.setSize(350, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
pane = new JTextPane();
label = new JLabel();
pane.addCaretListener(new SelectionListener());
MutableAttributeSet attrs = new SimpleAttributeSet();
StyleConstants.setBold(attrs, true);
pane.getDocument().insertString(0, "\n", null);
pane.getDocument().insertString(0, "This is first row non bold", null);
pane.getDocument().insertString(0, "\n", null);
pane.getDocument().insertString(0, "This is second row bold", attrs);
pane.getDocument().insertString(0, "\n", null);
pane.getDocument().insertString(0, "This is third row bold", attrs);
pane.getDocument().insertString(0, "\n", null);
frame.add(pane);
frame.add(label, BorderLayout.SOUTH);
frame.setVisible(true);
}
private static class SelectionListener implements CaretListener{
@Override
public void caretUpdate(CaretEvent e) {
AttributeSet attrs =((StyledEditorKit)pane.getEditorKit()).getInputAttributes();
label.setText("Is bold: " + String.valueOf(StyleConstants.isBold(attrs)));
}
}}
我还有两个奖励问题。这种方法是用于选择还是仅用于插入符号的位置?还有什么 returns,如果有一个文本选择,其中一部分是粗体而第二部分不是?
其实选择属性是个复杂的问题,需要你了解业务需求。
假设选择了一段文本并且您需要选择字体大小。但 该片段有 3 段不同的文本,有 3 种不同的大小。
选择开始位置放在10pt文本的中间,然后一段12pt大小的文本和选择结束在14pt大小片段的中间。
您想要什么尺寸? 10、12、14 或(多个)?
最简单的方法是使用 inputAttributes。
默认情况下,属性是从插入符位置复制的,但当然您可以添加一个插入符侦听器,并在每次更新时根据您的业务逻辑检查并根据需要填充输入属性(处理具有不同属性的多个文本片段).
更新:
尝试将 AttributeSet attrs =((StyledEditorKit)pane.getEditorKit()).getInputAttributes();
包装在 SwingUtilities.invokeLater() 调用
获取选区的属性没有预期的行为,只是因为选区可以包含具有不同属性的字符元素。
您必须了解,getInputAttributes
returns textPane 为下一个输入计算的最佳属性与 getCharacterAttributes
returns 当前插入符位置的属性。在选择的情况下,插入符号是您结束选择的位置。如果您从左到右或从右到左选择文本,它可以是给定的 getSelectionStart
或 getSelectionEnd
。
无论如何,我建议您获取 JTextPane 的 StyledDocument,然后遍历从 getSelectionStart
到 getSelectionEnd
的字符元素:
for(int i=jtp.getSelectionStart(); i<jtp.getSelectionEnd(); i++) {
AttributeSet set = jtp.getStyledDocument().getCharacterElement(i).getAttributes();
//here, combine, analyse, do whatever you like with your AttributeSet
//You can use StyleConstants.xxx to analyse the attributes
}
我使用@Sharcoux 的解决方案并做了一处更改:我确保始终至少有一个字符可以迭代。当没有选择时,getSelectionStart() == getSelectionEnd()
。出于这个原因,我会稍微改变一下:
int iStart = jtp.getSelectionStart();
int iEnd = jtp.getSelectionEnd();
if(iStart > 0) iStart--;
else if(iEnd < jtp.getDocument().getEndPosition().getOffset()) iEnd++;
for(int i = iStart; i < iEnd; i++) {
AttributeSet set = jtp.getStyledDocument().getCharacterElement(i).getAttributes();
//here, combine, analyse, do whatever you like with your AttributeSet
//You can use StyleConstants.xxx to analyse the attributes
}
唯一没有改变的情况是文档完全为空时,在这种情况下 getInputAttributes
应该可以正常工作。