Линейная оболочка JEditorPane в Java7

Прежде всего, я надеюсь, что этоне проблема, я начал новую тему. Я неПонятия не имею, как задать вопрос, основанный на уже отвеченном вопросе, поэтому я сделал это.

Я довольно новый с Java, и моя проблема заключается в следующем. Я'я пишу небольшую программу чата, и ям, используяJEditorPane сHTMLEditorKit отображать текст разными цветами, отображать смайлики и гиперссылки.

Моя проблема в том, что после некоторых исследований я обнаружил, что проблема может быть связана с Java7, я могуТкань работает правильно. Я хочу, чтобы текст переносился по словам и переносился по середине строк, превышающих ширину компонента. Обтекание словом работает хорошо, но если кто-то набирает довольно длинную строку,JEditorPane расширяется, и вам нужно изменить размер кадра, чтобы все отображалось на экране, чего я не хочу делать.

Мы попробовали несколько исправлений этой проблемы, но они разрешают перенос букв только таким образом, что перенос слов больше не работает. Кроме того, я хочу, чтобы пользователь мог обернуть свой текст, нажав Enter. За что яЕсли добавить текст и исправить, это больше не повлияет на результат и все остальное »будет отображаться в одной строке.

я чувствую, что яМы потратили годы в Интернете, чтобы найти решение, но сейчас у меня ничего не вышло, особенно потому, что все это время казалось одинаковым. Я надеюсь, что вы, ребята, можете мне помочь.

В итоге это означает:

Что я имею:

Строка переносит слово в случае длинных строк, разделенных пробеламиЕсли вы используете Windows, и ваш ввод содержит переносы строк, созданные нажатием Enter, они также переносятсяЕсли вы введете очень длинную строку без пробелов, панель раскроется, и вам нужно изменить размер фреймаФорматирование HTML позволяет отображать различные цвета, а также гиперссылки и смайлики.

Что мне нужно:

Поведение переноса слов, как сейчас, в случае, если это возможно, перенос букв только в случае длинных строк, не разделенных пробелами, чтобы предотвратить расширение панели.Вручную добавили переносы строк, нажав клавишу ВВОД в области ввода или если я скопировал предварительно отформатированный текст на панель вводаФорматирование 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("");
    htmlBuilder.append(txtIn);
    htmlBuilder.append("");

    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;
        }
    };
    }
}

Ответы на вопрос(2)

Ваш ответ на вопрос