首先,我希望这不是问题,所以我开始了一个新话题。我不知道如何根据已经回答的问题提出问题,所以我做到了。
我对Java很陌生,以下是我的问题。我正在编写一个小型聊天程序,并且使用JEditorPane
带有的HTMLEditorKit
来显示不同颜色的文本,显示笑脸和显示超链接。
我的问题是,经过一些研究,我发现问题可能是由于Java7造成的,我无法使换行器正常工作。我希望文本自动换行,并包裹在超出组件宽度的字符串中间。自动换行可以很好地工作,但是如果有人输入一个很长的字符串,它JEditorPane
会被扩展,并且您需要调整框架的大小以将所有内容显示在屏幕上,这是我不想发生的事情。
我已经尝试了一些解决此问题的方法,但是它们只允许换行,这样换行就不再起作用了。除此之外,我希望用户能够通过按Enter键来包装其文本。为此,我要在文本中添加\
n并进行修复,这将不再影响结果,并且所有内容都将显示在一行中。
我感觉自己已经花了很多年时间在网络上寻找解决方案,但是unitl现在对我的情况无济于事,特别是因为它似乎一直都是相同的解决方案。我希望你们能帮助我。
总之,这意味着:
我有的:
我需要的:
我尝试过的和没有帮助的:
jtextpane不换行,
JTextPane不换行
这是一些代码,您可以自己尝试。左下方是一个输入区域,用于输入一些文本。您还可以通过按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在项目中创建一个新类,然后使用此CustomEditorKit替换示例中的HTMLEditorKit。您会注意到单词和字母换行现在可以使用,但是如果您按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;
}
};
}
}
好!因此,我终于得到了您工作中遇到的所有问题。经过了一些研究和大量的反复试验,但是这里是:
这是我所做的:
所以这是代码。它有点长,您可能希望根据自己的喜好进行更改。我评论了所做的更改,并试图解释它们。
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.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.SizeRequirements;
import javax.swing.border.TitledBorder;
import javax.swing.text.*;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.InlineView;
import javax.swing.text.html.StyleSheet;
@SuppressWarnings("serial")
public class LineWrapTest extends JFrame implements ActionListener, KeyListener {
//This is the separator.
private String SEPARATOR = System.getProperty("line.separator");
private JButton btnSend;
private JTextArea textAreaIn;
private JEditorPane textAreaOut;
private JScrollPane outputScrollPane;
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");
//I added this scroll pane.
this.outputScrollPane = new JScrollPane(this.textAreaOut);
/*
* This is a whole whack of code. It's a combination of two sources.
* It achieves the wrapping you desire: by word and longgg strings
* It is a custom addition to HTMLEditorKit
*/
this.kit = new HTMLEditorKit(){
@Override
public ViewFactory getViewFactory(){
return new HTMLFactory(){
public View create(Element e){
View v = super.create(e);
if(v instanceof InlineView){
return new InlineView(e){
public int getBreakWeight(int axis, float pos, float len) {
//return GoodBreakWeight;
if (axis == View.X_AXIS) {
checkPainter();
int p0 = getStartOffset();
int p1 = getGlyphPainter().getBoundedPosition(this, p0, pos, len);
if (p1 == p0) {
// can't even fit a single character
return View.BadBreakWeight;
}
try {
//if the view contains line break char return forced break
if (getDocument().getText(p0, p1 - p0).indexOf(SEPARATOR) >= 0) {
return View.ForcedBreakWeight;
}
}
catch (BadLocationException ex) {
//should never happen
}
}
return super.getBreakWeight(axis, pos, len);
}
public View breakView(int axis, int p0, float pos, float len) {
if (axis == View.X_AXIS) {
checkPainter();
int p1 = getGlyphPainter().getBoundedPosition(this, p0, pos, len);
try {
//if the view contains line break char break the view
int index = getDocument().getText(p0, p1 - p0).indexOf(SEPARATOR);
if (index >= 0) {
GlyphView v = (GlyphView) createFragment(p0, p0 + index + 1);
return v;
}
}
catch (BadLocationException ex) {
//should never happen
}
}
return super.breakView(axis, p0, pos, len);
}
};
}
else if (v instanceof ParagraphView) {
return new ParagraphView(e) {
protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) {
if (r == null) {
r = new SizeRequirements();
}
float pref = layoutPool.getPreferredSpan(axis);
float min = 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;
}
};
}
};
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);
//I changed this to add the scrollpane, which now contains
//the JEditorPane
panelOut.add(this.outputScrollPane);
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);
//This disables enter from going to a new line. Your key listener does that.
this.textAreaIn.getInputMap().put(KeyStroke.getKeyStroke("ENTER"), "none");
//For the key listener to work, it needs to be added to the component
this.textAreaIn.addKeyListener(this);
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() {
//I tried to find a work around for this but I couldn't. It could be done
//by manipulating the HTMLDocument but it's beyond me. Notice I changed
//<br/> to <p/>. For some reason, <br/> no longer went to the next line
//when I added the custom wrap. <p/> seems to work though.
String txtIn = this.textAreaIn.getText().trim().replaceAll(SEPARATOR, "<p/>");
//My IDE recommends you use StringBuilder instead, that's up to you.
//I am not sure what the difference would be.
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()) {
//I made this work by defining the SEPARATOR.
//You could use append(Separator) instead if you want.
this.textAreaIn.setText(this.textAreaIn.getText() + SEPARATOR);
}
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
}
这里是(大多数)我用来解决此问题的链接:
使用HTMLDocument在JTextPane中启用自动换行
自定义换行是以下两者的组合:
http://java-sl.com/tip_html_letter_wrap.html
http://java-sl.com/wrap.html
删除JTextArea的keybind:
http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html
如果您有任何疑问,请在下面评论。 我会回答他们。我衷心希望这能解决您的问题
主要内容:1 Java JEditorPane的介绍,2 Java JEditorPane的内部类,3 Java JEditorPane的字段,4 Java JEditorPane的构造方法,5 Java JEditorPane的方法,6 Java JEditorPane的案例1,7 Java JEditorPane的案例21 Java JEditorPane的介绍 JEditorPane类用于创建一个简单的文本编辑器窗口。此类具有setContentType() 和setText() 方法
问题内容: 我已经成功使用httpclient成功登录到站点,并打印出启用该登录的cookie。但是,我现在陷入困境,因为我想使用.setPage(url)函数在JEditorPane中显示后续页面。但是,当我这样做并使用Wireshark分析我的GET请求时,我看到用户代理不是我的httpclient而是以下内容: 用户代理:Java / 1.6.0_17 GET请求(在侧面jeditorpan
问题内容: 我正在尝试为项目创建一个简单的Web浏览器,但是我正在使用JEditorPane呈现和显示HTML。我听说不应将JEditorPane用作浏览器组件,因为它不支持HTML3.2之上的任何功能(即使那样也无法正确显示它),但是我似乎找不到HTML5的替代方法。谁能帮我?提前致谢。 问题答案: 您可以使用JavaFX-2 Webview。从JavaFX-2 Adding HTML Cont
问题内容: 我正在开发一个Swing应用程序,其中必须显示HTML文件。 我正在为此使用控件。它显示的是HTML文件的内容,但格式与实际HTML文件中的原始格式不同。 不支持该元素。与其加载目标文件,不如显示它。 Swing中是否还有其他内置控件来浏览HTML文件而不是? 我正在使用以下代码: 问题答案: 在核心Java中进行更高级的HTML呈现的最佳选择是使用基于JavaFX的组件,如向Java
问题内容: 我在JScrollPane中有一个JeditorPane。在应用程序中的某些点,我想检索在scrollPane中可见的文本(当前正在显示的文本)以及仅此文本。有没有办法做到这一点? 谢谢, 艾略特 问题答案: 您可以使用视口来获取视图的位置和大小。 一旦知道了视口的起点/终点,就可以使用: 一旦知道了文本的偏移量,就可以从组件中获取文本: 没有代码经过测试。
问题内容: 我正在尝试在Java JEditorPane中显示嵌入式图像。下面的代码使用HTML内容,这些内容可以在Firefox中正确显示图像,但不能在JEditorPane中显示图像。有什么想法吗?谢谢。 问题答案: 您需要为“数据:”添加协议处理程序,以便可以为其打开URL / URLConnection。或者,您可以为类路径资源创建一些协议处理程序“ resource:”。 您需要一个带有