JEditorPane linewrap w Javie7

Przede wszystkim mam nadzieję, że to nie problem, zacząłem nowy temat. Tbh Nie mam pojęcia, jak zadać pytanie na podstawie odpowiedzi, więc zrobiłem to.

Jestem całkiem nowy w Javie i mój problem jest następujący. Piszę mały program do czatu i używamJEditorPane zHTMLEditorKit wyświetlać tekst w różnych kolorach, wyświetlać emotikony i wyświetlać hiperłącza.

Moim problemem jest to, że po kilku badaniach, które odkryłem, problem może być spowodowany przez Java7, nie mogę sprawić, by linka działała poprawnie. Chcę, aby tekst zawinął się w słowo i zawinął w środku Ciągów przekraczających szerokość komponentu. Zawijanie słów działa dobrze, ale jeśli ktoś wpisze dość długi ciąg znakówJEditorPane zostaje rozbudowany i musisz zmienić rozmiar ramki, aby uzyskać wszystko na ekranie, a tego nie chcę robić.

Spróbowałem kilku poprawek tego problemu, ale zezwalają one tylko na zawijanie liter, tak że zawijanie słów już nie działa. Poza tym chcę, aby użytkownik mógł zawinąć swój tekst, naciskając klawisz Enter. W tym celu dodam n do tekstu iz poprawkami nie będzie to miało wpływu na wynik i wszystko będzie wyświetlane w jednym wierszu.

Czuję, że spędziłem wiele lat w sieci, aby znaleźć rozwiązanie, ale teraz w moim przypadku nic nie działało, zwłaszcza, że ​​wydawało się, że jest to ta sama poprawka przez cały czas. Mam nadzieję, że możecie mi pomóc.

Oznacza to w skrócie:

Co ja mam:

Słowo zawija wiersz w przypadku długich ciągów oddzielonych spacjamijeśli używasz systemu Windows, a dane wejściowe zawierają zawijanie linii utworzone przez naciśnięcie klawisza Enter, będą one również zawijaneJeśli wpiszesz bardzo długi łańcuch bez spacji, panel zostanie rozwinięty i musisz zmienić rozmiar ramkiFormatowanie HTML pozwala mi wyświetlać różne kolory, a także hiperłącza i emotikony

Czego potrzebuję:

Zachowanie typu „zawijanie słów” jest takie, jak w przypadku, gdy jest to możliwe, ale zawijanie tylko TYLKO w przypadku długich ciągów znaków nie oddzielonych spacjami, aby zapobiec rozszerzeniu panelu.Ręcznie dodane zawijanie linii wykonane przez naciśnięcie ENTER w polu wprowadzania lub jeśli skopiuję wstępnie sformatowany tekst do panelu wejściowegoFormatowanie HTML, jak już mam

Co próbowałem i co nie pomogło:

jtextpane nie zawija tekstu iJTextPane nie zawiera tekstu

Oto kod do samodzielnego wypróbowania. W lewym dolnym rogu znajduje się obszar wprowadzania tekstu. Możesz również dodawać zawijanie linii, naciskając enter. Po kliknięciu przycisku zobaczysz tekst w powyższym obszarze.

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) {
}
}

AKTUALIZACJA: bazować na niektórych częściachhttp://java-sl.com/tip_java7_text_wrapping_bug_fix.html

Jakoś to sobie wyobraziłem, żeby zbliżyć się do celu. Próbowałem połączyć poprawkę dla HTMLEditorKit z poprawką StlyedEditorKit. Ale muszę być szczery, nie mam pojęcia, co właściwie tam zrobiłem :( Smutne jest to, że ręczne zawijanie linii nie działa już z tym jako zamiennik HTMLEditorKit. Może możesz użyć tego jako baza dla lepszego wdrożenia.

Aby go użyć w moim przykładzie, wystarczy utworzyć nową klasę w projekcie za pomocą CustomEditorKit i zastąpić HTMLEditorKit w przykładzie tym CustomEditorKit. Zauważysz, że zawijanie słów i liter działa teraz, ale jeśli naciśniesz ENTER, aby uzyskać własne zawijanie linii, zmiana ta nie będzie już widoczna na panelu wyjściowym i wszystko będzie wyświetlane w jednym wierszu. Innym dziwnym problemem jest to, że jeśli zmienisz rozmiar ramki, linie będą czasem leżały na sobie.

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

questionAnswers(2)

yourAnswerToTheQuestion