Új sor beszúrási probléma JEditorPane-ben

Fórumok

Sziasztok!

Van egy kis miniatűr progim, ami HTML-ben formázott szövegeket (sorokba rendezve) ír ki egy JEditorPane objektumba. (A progit lásd lent!) A problémám az, hogy az első és második sor között mindig kihagy plusz egy sort a szerkesztő. A többi sor esetén már jól viselkedik. Így kénytelen voltam kiegészíteni a programot egy extra törlési funkcióval, ami figyeli, hogy hányadik sort írom éppen, és ha a második következne, kitörlöm a felesleges extra üres sort.

Kérdéseim:
- Mitől lehet ez a jelenség?
- Hogyan lehet kiküszöbölni hivatalosan?
- Lehet, hogy operációs rendszer függő a dolog? (UBUNTU 8.04)


import java.awt.*;
import javax.swing.*;

public class HtmlFormating extends JFrame {
    String[] adat = new String[] {"Jóska", "Helló!", "Jancsi", "Szia!"};
    String uj_uzenet1 = "<b>" + adat[0] + "</b> üzenete: <font size=\"4\" face=\"Tahoma\" color=\"black\">" + adat[1] + "</font><br>";
    String uj_uzenet2 = "<b>" + adat[2] + "</b> üzenete: <font size=\"2\" face=\"Tahoma\" color=\"red\">" + adat[3] + "</font><br>";
    String uj_uzenet3 = "<b>" + adat[0] + "</b> üzenete: <font size=\"2\" face=\"Tahoma\" color=\"black\">" + adat[3] + "</font><br>";
    String uj_uzenet4 = "<b>" + adat[2] + "</b> üzenete: <font size=\"2\" face=\"Tahoma\" color=\"black\">" + adat[1] + "</font><br>";
    JEditorPane ep1 = new JEditorPane();
    JEditorPane ep2 = new JEditorPane();
    JScrollPane scrp;
    int line = 0;

    public HtmlFormating() {
        super("Html Formating Example");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setBounds(50, 50, 500, 500);
        getContentPane().add(scrp = new JScrollPane(ep1));
        
        ep1.setContentType("text/html");       
        ep2.setContentType("text/html");       
        writeText();
        setVisible(true);
    } // end of HtmlFormating()
    
    private int getLast(JEditorPane ep) {
        return ep.getDocument().getLength();
    }
    
    public void writeHtmlString(String s) {
        int i = getLast(ep1);
        ep2.setText(s);
        ep2.select(0, getLast(ep2));
        ep2.copy();
        ep1.paste();
        line = line + 1;
        
        // Ezt a törlési funkciót muszáj voltam beilleszteni
        if (line == 2  &&  i > 0) {
            ep1.select(i-1, i);
            ep1.cut();
        }
        // Itt a vége a törlésnek
        
        i = getLast(ep1);
        ep1.select(i, i);        
    }
    
    public void writeText() {
        writeHtmlString(uj_uzenet1);       
        writeHtmlString(uj_uzenet2);
        writeHtmlString(uj_uzenet3);
        writeHtmlString(uj_uzenet4);
        writeHtmlString(uj_uzenet1);       
        writeHtmlString(uj_uzenet2);
        writeHtmlString(uj_uzenet3);
        writeHtmlString(uj_uzenet4);
    } // end of writeText()
    
    public static void main(String[] args) {
        HtmlFormating st = new HtmlFormating();
    }
    
} // end of class

Hozzászólások

helló! egy lehetséges mo. ebből nem nehéz kitalálni, hogy miért kerül újsor az ep1-be.
...


	public void writeHtmlString(String s) {
		int i = getLast(ep1);
		ep2.setText(s);
		ep2.select(0, getLast(ep2)-1);
		ep2.copy();
		ep1.paste();
//		line = line + 1;

		// Ezt a törlési funkciót muszáj voltam beilleszteni
	        //	if (line == 2  &&  i > 0) {
		//		ep1.select(i-1, i);
		//		ep1.cut();
		//	}
		// Itt a vége a törlésnek

...

amikor először lefut a

writeHtmlString

akkor az

ep2

-ben a

setText

-el beállított szövegen kívül még egy újsor is ki lesz jelölve. ezután átmásolod ezt a szöveget az

ep1

-be és megjelenik a szövegen kívül az újsor is. a második lefutáskor viszont az

ep2

-ben a kijelölt szövegre állítasz a

setText

-el, vagyis felülírod az újsort is. ezután már a plusz újsor nélkül jelölöd és másolod a szöveget az

ep2

-ből. remélem jól tippelek :)

A te gondolatmeneted alapján próbálkoztam a konstruktor függvényben eliminálni a problémát, de nem jött össze.

Ugyanakkor egy érdekes jelenséget vettem észre. Ha csak egy sort íratok ki, akkor ha a kiírt sor végére megyek manuálisan, az utolsó karakter után eltűnik a kurzor. Ha visszaléptetek eggyel újra megjelenik. Ilyen eltűnési jelenség nem tapasztalható, két vagy több sor esetén!

Nem lehet, hogy valami bug ez inkább?

rosszul magyarázom mert nemcsak az első sor után került újsor a megoldásodba (vagy

<br>

?) hanem a többi után is. ezek vmiért nem jelennek meg mint az első sornál és itt a kurzor is eltűnik - beleveszik az újsorjelbe. a másik felén meg kijön. érdekes. mindenesetre ha a javított kódot használod - óvatosan ajánlom magam - amibe nincs belevéve az újsor másoláskor az normálisan működik nálam 1.5.0.15 jdk-val linux alatt.


import java.awt.*;
import javax.swing.*;

public class HtmlFormating extends JFrame {
	String[] adat = new String[] {"Jóska", "Helló!", "Jancsi", "Szia!"};
	String uj_uzenet1 = "<b>" + adat[0] + "</b> üzenete: <font size=\"4\" face=\"Tahoma\" color=\"black\">" + adat[1] + "</font><br>";
	String uj_uzenet2 = "<b>" + adat[2] + "</b> üzenete: <font size=\"2\" face=\"Tahoma\" color=\"red\">" + adat[3] + "</font><br>";
	String uj_uzenet3 = "<b>" + adat[0] + "</b> üzenete: <font size=\"2\" face=\"Tahoma\" color=\"black\">" + adat[3] + "</font><br>";
	String uj_uzenet4 = "<b>" + adat[2] + "</b> üzenete: <font size=\"2\" face=\"Tahoma\" color=\"black\">" + adat[1] + "</font><br>";
	JEditorPane ep1 = new JEditorPane();
	JEditorPane ep2 = new JEditorPane();

	public HtmlFormating() {
		super("Html Formating Example");
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setBounds(50, 50, 500, 500);
		getContentPane().add(new JScrollPane(ep1));
		ep1.setContentType("text/html");       
		ep2.setContentType("text/html");       
		writeText();
		setVisible(true);
	}   // end of HtmlFormating()

	private int getLast(JEditorPane ep) {
		return ep.getDocument().getLength();
	}

	public void writeHtmlString(String s) {
		ep2.setText(s);
		ep2.select(0, getLast(ep2)-1);
		ep2.copy();
		ep1.paste();
		ep1.setCaretPosition(getLast(ep1));
	}

	public void writeText() {
		writeHtmlString(uj_uzenet1);       
		writeHtmlString(uj_uzenet2);
		writeHtmlString(uj_uzenet3);
		writeHtmlString(uj_uzenet4);
		writeHtmlString(uj_uzenet1);       
		writeHtmlString(uj_uzenet2);
		writeHtmlString(uj_uzenet3);
		writeHtmlString(uj_uzenet4);
	} // end of writeText()

	public static void main(String[] args) {
		HtmlFormating st = new HtmlFormating();
	}
}

Korábban, amikor megköszöntem a segítséget, már jeleztem, hogy a "-1" megoldásod működik nálam is, de úgy érzem, itt valami nem stimmel. Ezért kértem a közösséget, hogy valaki nézze meg Windows alatt, hogyan működik az eredeti progi.

Még az is egy érdekes kérdés számomra, hogyha a te megoldásoddal nem másoljuk át az újsor jelet, akkor miért kerülnek mégis új sorba az egyes szövegek. Ilyenkor nem egymás után folytatólagosan kellene elhelyezkedniük?

ha elhagyod a -1-et és a

<br>

-eket, akkor is jól működik (lényegében u.a. a mo. mert nem az ep-k újsorait törölgettük hanem a

<br>

-eket). ez azt jelenti h. vmi bugos, mert nem értelmezi rendesen minden sorban a

<br>

-eket, csak az elsőbe. a második kérdés egyelőre nekem is rejtély.

Szerintem elsietted.

Jó pár dolog "fura" a kódban amit írtál..
.. miért használsz 2 editorpanel-t?
.. miért használsz copy() paste()-t?
.. miért editable módban van az editorpanel (szerintem itt lesz a kutya elásva, az új sorral)

Én az utóbbi kettő miatt simán lepattintanám a bug-reportodat, mivel HTML-ről van szó.

A program nem nekem kellett. Csak segítettem másnak. Valamiféle szerver-kliens programhoz kellett. A szerverről érkező adatokat kell megjeleníteni a kliens oldalon. Fontos, hogy formázható legyen a szöveg elsősorban HTML formátumban. A probléma az volt, hogy a HTML formátum és a formázhatóság miatt kénytelen volt JEditorPane-t használni, de mivel ebben nincs append() függvény a szöveg továbbfűzésére, ezért létrehozott egy listát a már beérkezett üzenetekről és ahhoz fűzte az új üzenetet, majd setText() függvénnyel felülírta a régi JEditorPane belsőt. Csakhogy így a kurzor az újra íráskor felugrik, majd le. Tehát nem a legesztétikusabban viselkedik. Fontos követelmény volt számára, hogy a kurzor mindig (az új szöveg beszúrásakor is) szépen maradjon a szöveg végén, és ne ugráljon. Az ugrálást maga a setText() használata okozza, hiszen hosszabb szöveg esetén már maga a kiírás is viszonylag hosszabb idő. Meg kellett tehát oldani, hogy az append()-hez hasonló viselkedést állítsunk elő. Tehát ne kelljen mindig a teljes szöveget újra írni. Ugyanakkor valamiért az is fontos volt számára, hogy a kurzor látszódjon.

Nos ezt valósítaná meg ez a program.
A háttérben lévő ep2 biztosítja, hogy a HTML formátumot rendesen meg tudjuk jeleníteni, ugyanakkor a copy/paste lehetővé teszi az append()-hez hasonló viselkedést.

Nem tudná valaki kipróbálni, mi a helyzet Windows esetén ezzel a programmal?

netről szedett megoldás (1 db JEditorPane) segítségével átírva is ugyanúgy hibásan jelennek meg a

<br>

-ek. az h. szerkeszthető-e vagy sem a pane, ezen nem változtat.


import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import java.io.StringReader;

public class HtmlFormating2 extends JFrame {
        String[] adat = new String[] {"Jóska", "Helló!", "Jancsi", "Szia!"};
        String uj_uzenet1 = "<b>" + adat[0] + "</b> üzenete: <font size=\"4\" face=\"Tahoma\" color=\"black\">" + adat[1] + "</font><br>";
        String uj_uzenet2 = "<b>" + adat[2] + "</b> üzenete: <font size=\"2\" face=\"Tahoma\" color=\"red\">" + adat[3] + "</font<br>";
        String uj_uzenet3 = "<b>" + adat[0] + "</b> üzenete: <font size=\"2\" face=\"Tahoma\" color=\"black\">" + adat[3] + "</font><br>";
        String uj_uzenet4 = "<b>" + adat[2] + "</b> üzenete: <font size=\"2\" face=\"Tahoma\" color=\"black\">" + adat[1] + "</font><br>";

        public HtmlFormating2() {
            super("Html Formating Example");
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setBounds(50, 50, 500, 500);
            JEditorPane ep1 = new JEditorPane();
            getContentPane().add(new JScrollPane(ep1));
            try {
                ep1.setContentType("html/text");
                ep1.setEditorKit(new HTMLEditorKit());
                //ep1.setEditable(false);
                append(ep1, uj_uzenet1);
                append(ep1, uj_uzenet2);
                append(ep1, uj_uzenet3);
                append(ep1, uj_uzenet4);
                append(ep1, uj_uzenet1);
                append(ep1, uj_uzenet2);
                append(ep1, uj_uzenet3);
                append(ep1, uj_uzenet4);
                setVisible(true);
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }

        public void append(JEditorPane ep, String str) {
            try {
                Document doc = (Document) ep.getDocument();
                ((HTMLEditorKit)ep.getEditorKit()).read(new StringReader(str), doc, doc.getLength());
                ep.setCaretPosition(doc.getLength());
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }

        public static void main(String[] args) {
            HtmlFormating2 st = new HtmlFormating2();
        }
}