Archiv für

Juni, 2005

...

Einfügen von HTML-Tags in JEditorPane

11 kommentare

Wer schon einmal versucht hat, einen halbwegs brauchbaren Editor unter Java zu schreiben, der weiß um die Schwierigkeiten mit der Komponente JEditorPane: für jedes Format muss ein brauchbarer EditorKit her, um ein Einfügen oder Bearbeiten des Textes zu erlauben.

Der EditorKit HTMLEditorKit reicht für das Anzeigen einfacher HTML-Dokumente aus. Wie geht es aber weiter, wenn man beispielsweise eine Textstelle umformatieren möchte? Kann man einfach ein HTML-Tag wie <strong>...</strong> einfügen, um Text fett darzustellen? Wer es einmal ausprobiert, wird feststellen: Es reicht nicht.

Diese Erkenntnis habe ich auch gewonnen. Ein Blick in die API-Dokumentation brachte mich auch nicht weiter. Aber eine kurze Recherche im Netz hat schliesslich folgenden Codeschnippsel zu Tage gefördert:

HTMLDocument html = (HTMLDocument) editorPane.getDocument();
HTMLEditorKit kit = (HTMLEditorKit) editorPane.getEditorKit();
try {
    String s = ""+html.getText(start, end - start)+"";
    // remove old, change to bold
    html.remove(start, end - start);
    kit.insertHTML(html, start, s, 0, 0, HTML.Tag.STRONG);
} catch (BadLocationException e1) {
    e1.printStackTrace();
} catch (IOException e1) {
    e1.printStackTrace();
}

Als erstes wird in Zeile 1 + 2 ein HTMLDocument und der zuständige HTMLEditorKit aus dem JEditorPane geholt. Anschliessend wird der ausgewählte Text mit den Tags <strong>...</strong> umschlossen. Zeile 5 entfernt anschliessend den ausgewählten Text und Zeile 6 fügt den Text inklusive HTML-Tag wieder an der gleichen Stelle ein.

Zeile 6 ist die wichtigste Stelle in diesem Code. Sie fügt nicht nur den Text ein, sie enthält auch Informationen über die Formatierung. HTML.Tag.STRONG zeichnet den eingefügten Text als Fettdruck aus. Der EditorKit benutzt diese Formatierung, um sie dem Parser zur Darstellung bekannt zu machen. Die Tags allein als reinen Text einzufügen, würde nur die Anzeige von <strong<...</strong> zur Folge haben.

Was passiert nun aber, wenn man an der gleichen Stelle eine weitere Formatierung einfügen möchte? Eigenlich sollten die äußeren Tags erhalten bleiben und eine tiefere Ebene sollte mit der neuen Formatierung erzeugt werden. Leider ist das nicht der Fall. Wenn z.B. eine kursive Textstelle innerhalb des zuvor erzeugten Fettdrucks einfügt wird, kommt folgendes heraus:

Vorher:
<strong>Dies ist nur ein Test. Es passiert rein gar nichts.</strong>

Nachher:
<strong>Dies ist nur ein Test. Es </strong><em>passiert</em> <strong>rein gar nichts.</strong>

Der alte Tag wird also aufgebrochen, die neue Formatierung dazwischen eingefügt. Der Benutzer wollte natürlich etwas anderes, nämlich Kursiv- und Fettdruck gleichzeitig.

Wenn jemand eine Lösung für dieses Problem weiß, bin ich für jede Hilfe wieder einmal dankbar. Ich habe schon einige meiner Bücher gewälzt, leider ist kein ausgezeichnetes Swing-Buch dabei. Auch für eine Buchempfehlung wär ich dankbar. Swing interessiert mich sehr, natürlich auch die Variante aus dem JDK5.0.

Tags: Java

Ein kleiner Passwort-Generator

Kommentare deaktiviert

Aus gegebenem Anlass: Ein kleiner Passwort-Generator in Java, der einstellbar Passwörter erzeugt. Er kann sowohl aus vorgebenenen wie auch aus einem selbstdefinierten Zeichenpool ein beliebig langes Passwort erzeugen. Um das Programm zu starten, müssen natürlich auch wieder die Bibliotheken JGoodies Looks & Forms im Classpath zu finden sein. Mittlerweile ist die Benutzung der Bibliotheken schon fast eine Angewohnheit.

Wer es nicht mag, der muss das Layout noch einmal an das “normale” Swing anpassen. Das FormLayout und der PanelBuilder können bei so einem einfachen Programm natürlich schnell gelöscht werden. Nur zu – aber kommt zurück und berichtet darüber! ;-) Ich habe allerdings schon eine Version erstellt, die ohne JGoodies läuft. Wer möchte, kann sie hier runterladen. Und wer einfach das Programm testen will, der kann sich ein ausführbares JAR-Archiv runterladen. Unter Windows sollte das Programm nach einem Doppelklick starten – wenn nicht, einfach auf der Kommandozeile

$>java -jar jpassgen.jar

eingeben. Das sollte funktionieren.

Und wer wissen möchte, wie das ganze aussieht, der sollte weiterlesen.

Mehr: Lies den Rest dieses Artikels…

Kommentare deaktiviert

Was man alles mit einem JTable machen kann

Kommentare deaktiviert

Erstaunlich, was man alles aus einer einfachen Tabelle herausholen kann. Hier erstmal der Screenshot:

Pimp my JTable

This is the first article in a series looking at the information visualizations found in JInspired’s JXInsight J2EE performance management console. I thought it would be best to start with the standard table view which appears in nearly all performance management tools. It’s usage is so widespread that it is a standard component of any mature and production ready UI toolkit including Java Swing the cross platform technology used and extended by JXInsight’s award winning console.

[gelesen bei ClientJava.com - What Can Be Done With a JTable]

Tags: Java

Kommentare deaktiviert

Kaffee-Timer in Java

6 kommentare

Ok, ich gebe es zu: mir war langweilig! Ausserdem wollte ich schon immer mal eine System Tray-Applikation schreiben. Also habe ich mir auch gleich noch etwas gesucht, das vielleicht nützlich sein könnte. Ich vergesse nämlich manchmal/meistens, dass ich einen Kaffee aufgesetzt habe, wenn ich am Rechner bin. Also dachte ich mir: Hm, ein Timer wär nicht schlecht, der mich daran erinnert. Dann dachte ich: Hey, ich könnte mal wieder Java machen! Und dann dachte ich mir: Ein Timer in Java wäre super, den man -ruckzuck- auf eine bestimmte oder eine einzugebende Zeit einstellen könnte und der dann im System Tray (dieser Bereich neben der Windows-Uhr) verschwindet und mich anschliessend per Sound und Benachrichtigungsballon an meinen Kaffee erinnert. Also hab ich gleich mal angefangen und mir die nötigen Bibliotheken angesehen…

Als erstes wär da JTray, eine Bibliothek für den System Tray-Zugriff unter Windows. Funktioniert natürlich nur unter Windows, aber im Moment macht das nichts. (Und das, obwohl Sarge raus ist*seufz*) Die Bibliothek kann als kostenlose Demo-Version runtergeladen werden. Dann poppt allerdings vor dem Start des eigenen Programms ein Fenster mit einem Hinweis auf, ausserdem erscheint ein zusätzliches Icon im System Tray. Die komplette Bibliothek kostet $175 USD – wenn jemand also eine Alternative kennt: Schreibt mir bitte!

Ausserdem habe ich natürlich wieder die Bibliotheken von JGoodies eingesetzte. Forms bietet eine schnelle und einfache Möglichkeit, aufgeräumte GUIs zu erstellen. Sehr leicht zu lernen, sehr schnell einzusetzen. Looks hingegen motzt die etwas angestaubte Swing-Oberfläche vom alten Metal-Look and Feel auf und passt sie an ein modernes Windows an. Funktioniert natürlich auch unter Linux.

So, damit wäre alles beisammen. Geschrieben habe ich das kleine Programm in Ermangelung meiner gewohnten IDE IDEA mit der Windows-Version von ViM, einem leistungsstarken Editor aus der Unix/Linux-Welt. Die Kommandozeilen-Tools von Java können bequem von der Windows Eingabe-Aufforderung gestartet werden – für ein so kleines Projekt ist keine umständliche Verwaltung des Classpath und der Bibliotheken notwendig.

Die Oberfläche ist einfach gehalten. Es gibt nur ein paar JRadioButtons für vordefinierte Zeitspannen, ein JTextField für selbst definierte Zeitspannen und Buttons zum Start/Stop des Timers. Das ganze sieht dann so aus:

Screenshot der Timer-Applikation

Die Benachrichtigungsballons poppen über dem System Tray auf. Dazu gibt es natürlich auch einen kleinen Screenshot:

Screenshot der Benachrichtigung

Die Erstellung eines Menüs für das Tray-Icon ist leicht, die Bibliothek verhilft zu schnellem Erfolg. Das übliche Prozedere aus der Swing-Welt kann 1:1 übernommen werden:

JTrayIcon jTrayIcon;
JPopupMenu rightTrayMenu = new JPopupMenu();
JPopupMenu leftTrayMenu = new JPopupMenu();
JMenuItem trayClose = new JMenuItem("Close");
JMenuItem trayHide = new JMenuItem("Hide");
JMenuItem trayShow = new JMenuItem("Show");
JMenuItem tray5Min = new JMenuItem("5 Min");
JMenuItem tray3Min = new JMenuItem("3 Min");
JMenuItem tray1Min = new JMenuItem("1 Min");

try {
	jTrayIcon = new JTrayIcon("images\icon1.png", ImageFileType.JAVA_SUPPORTED);
	// set the right click target to the popup menu after the jPopupMenu and its components have been completely defined
	jTrayIcon.setRightClickTarget(rightTrayMenu);
	jTrayIcon.setLeftClickTarget(leftTrayMenu);
	// display this JTrayIcon
	jTrayIcon.show();
} catch (JTrayLibraryLoadFailedException e) {
	System.out.println(e);
	System.exit(-1);
}

Damit ist das Tray-Icon mit Menüs bestückt, ausserdem wird die Grafik images\icon1.png als Icon angezeigt. Es sind natürlich auch Animation möglich, das werde ich später ausprobieren – wenn ich mal wieder Lust habe, ein Icon zu erstellen. Was jetzt noch fehlt ist eine Methode, um den Timer zu starten und eine Benachrichtigung in den bekannten Ballon-Fenstern anzuzeigen. Beides ist schnell gemacht:

private void startTimer(float duration) {
	if(time.isEditable()) {
		duration = Float.parseFloat(time.getText());
	}

	// create timer
	float delay = duration * 1000f; // convert to ms
	ActionListener taskPerformer = new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			t.stop();
			timerEnded();
		}
	};
	t = new Timer((int) delay, taskPerformer);
	this_windowHide();
	t.start();
}

private void showBalloonMessage(String title, String text) {
	jTrayIcon.showBalloonMessage(title, text);
}

Damit ist der Timer schon fertig und kann eingesetzt werden. Das Abspielen der Sound-Datei habe ich auf dem einfachsten Weg abgefertigt: Die Methode Applet.newAudioClip(URL) lädt die WAV-Datei und spielt sie anschliessend beim Ende des Timers ab. Schon wird neben der Ballon-Benachrichtigung ein Sound ertönen, der mich darauf hinweist, endlich den Kaffee aus der Maschine zu holen.

try {
		String file = "file:" + System.getProperty("user.dir") + "/" + soundfile;
		soundclip = Applet.newAudioClip(new URL(file));
		System.out.println("Loaded " + file);
	} catch(MalformedURLException e) {
		System.err.println("Can't find soundclip.");
		System.exit(-1);
	}

Das Ganze ist natürlich noch ausbaufähig und wenn jemand einen Vorschlag hat oder dieses kleine Programm selbst erweitern möchte, der kann das natürlich gern machen.

Hier gibt es alle notwendigen Dateien direkt als Download:

JGoodies Forms & Looks
JTray Trial-Version
Sourcecode von JTeaTimer

Tags: Java