我的字符串末尾的最终字符 '\n' 已被修改为 space 字符
final character '\n' at the end of my string has been modified to space character
我希望在 JTextField
中检索文本末尾的换行符,但是在将文本字段的文本设置为我的字符串后,它已被修改为 space特点。下面的代码突出了这个问题。
是否可以在文本字段中保留 \n
?
import javax.swing.JTextField;
public class StackOver {
public static void main(String[] args) {
String hasNewLineEscapeCharacter = makeStringWithNewLineCharacter();
JTextField backgroundText = new JTextField(90);
backgroundText.setText(hasNewLineEscapeCharacter);
char spaceChar = backgroundText.getText().charAt(backgroundText.getText().length()-1);
char newLineChar = hasNewLineEscapeCharacter.charAt(needsNewLineEscapeCharacter.length()-1);
}
public static String makeStringWithNewLineCharacter() {
String str = "hello,world!";
str += ('\n');
return str;
}
}
Is it possible to preserve the '\n' in my JTextField?
A JTextField
使用一个 PlainDocument
,其中包含一个 属性,过滤“\n”并将其替换为 space 字符。
要在文本字段中保留换行符,您可以尝试:
textField.getDocument().putProperty("filterNewlines", Boolean.FALSE);
但是,这会导致文本像文本区域一样分两行显示。
因此,按照上面的建议,您应该只使用 JTextArea。
无法在单行中显示包含换行符的文本。
您可能想要做的是在文本字符串中存储一些其他不可打印的字符,然后使用 String.replaceAll(...) 如果您需要访问添加回换行符的文本.
如果您希望 JTextField
在用户按下 [=] 时不仅 显示 ,而且 接受 换行符33=]输入键,还需要加一个ActionListener
。如果您继承 JTextField
(您可以使用 工厂方法 ),它可能看起来像这样:
public class JMultilineTextField extends JTextField {
public JMultilineTextField() {
addActionListener(e -> {
try {
final int selectionStart = getSelectionStart();
final int selectionEnd = getSelectionEnd();
final Document document = getDocument();
if (selectionStart != selectionEnd) {
document.remove(selectionStart, selectionEnd - selectionStart);
}
document.insertString(selectionStart, "\n", null);
} catch (final BadLocationException ble) {
// Unlikely to happen, but add your error handling code here.
ble.printStackTrace();
}
});
}
}
但这带来了另一个问题:您的 JTextField
会随着换行符的添加或删除而垂直增长或收缩,您需要父组件反映文本字段大小的变化并相应地布局其子组件(否则,您很可能最终会有重叠的 Swing 组件)。这个问题可以通过在文本字段的 Document
:
中安装 DocumentListener
来解决
public class JMultilineTextField extends JTextField {
// ...
@Override
public void setDocument(final Document doc) {
setupDocument(doc);
super.setDocument(doc);
}
private void setupDocument(final Document doc) {
doc.putProperty("filterNewlines", false);
installDocumentListenerIfNecessary(doc);
}
private void installDocumentListenerIfNecessary(final Document doc) {
final DocumentListener documentListeners[] = ((AbstractDocument) doc).getListeners(DocumentListener.class);
if (Stream.of(documentListeners).noneMatch(documentListener -> documentListener instanceof RowCountChangeListener)) {
doc.addDocumentListener(new RowCountChangeListener());
}
}
private final class RowCountChangeListener implements DocumentListener {
@Override
public void insertUpdate(final DocumentEvent e) {
revalidateParentIfNecessary();
}
@Override
public void removeUpdate(final DocumentEvent e) {
revalidateParentIfNecessary();
}
@Override
public void changedUpdate(final DocumentEvent e) {
revalidateParentIfNecessary();
}
private void revalidateParentIfNecessary() {
final JMultilineTextField textField = JMultilineTextField.this;
final Dimension currentSize = textField.getSize();
final Dimension preferredSize = textField.getPreferredSize();
/*
* Grow/shrink vertically as necessary.
*/
if (currentSize.height != preferredSize.height) {
textField.getParent().revalidate();
}
}
}
}
我还建议您从文本字段的构造函数中调用 setupDocument()
:
public class JMultilineTextField extends JTextField {
public JMultilineTextField() {
setupDocument(getDocument());
// add ActionListener, etc.
}
// ...
}
我希望在 JTextField
中检索文本末尾的换行符,但是在将文本字段的文本设置为我的字符串后,它已被修改为 space特点。下面的代码突出了这个问题。
是否可以在文本字段中保留 \n
?
import javax.swing.JTextField;
public class StackOver {
public static void main(String[] args) {
String hasNewLineEscapeCharacter = makeStringWithNewLineCharacter();
JTextField backgroundText = new JTextField(90);
backgroundText.setText(hasNewLineEscapeCharacter);
char spaceChar = backgroundText.getText().charAt(backgroundText.getText().length()-1);
char newLineChar = hasNewLineEscapeCharacter.charAt(needsNewLineEscapeCharacter.length()-1);
}
public static String makeStringWithNewLineCharacter() {
String str = "hello,world!";
str += ('\n');
return str;
}
}
Is it possible to preserve the '\n' in my JTextField?
A JTextField
使用一个 PlainDocument
,其中包含一个 属性,过滤“\n”并将其替换为 space 字符。
要在文本字段中保留换行符,您可以尝试:
textField.getDocument().putProperty("filterNewlines", Boolean.FALSE);
但是,这会导致文本像文本区域一样分两行显示。
因此,按照上面的建议,您应该只使用 JTextArea。
无法在单行中显示包含换行符的文本。
您可能想要做的是在文本字符串中存储一些其他不可打印的字符,然后使用 String.replaceAll(...) 如果您需要访问添加回换行符的文本.
如果您希望 JTextField
在用户按下 [=] 时不仅 显示 ,而且 接受 换行符33=]输入键,还需要加一个ActionListener
。如果您继承 JTextField
(您可以使用 工厂方法 ),它可能看起来像这样:
public class JMultilineTextField extends JTextField {
public JMultilineTextField() {
addActionListener(e -> {
try {
final int selectionStart = getSelectionStart();
final int selectionEnd = getSelectionEnd();
final Document document = getDocument();
if (selectionStart != selectionEnd) {
document.remove(selectionStart, selectionEnd - selectionStart);
}
document.insertString(selectionStart, "\n", null);
} catch (final BadLocationException ble) {
// Unlikely to happen, but add your error handling code here.
ble.printStackTrace();
}
});
}
}
但这带来了另一个问题:您的 JTextField
会随着换行符的添加或删除而垂直增长或收缩,您需要父组件反映文本字段大小的变化并相应地布局其子组件(否则,您很可能最终会有重叠的 Swing 组件)。这个问题可以通过在文本字段的 Document
:
DocumentListener
来解决
public class JMultilineTextField extends JTextField {
// ...
@Override
public void setDocument(final Document doc) {
setupDocument(doc);
super.setDocument(doc);
}
private void setupDocument(final Document doc) {
doc.putProperty("filterNewlines", false);
installDocumentListenerIfNecessary(doc);
}
private void installDocumentListenerIfNecessary(final Document doc) {
final DocumentListener documentListeners[] = ((AbstractDocument) doc).getListeners(DocumentListener.class);
if (Stream.of(documentListeners).noneMatch(documentListener -> documentListener instanceof RowCountChangeListener)) {
doc.addDocumentListener(new RowCountChangeListener());
}
}
private final class RowCountChangeListener implements DocumentListener {
@Override
public void insertUpdate(final DocumentEvent e) {
revalidateParentIfNecessary();
}
@Override
public void removeUpdate(final DocumentEvent e) {
revalidateParentIfNecessary();
}
@Override
public void changedUpdate(final DocumentEvent e) {
revalidateParentIfNecessary();
}
private void revalidateParentIfNecessary() {
final JMultilineTextField textField = JMultilineTextField.this;
final Dimension currentSize = textField.getSize();
final Dimension preferredSize = textField.getPreferredSize();
/*
* Grow/shrink vertically as necessary.
*/
if (currentSize.height != preferredSize.height) {
textField.getParent().revalidate();
}
}
}
}
我还建议您从文本字段的构造函数中调用 setupDocument()
:
public class JMultilineTextField extends JTextField {
public JMultilineTextField() {
setupDocument(getDocument());
// add ActionListener, etc.
}
// ...
}