Zum Inhalt springen

JEditorPane und <fieldset>


Empfohlene Beiträge

Geschrieben

Morgen,

kennt von euch jemand eine Möglichkeit im JEditorPane übergansweise, bis Swing es unterstützt, den fieldsetTag einzubinden...

fertige freie Lösungen, und/oder

codeSchnipsel, und

denkanstöße willkommen.

Mein Freund google liefert zwar einen Treffer mit dem HTMLKit, aus den sun Foren, nur leider funktioniert, trotz dem Workarround zur Fehlerbehebung der Code bei mir nicht.

Meine erste Idee war es einfach zu gucken, ob im Text ein <fieldset> vorkommt, "<fieldset>Textblahblah</fieldset>" das zu löschen, eine paint methode aufzurufen die an die betreffende Stelle ein Rectangle zeichnet und darinnen den Text.

Probleme bei der Methode wären:

a) Geschwindigkeit

Text wird durchsucht (ich denke zum zweiten mal, da um die Standard Tags zu erstellen der text auch schon druchsucht worden ist)

B) Positionierung

b.1) die genaue Position des Rectangles herauszubekommen, da sie abhängig is von Breite, Buchstabengröße etc.

b.2) die Größe des Rectangles müsste sich je nach Textinhalt richten, mit den Oben genannten Formationsproblemem

c) Formatierung

es müsste für sämtliche borderstyles und ähnliches eine neue Methode geschrieben werden...

Vielleicht fällt von euch jemandem eine andere Möglichkeit ein, ich würde sogar pfuschen und das fieldset mit anderen html-tags darstellen wenn möglich...

Grüße

madbat

Geschrieben

du willst einfach nur einen Rahmen um den text in <fieldset> ?

dann ersetze doch einfach <fieldset> durch <div style="border: 1px solid black;">

und </fieldset> durch </div>

oder wie meinst du das?

Geschrieben

genauso meine ich das, nur muss ich jetzt noch was für den legend Befehl haben, also die Überschrift, aber ich denke mal das sollte auch möglich sein.

Kenne mich mit html tags leider nicht mehr so gut aus wie früher, da ich sie schon lange nicht mehr intensiv gebraucht habe.

so wie du geraten hast klappt es leider auch nicht, der HTMLParser ist echt bescheiden, naja habe jetzt einfach mal

<p style=\"border-width:thin; border-style:solid; \">content</p>

genommen, dass funktioniert, nur muss ich jetzt noch den <legend> befehl emulieren, sprich die Überschrift, jemand ne Idee?

Grüße,

madbat

Geschrieben

So ich hab mal ein bisschen im Netz gesucht und hab es tatsächlich geschafft einen neuen Tag hinzuzufügen:

Fieldset Layout:


/*
* Fieldset.java
*
* Created on 09.03.2010, 11:36:34
*/

package entwicklung;

/**
*
* @author madbat
*/
public class Fieldset extends javax.swing.JPanel {

/** Creates new form Fieldset */
public Fieldset(String content) {
this(content, "");
}
public Fieldset(String content, String headLine) {
initComponents();
this.content.setText(content);
this.headline.setText(headLine);
}

/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

headline = new javax.swing.JLabel();
jPanel1 = new javax.swing.JPanel();
content = new javax.swing.JLabel();

org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(entwicklung.EntwicklungApp.class).getContext().getResourceMap(Fieldset.class);
setBackground(resourceMap.getColor("Form.background")); // NOI18N
setName("Form"); // NOI18N
setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

headline.setBackground(resourceMap.getColor("headline.background")); // NOI18N
headline.setText(resourceMap.getString("headline.text")); // NOI18N
headline.setFocusable(false);
headline.setName("headline"); // NOI18N
headline.setOpaque(true);
add(headline, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 0, -1, -1));

jPanel1.setBackground(resourceMap.getColor("jPanel1.background")); // NOI18N
jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jPanel1.setName("jPanel1"); // NOI18N

content.setText(resourceMap.getString("content.text")); // NOI18N
content.setName("content"); // NOI18N

javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addComponent(content)
.addContainerGap(324, Short.MAX_VALUE))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addComponent(content)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);

add(jPanel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 7, 370, 30));
}// </editor-fold>


// Variables declaration - do not modify
private javax.swing.JLabel content;
private javax.swing.JLabel headline;
private javax.swing.JPanel jPanel1;
// End of variables declaration

}

[/PHP]

HTML-Tag-Erweiterung:

[PHP]public class ownHTML extends HTML {
public static class ownHTMLTag extends Tag{
protected ownHTMLTag(String id){
super(id);
}
protected ownHTMLTag(String id,boolean causesbreak,boolean isblock){
super(id,causesbreak,isblock);
}

public static final Tag fieldset=new UnknownTag("fieldset");

}


}

HTML-EditorKit mit neuem Tag enthalten:

public class MyEditorKit extends HTMLEditorKit {

@Override
public ViewFactory getViewFactory() {
return new OwnHTMLFactory();
}

public static class OwnHTMLFactory extends HTMLEditorKit.HTMLFactory implements ViewFactory{


@Override
public View create(Element ele){
Object attr = ele.getAttributes().getAttribute(StyleConstants.NameAttribute);
if (attr instanceof ownHTML.ownHTMLTag | attr instanceof HTML.Tag){
//Start processing for the custom tag
if(ele.getName().equals("fieldset")){
return new ComponentView(ele){
@Override
protected Component createComponent(){
String content = "content\nline1\nline2";
String headline = "headline";
Fieldset field = new Fieldset(content, headline);
return field;
}
};
}else
{
return super.create(ele);
}

}else{
return null;
}
}
}[/PHP]

Eigene Browser Komponente:

[PHP]public class OwnBrowserPane extends JEditorPane {

EditorKit kit = new MyEditorKit();

public OwnBrowserPane() {
this.setEditorKit(kit);
}
}

rufe ich jetzt

 @Action
public void ddd() {
String text="<fieldset>test</fieldset>";
ownBrowserPane.setText(text);
}[/PHP]

auf erhalte ich den Output folgendermaßen:

[PHP]test<fieldset><legend>headline</legend>content</fieldset>

Wenn mir einer sagen kann, wie ich es schaffe den Text zwischen den Tags zu erhalten wäre mein Problem gelöst (:

Geschrieben

Ich habe mich auch mal in das Problem/Thema eingelesen und mal die Quelltexte der Standard Javaklassen zu dem Thema angeschaut, und ich denke das was du da gefunden hast, ist zwar schon ein guter Ansatz, wird das Problem aber noch nicht vollständig lösen.

Das Problem ist einfach, dass der Parser den HTML-Tag '<fieldset>' nicht kennt, dadurch werden diese Tags zur Weiterverarbeitung als SimpleTags weitergegeben, wodurch er einmal den Start-Tag anliefert, und unabhängig davon den End-Tag. Wodurch, jedenfalls ist das zurzeit meine Vermutung, die Formularfelder innerhalb des Fieldsets im HTMLDocument nicht als Kindelemente des Fieldsets eingetragen werden, sondern auf einer Ebene mit dem Fieldset, wodurch die gesamte Darstellung im JEditorPane nicht passt.

Zurzeit denke ich, wenn man das wirklich sauber lösen will, muss man bis runter zum Parser die Klassen überschreiben damit der Parser eine eigene DTD und HTML Klasse benutzt.

Ob das aber wirklich alles ist, oder es vielleicht doch noch eine leichtere Methode gibt, weiß ich zurzeit noch nicht.

Eine Interessante Lektüre dazu ist aber folgendes PDF:

http://examples.oreilly.com/jswing2/code/goodies/HtmlEdKit.pdf

Geschrieben (bearbeitet)

Sooo, ich hätte dann ne Lösung für dich. Binde einfach folgendes *.jar Archiv bei dir ein, und dir dürften im JEditorPane auch 'fieldsets' angezeigt werden. Falls du nach der nachfolgenden Erklärung noch mehr darüber wissen willst, sind in dem *.jar Archiv auch die Quelltexte der Klassen enthalten.

Link zum *.jar Archiv.

In dem Archiv sind 4 Quelltextdateien vorhanden:

  • XDTD.java
  • XHTMLDocument.java
  • XHTMLEditorKit.java
  • XParserDelegator.java

(Das XHTML soll jetzt nicht heißen, dass damit der gesamte XHTML Standard unterstützt wird, das X war einfach nur nen Platzhalter für meine eigenen Klassen ;) )

Um dein JEditorPanel dazu zu bringen 'fieldset's anzeigen zu können musst du einfach nur ein neues Objekt vom XHTMLEditorKit erzeugen und dieses als EditorKit dem JEditorPanel zuweisen.

Das bewirkt dann im einzelnen, dass das Panel nicht mehr auf einem HTMLDocument aufbaut, sondern auf dem XHTMLDocument. In diesem sind zum einem die beiden HTML-Tags 'fieldset' und 'legend' als Klassen vom Typ HTML.Tag definiert. Außerdem wird intern die HTMLReader Klasse überschrieben, damit diese beiden Tags auch richtig behandelt werden. Das geschieht in dem den beiden Tags jeweils eine BlockAction zugewiesen wird, dadurch wird im Document jeweils ein neuer Block erstellt, wenn die Tags gefunden werden.

Das XHTMLDocument gibt diesen Reader über die getReader() Methode zurück.

Dieses Document wird vom XHTMLEditorKit erzeugt und an das Panel übergeben, wenn ein neuens HTML-Dokument geladen wird. Außerdem wird im XHTMLEditorKit noch die Parser Klasser überschrieben. Bei jeder Anfrage nach dem Parser durch das Panel wird vom XParseDelegator ein neues Objekt vom Typ DocumentParser zurück gegeben. Diesem wird bei der Erzeugung eine eigene Instanz der DTD Klasse übergeben, diese heißt XDTD. Mit dieser wird bewerkstelligt, dass die Tags 'fieldset' und 'legend' in die DTD aufgenommen werden und auch in allen Tags erlaubt sind. Dadurch funktioniert das gesamte Zusammenspiel mit den Standardkomponenten erst richtig.

Um diese beiden Tags dann auch noch richtig anzeigen zu können, ist die HTMLFactory im XHTMLEditorKit auch nochmals überschrieben, damit das 'legend' Tag garnicht und das 'fieldset' Tag mit einem TitledBorder und dem Text aus dem 'legend' Tags als Überschrift angezeigt wird.

Ich habe das ganze jetzt nicht all zu anspruchsvoll getestet, aber eigentlich dürfte es soweit funktionieren. Falls es noch Fragen gibt, bin ich hier im Forum, per PN oder ICQ zu erreichen ;)

Als Anhang auch nochmal die Quelltexte, falls diese in ein paar Jahren mal jemand braucht, wenn das *jar Archiv vielleicht nicht mehr online zu erreichen ist:

XDTD:


package de.tnteam.dragon.html;

import java.io.*;

import java.util.BitSet;


import javax.swing.text.html.parser.*;


public class XDTD extends DTD {


	protected XDTD(String name) {

		super(name);

	}


	@Override

	public Element defineElement(String name, int type, boolean omitStart,

			boolean omitEnd, ContentModel content, BitSet exclusions,

			BitSet inclusions, AttributeList atts) {


		if ( content != null && !ignoreElements(name) ) {

			ContentModel c = content;

			ContentModel p = content;

			for ( ; !(c.content instanceof Element); p = c, c = (ContentModel) c.content )

				;


			if ( "fieldset".equals(name) ) {

				p.content = defContentModel(0, getElement("legend"), c);

			} else {

				p.content = defContentModel(0, getElement("fieldset"), c);

			}

		}


		return super.defineElement(name, type, omitStart, omitEnd, content,

				exclusions, inclusions, atts);

	}


	protected boolean ignoreElements(String name) {

		return ("html".equals(name) || "head".equals(name)

				|| "title".equals(name) || "legend".equals(name));

	}


	@Override

	public void read(DataInputStream in) throws IOException {

		super.read(in);

		Element div = getElement("div");

		Element h1 = getElement("h1");

		defineElement("fieldset", div.getType(), false, false,

				div.getContent(), null, null, div.getAttributes());

		defineElement("legend", h1.getType(), false, false, h1.getContent(),

				null, null, h1.getAttributes());

	}


}


XHTMLDocument:

package de.tnteam.dragon.html;

import java.net.URL;


import javax.swing.text.Document;

import javax.swing.text.html.*;


public class XHTMLDocument extends HTMLDocument {


	public static final HTML.Tag FIELDSET = new HTML.UnknownTag("fieldset");

	public static final HTML.Tag LEGEND = new HTML.UnknownTag("legend");


	public XHTMLDocument(StyleSheet styles) {

		super(styles);

	}


	public HTMLEditorKit.ParserCallback getReader(int pos) {

		Object desc = getProperty(Document.StreamDescriptionProperty);

		if ( desc instanceof URL ) {

			setBase((URL) desc);

		}

		return new XHTMLReader(pos);

	}


	class XHTMLReader extends HTMLDocument.HTMLReader {


		public XHTMLReader(int offset) {

			super(offset);

			registerTag(FIELDSET, new BlockAction());

			registerTag(LEGEND, new BlockAction());

		}

	}

}


XHTMLEditorKit:


package de.tnteam.dragon.html;

import java.awt.*;


import javax.swing.*;

import javax.swing.text.*;

import javax.swing.text.Position.Bias;

import javax.swing.text.html.*;


public class XHTMLEditorKit extends HTMLEditorKit {


	private Parser defaultParser = null;

	private HTMLFactory defaultFactory = null;

	protected JComponent pane = null;


	@Override

	public void install(JEditorPane c) {

		this.pane = c;

		super.install(c);

	}


	@Override

	public void deinstall(JEditorPane c) {

		this.pane = null;

		super.deinstall(c);

	}


	@Override

	protected Parser getParser() {

		if ( defaultParser == null )

			defaultParser = new XParserDelegator();

		return defaultParser;

	}


	@Override

	public ViewFactory getViewFactory() {

		if ( defaultFactory == null )

			defaultFactory = new XHTMLFactory();

		return defaultFactory;

	}


	@Override

	public Document createDefaultDocument() {

		StyleSheet styles = getStyleSheet();

		StyleSheet ss = new StyleSheet();


		ss.addStyleSheet(styles);


		HTMLDocument doc = new XHTMLDocument(ss);

		doc.setParser(getParser());

		doc.setAsynchronousLoadPriority(4);

		doc.setTokenThreshold(100);

		return doc;

	}


	class XHTMLFactory extends HTMLFactory implements ViewFactory {


		public XHTMLFactory() {

			super();

		}


		public View create(javax.swing.text.Element elem) {

			HTML.Tag kind = (HTML.Tag) (elem.getAttributes()

					.getAttribute(javax.swing.text.StyleConstants.NameAttribute));


			if ( kind.equals(XHTMLDocument.FIELDSET) ) {

				return new FieldsetView(elem, BlockView.X_AXIS);

			}

			if ( kind.equals(XHTMLDocument.LEGEND) ) {

				return new HiddenView(elem);

			}


			return super.create(elem);

		}


		class HiddenView extends View {


			public HiddenView(javax.swing.text.Element elem) {

				super(elem);

			}


			@Override

			public float getPreferredSpan(int axis) {

				return 0;

			}


			@Override

			public Shape modelToView(int pos, Shape a, Bias 

					throws BadLocationException {

				return null;

			}


			@Override

			public void paint(Graphics g, Shape allocation) {}


			@Override

			public int viewToModel(float x, float y, Shape a, Bias[] biasReturn) {

				return 0;

			}


		}


		class FieldsetView extends BlockView {


			public FieldsetView(javax.swing.text.Element elem, int axis) {

				super(elem, axis);

			}


			@Override

			public void paint(Graphics g, Shape a) {

				super.paint(g, a);

				Rectangle b = a.getBounds();

				BorderFactory.createTitledBorder(getLegend()).paintBorder(pane,

						g, b.x, b.y, b.width, b.height);

			}


			public String getLegend() {

				javax.swing.text.Element l = getElement().getElement(0)

						.getElement(0);

				String s;

				try {

					s = getDocument().getText(l.getStartOffset(),

							l.getEndOffset() - l.getStartOffset());

				} catch (BadLocationException e) {

					e.printStackTrace();

					s = "";

				}


				return s;

			}


		}

	}


}


[/code]




[b]XParserDelegator[/b]:

[code] package de.tnteam.dragon.html; import java.io.*; import javax.swing.text.html.HTMLEditorKit.ParserCallback; import javax.swing.text.html.parser.*; public class XParserDelegator extends ParserDelegator { public XParserDelegator() {} private DTD dtd = null; @Override public void parse(Reader r, ParserCallback cb, boolean ignoreCharSet) throws IOException { new DocumentParser(getDTD()).parse(r, cb, ignoreCharSet); } public DTD getDTD() { if ( dtd == null ) { String nm = "html32"; DTD _dtd = new XDTD(nm); _dtd = createDTD(_dtd, nm); dtd = _dtd; } return dtd; } }

Bearbeitet von Dragon8
Geschrieben

Morgen,

cool ich danke dir ganz vielmals, ich habe nach wie vor weiter versucht die tags irgendwie einzubauen, aber es hat nicht wirklich geklappt, wenn ich mir deine quells angucke, dann habe ich eindeutig zu wenige unterschiedliche Quellen überschrieben, außerdem habe ich es nicht wirklich hinbekommen mir mit BlockView eine vernünftige Ansicht zu erstellen.

Vielen lieben Dank,

madbat

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...