Java ist auch eine Insel

Samstag, Januar 14, 2006

Insel: Automatisches Sortieren, Hervorheben und Filtern mit JXTable

JXTable (http://swinglabs.org/) ist eine quelloffene und frei verfügbare Erzweiterung einer JTable, die Sortierung, Hervorhebung und Filterung einfach unterstützt. Wir wollen unser ersten Beispiel mit QuadratTableModelSimple zunächst so ändern, in dem wir statt JTable die neue Klasse JXTable verwenden:

QuadratJXTable.java, main()

TableModel model = new QuadratTableModelSimple();

JXTable table = new JXTable( model );

Automatisch unterstützt die JXTable Sortierung: Ein Klick auf die Kopfzeile der Tabelle zeigt einen kleinen Pfeil mit Sortierrichtung.

Um eine automatische Hervorhebung zu nutzen, nutzt JXTable Objekte vom Typ Highlighter, die Farben und Logik beschreiben, wann welche Zeile wie hervorgehoben wird. Die Highlighter werden in einer HighlighterPipeline gesammelt, und diese wird der JXTable zugewiesen. Highlighter selbst ist eine Schnittstelle und zwei implementierende Klassen schauen wir uns an: PatternHighlighter und AlternateRowHighlighter.

QuadratJXTable.java, main()

HighlighterPipeline highlighters = new HighlighterPipeline();

highlighters.addHighlighter( new AlternateRowHighlighter() );

highlighters.addHighlighter( new PatternHighlighter(null, Color.RED, "6", 0, 1) );

table.setHighlighters( highlighters );

Der AlternateRowHighlighter lässt sich – wie wir es machen – mit einem Standardkonstruktor aufbauen, und Farben sind vorbelegt. Es lässt sich aber auch der pararmetrisierter Konstrukor mit drei Color-Objekten aufrufen, der die Farben für ungerade Zeilen, gerade Zeilen und Vordergrundfarbe annimmt. Der zweite Hervorheber ist ein PatternHighlighter, der nicht die Zeilen hinterlegt, sondern Elemente in den Zeilen, die auf reguläre Ausdrücke matchen. Der Ausdruck ist im Beispiel besonders einfach: Alle Strings, die eine 6 enthalten, sollen mit einer roten Vordergrundfarbe erscheinen; das erste Argument ist null, da wir die Hintergrundfarbe übernehmen und keine Farbe individuell zuweisen. Wo wir 0 eingetragen haben, können Match-Flags sitzen, Konstanten wie Pattern.CASE_INSENSITIVE, Pattern.MULTILINE, Pattern.DOTALL, Pattern.UNICODE_CASE und Pattern.CANON_EQ. Der letzte Ausdruck ist der wichtigste, denn er sagt, welche Spalte im Model berücksichtigt wird ­­– in unserem Fall die zweite.

Eine weitere Fähigkeit von JXTable sind die Filter, die in eine FilterPipeline gesetzt werden. Zwei wichtige Filter-Implementierungen sind PatternFilter und ShuttleSorter – er sieht auf den ersten Blick nicht wie ein Filter aus. Der PatternFilter belässt alle Zeilen in der Ergebnismenge, die einen regulären Ausdruck matchen und der ShuttleSorter sortiert auf Grund eines Comparators.

QuadratJXTable.java, main()

Sorter sorter = new ShuttleSorter( 0, true );

sorter.setComparator( new Comparator() {

public int compare( String s1, String s2 ) {

return new BigInteger( s1 ).bitCount() - new BigInteger( s2 ).bitCount();

}

} );

Filter[] filterArray = {

new PatternFilter( "(0|2|4|6|8)$", 0, 0 ),

sorter

};

table.setFilters( new FilterPipeline( filterArray ) );
Unser ShuttleSorter nutzt eine Anzahl-Bit-Comparator und berücksichtigt die erste Spalte (0) und sortiert aufsteigend (true). Der PatternFilter lässt alle geraden Zahlen durch. Das zweite Argument ist wie beim Highlighter die Match-Flags und das dritte Argument die Spalte – bei uns soll die erste Spalte gefiltert werden.

AddThis Social Bookmark Button

Donnerstag, Januar 12, 2006

mime4j für MS-Web-Archive MHT

Während Word und Excel beim Export einzelnde (mehr oder wenig schöne) XML-Dateien erzeugen (können), macht PPT das nicht: Es generiert entweder eine Sammlung von XML/HTML/GIF/.. Dateien, oder packt alle Dateien in ein MHT-Datei. Möchte man diese Datei auseinandernehmen, kann man gut http://mime4j.sourceforge.net/apidocs/ nutzen, denn MS bündelt die Dokumente wie eine MIME-EMail. Zunächst benötigt man einen Handler:

package TEST;

import java.io.IOException;
import java.io.InputStream;

import org.mime4j.BodyDescriptor;
import org.mime4j.SimpleContentHandler;
import org.mime4j.message.Header;

public class MyHandler extends SimpleContentHandler
{
@Override
public void headers( Header header )
{
System.out.println( header );
}

@Override
public void bodyDecoded( BodyDescriptor bd, InputStream is ) throws IOException
{
System.out.println( bd );
}
}

Der macht jetzt nicht viel, man sieht aber das Prinzip.

Der Quellcode des Parsers ist auch kurz:

package TEST;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

import org.mime4j.ContentHandler;
import org.mime4j.MimeStreamParser;

public class Mime4J
{
public static void main( String[] args ) throws IOException
{
ContentHandler handler = new MyHandler();
MimeStreamParser parser = new MimeStreamParser();
parser.setContentHandler( handler );
parser.parse( new BufferedInputStream( new FileInputStream( "c:/a.mht" ) ) );
}
}

Auf der Konsole folgen dann Ausgaben wie

MIME-Version: 1.0
Content-Type: multipart/related; boundary="----=_NextPart_01C617A0.DCEFFF40"

Content-Location: file:///C:/EC2C4D01/a.htm
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="us-ascii"

text/html
Content-Location: file:///C:/EC2C4D01/a-Dateien/master29.htm
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="us-ascii"

text/html
Content-Location: file:///C:/EC2C4D01/a-Dateien/master29.xml
Content-Transfer-Encoding: quoted-printable
Content-Type: text/xml; charset="utf-8"

Ein Java-Programm (nicht quelloffen), was das schon alles macht -- und für Mac/Linux ganz spannend ist, ist unmhtml von http://www.joecheng.com/code/.

AddThis Social Bookmark Button