まず第一に、それが問題ではないことを願っています 新しいトピックを開始しました。すでに回答された質問に基づいて質問する方法がわからないので、これを作成しました。
私はJavaにかなり慣れていませんが、私の問題は次のとおりです。私は小さなチャット プログラムを作成しており、 を使用してJEditorPane
テキストHTMLEditorKit
をさまざまな色で表示したり、スマイリーを表示したり、ハイパーリンクを表示したりしています。
私の問題は、いくつかの調査の結果、問題がJava7に起因する可能性があることが判明したため、ラインラップを適切に機能させることができないことです。テキストをワードラップし、コンポーネントの幅を超える文字列の途中でラップしたい。ワードラップは正常に機能しますが、誰かがかなり長い文字列を入力するJEditorPane
と展開され、フレームのサイズを変更してすべてを画面に表示する必要があります。これは私が起こりたくないことです.
この問題に対していくつかの修正を試みましたが、文字の折り返しのみが許可され、単語の折り返しが機能しなくなりました。それに加えて、ユーザーが Enter キーを押してテキストを折り返すことができるようにしたいと考えています。そのために、テキストに \n を追加しています。修正により、これは結果に影響を与えなくなり、すべてが 1 行で表示されるようになります。
解決策を見つけるために何年もウェブで過ごしたような気がしますが、特に常に同じ修正であるように見えたため、私の場合は何もうまくいきませんでした。皆さんが私を助けてくれることを願っています。
これは要約すると次のことを意味します。
私が持っているもの:
- スペースで区切られた長い文字列の場合、改行で単語が折り返されます
- Windows を使用していて、Enter キーを押すことによって作成された改行が入力に含まれている場合、それらも改行されます。
- スペースなしで非常に長い文字列を入力すると、パネルが展開され、フレームのサイズを変更する必要があります
- HTML フォーマットにより、ハイパーリンクや顔文字だけでなく、さまざまな色を表示できます
必要なもの:
- 可能な場合の現時点でのようなワードラップ動作ですが、パネルが拡張するのを防ぐためにスペースで区切られていない長い文字列の場合にのみレターラップが行われます。
- 入力領域で ENTER を押すか、事前に書式設定されたテキストを入力パネルにコピーした場合に手動で追加された改行
- 私がすでに持っているようなHTMLフォーマット
私が試したことと役に立たなかったもの:
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 を使用してプロジェクトに新しいクラスを作成し、例の HTMLEditorKit をこの CustomEditorKit に置き換えます。単語と文字の折り返しが機能するようになりましたが、Enter キーを押して独自の行折り返しを取得すると、この変更は出力パネルに表示されなくなり、すべてが 1 行に表示されます。もう 1 つの奇妙な問題は、フレームのサイズを変更すると、線が重なり合うことがあることです。
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;
}
};
}
}