首先,我希望新开一个话题不会成为问题。说实话,我不知道如何在已有回答的基础上提出问题,所以就创建了这个话题。
我对Java还比较陌生,我的问题如下。我正在编写一个简单的聊天程序,使用
我的问题是,在进行了一些研究后,我发现问题可能是由于Java7引起的,无法正确地使换行符正常工作。我希望文本自动换行,并且在超出组件宽度的字符串中间进行换行。 自动换行功能正常,但如果有人输入了一个相当长的字符串,则
我尝试了一些修复此问题的方法,但它们只允许字母换行,因此自动换行将不再起作用。此外,我希望用户可以通过按Enter键来换行。因此,我向文本添加了\n,而使用这些修复方法将不再影响结果,并且所有内容都将在一行中显示。
我感觉自己花了很多时间在网上寻找解决方案,但迄今为止还没有任何解决方法适用于我的情况,尤其是因为似乎一直都是相同的解决方案。我希望你们可以帮帮我。
总结一下:
现有情况:
- 在长字符串之间以空格分隔时,自动换行功能正常。 - 如果您使用Windows并且输入包含通过按Enter键创建的换行符,则该文本也会自动换行。 - 如果您输入一个没有空格的非常长的字符串,则面板会扩展,需要调整框架大小。 - HTML格式允许我显示不同的颜色、超链接和表情符号。
需要实现的内容:
- 在可能的情况下,仍然保持当前的自动换行行为,但仅在未使用空格分隔的长字符串中进行字母换行,以防止面板扩展。 - 在输入区域手动添加的换行符,或者如果我将预先格式化的文本复制到输入面板。 - 与我已经拥有的HTML格式相同。
我尝试过但没有效果的方法:
- jtextpane doesn't wrap text - JTextPane is not wrapping text 这里有一些代码可供尝试。在左下方有一个输入区域,可以输入一些文本。您也可以通过按Enter键添加换行符。单击按钮后,您将在上面的区域中看到文本。
我对Java还比较陌生,我的问题如下。我正在编写一个简单的聊天程序,使用
JEditorPane
和HTMLEditorKit
来显示不同颜色的文本,显示表情符号和超链接。我的问题是,在进行了一些研究后,我发现问题可能是由于Java7引起的,无法正确地使换行符正常工作。我希望文本自动换行,并且在超出组件宽度的字符串中间进行换行。 自动换行功能正常,但如果有人输入了一个相当长的字符串,则
JEditorPane
会被扩展,您需要调整框架大小才能将所有内容显示在屏幕上,我不想让这种情况发生。我尝试了一些修复此问题的方法,但它们只允许字母换行,因此自动换行将不再起作用。此外,我希望用户可以通过按Enter键来换行。因此,我向文本添加了\n,而使用这些修复方法将不再影响结果,并且所有内容都将在一行中显示。
我感觉自己花了很多时间在网上寻找解决方案,但迄今为止还没有任何解决方法适用于我的情况,尤其是因为似乎一直都是相同的解决方案。我希望你们可以帮帮我。
总结一下:
现有情况:
- 在长字符串之间以空格分隔时,自动换行功能正常。 - 如果您使用Windows并且输入包含通过按Enter键创建的换行符,则该文本也会自动换行。 - 如果您输入一个没有空格的非常长的字符串,则面板会扩展,需要调整框架大小。 - HTML格式允许我显示不同的颜色、超链接和表情符号。
需要实现的内容:
- 在可能的情况下,仍然保持当前的自动换行行为,但仅在未使用空格分隔的长字符串中进行字母换行,以防止面板扩展。 - 在输入区域手动添加的换行符,或者如果我将预先格式化的文本复制到输入面板。 - 与我已经拥有的HTML格式相同。
我尝试过但没有效果的方法:
- jtextpane doesn't wrap text - JTextPane is not wrapping text 这里有一些代码可供尝试。在左下方有一个输入区域,可以输入一些文本。您也可以通过按Enter键添加换行符。单击按钮后,您将在上面的区域中看到文本。
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.border.TitledBorder;
import javax.swing.text.BadLocationException;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;
@SuppressWarnings("serial")
public class LineWrapTest extends JFrame implements ActionListener, KeyListener {
private JButton btnSend;
private JTextArea textAreaIn;
private JEditorPane textAreaOut;
private HTMLEditorKit kit;
private HTMLDocument doc;
public LineWrapTest() {
this.setSize(600, 500);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setTitle("Linewrap Test");
}
/**
* Not important for problem
*/
public void paintScreen() {
this.setLayout(new BorderLayout());
this.add(this.getPanelOut(), BorderLayout.CENTER);
this.add(this.getPanelIn(), BorderLayout.SOUTH);
this.textAreaIn.requestFocusInWindow();
this.setVisible(true);
}
/**
* Not important for problem
*
* @return panelOut
*/
private JPanel getPanelOut() {
JPanel panelOut = new JPanel();
panelOut.setLayout(new BorderLayout());
this.textAreaOut = new JEditorPane();
this.textAreaOut.setEditable(false);
this.textAreaOut.setContentType("text/html");
this.kit = new HTMLEditorKit();
this.doc = new HTMLDocument();
StyleSheet styleSheet = this.kit.getStyleSheet();
this.kit.setStyleSheet(styleSheet);
this.textAreaOut.setEditorKit(this.kit);
this.textAreaOut.setDocument(this.doc);
TitledBorder border = BorderFactory.createTitledBorder("Output");
border.setTitleJustification(TitledBorder.CENTER);
panelOut.setBorder(border);
panelOut.add(this.textAreaOut);
return panelOut;
}
/**
* Not important for problem
*
* @return panelIn
*/
private JPanel getPanelIn() {
JPanel panelIn = new JPanel();
panelIn.setLayout(new BorderLayout());
this.textAreaIn = new JTextArea();
this.textAreaIn.setLineWrap(true);
this.textAreaIn.setWrapStyleWord(true);
TitledBorder border = BorderFactory.createTitledBorder("Input");
border.setTitleJustification(TitledBorder.CENTER);
panelIn.setBorder(border);
panelIn.add(this.getBtnSend(), BorderLayout.EAST);
panelIn.add(this.textAreaIn, BorderLayout.CENTER);
return panelIn;
}
/**
* Not important for problem
*
* @return btnSend
*/
private JButton getBtnSend() {
this.btnSend = new JButton("Send");
this.btnSend.addActionListener(this);
return this.btnSend;
}
private void append(String text) {
try {
this.kit.insertHTML(this.doc, this.doc.getLength(), text, 0, 0, null);
} catch (BadLocationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private String getHTMLText() {
String txtIn = this.textAreaIn.getText().trim().replaceAll(SEPARATOR, "<br/>");
StringBuffer htmlBuilder = new StringBuffer();
htmlBuilder.append("<HTML>");
htmlBuilder.append(txtIn);
htmlBuilder.append("</HTML>");
return htmlBuilder.toString();
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == this.btnSend) {
this.append(this.getHTMLText());
this.textAreaIn.setText("");
this.textAreaIn.requestFocusInWindow();
}
}
public static void main(String[] args) {
LineWrapTest test = new LineWrapTest();
test.paintScreen();
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER)
if (!this.textAreaIn.getText().trim().isEmpty())
this.textAreaIn.setText(this.textAreaIn.getText() + SEPARATOR);
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
}
更新: 基于 http://java-sl.com/tip_java7_text_wrapping_bug_fix.html 的部分内容。
我成功地离我的目标更近了一步。我试图将 HTMLEditorKit 的修复和 StlyedEditorKit 的修复结合起来。但说实话,我并不知道我到底做了什么 :( 不幸的是,这个替代 HTMLEditorKit 的修复会导致手动换行不再起作用。 也许你可以以此为基础进行更好的实现。
要在我的示例中使用它,只需在项目中创建一个新类,使用 CustomEditorKit,并将 HTMLEditorKit 替换为该 CustomEditorKit。 您会发现单词换行和字母换行现在都可以工作了,但是如果您按 ENTER 进行自己的换行,则此更改将不再出现在输出面板中,并且所有内容都将显示在一行中。 另一个奇怪的问题是,如果调整窗口大小,有时线条会相互覆盖。
import javax.swing.SizeRequirements;
import javax.swing.text.Element;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.InlineView;
import javax.swing.text.html.ParagraphView;
@SuppressWarnings("serial")
public class CustomEditorKit extends HTMLEditorKit {
@Override
public ViewFactory getViewFactory() {
return new HTMLFactory() {
@Override
public View create(Element e) {
View v = super.create(e);
if (v instanceof InlineView) {
return new InlineView(e) {
@Override
public int getBreakWeight(int axis, float pos, float len) {
return GoodBreakWeight;
}
@Override
public View breakView(int axis, int p0, float pos, float len) {
if (axis == View.X_AXIS) {
this.checkPainter();
this.removeUpdate(null, null, null);
}
return super.breakView(axis, p0, pos, len);
}
};
}
else if (v instanceof ParagraphView) {
return new ParagraphView(e) {
@Override
protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) {
if (r == null) {
r = new SizeRequirements();
}
float pref = this.layoutPool.getPreferredSpan(axis);
float min = this.layoutPool.getMinimumSpan(axis);
// Don't include insets, Box.getXXXSpan will include them.
r.minimum = (int) min;
r.preferred = Math.max(r.minimum, (int) pref);
r.maximum = Integer.MAX_VALUE;
r.alignment = 0.5f;
return r;
}
};
}
return v;
}
};
}
}