Common und CommonUI - nur ein paar Utility-Klassen

Auch wenn

  • das allgemeine Jauchzen und Jubilieren ob der Veröffentlichung meiner Projektchen mich schon fast erdrückt :roll_eyes:
  • diese Beiden eigentlich nicht für die „öffentliche Verwendung“ gedacht sind
  • … und sie (teilweise deshalb) (noch) nicht in der Maven Central liegen

eher „der Vollständigkeit halber“ ein Hinweis auf diese beiden:

Ein paar allgemeine utility-Klassen, z.B. für XML, oder um Java Beans komplett als XML rauszuschreiben, oder auch ein bißchen was zu Collections oder Iteratoren (Iteratoren über mehrere Iterables, Iteratoren über mehrere Iteratoren, … Iteraception…), oder auch zu concurrency, etwa, um schnell und einfach parallel auf einer „Range“ (bzw. einem Array) zu berechnen, oder einen ExecutorService zu erstellen, der Exceptions nicht verschluckt. Nichts, was es nicht auch irgendwo anders gäbe, aber vielleicht findet der eine oder andere ja einen interessanten Schnipsel zum Rauskopieren.

Ein paar allgemeine utility-Klassen für Swing. Da könnte vielleicht auch das eine oder andere nützliche dabei sein, nur kurz aufgelistet:

  • Ein JTree mit Checkboxen und „Tri-State“-Verhalten
  • Ein JTree, der gefiltert werden kann (nicht perfekt, aber für meine Zwecke war’s OK)
  • Utilities, damit man bei einer JTable die Spaltensortierungen vernünftig handhaben kann, und zwar indem man umschalten kann zwischen „Aufsteigend sortiert“, „Absteigend sortiert“ und (und das fehlt normalerweise: ) „Gar nicht sortiert“. Das ganze natürlich auch für mehrere Spalten, um mehrere Sortierkriterien angeben zu können, hübsch mit passendem Renderer für den Header, der die Pfeilchen unterschiedlich groß malt und so…
  • Eine Klasse, mit der man in eine JTabbedPane Tabs einfügen kann, die einen „Schließen“-Button haben
  • Ein Klassiker: Ein „CollapsiblePanel“, das man mit einem Klick auf den Rahmen auf- und zuklappen kann
  • Eine (seeeehr experimentelle und vorläufige) Klasse, mit der man normale Layouts auch auf die JInternalFrames eines JDesktopPane anwenden kann
  • Eine „LocationBasedAction“, mit der man das Kontextmenü (z.B. auf einem JTree) dynamisch anpassen kann, je nachdem, wo man es aufgemacht hat
  • Ein utility, mit dem man einen JSpinner so frisieren kann, dass man ihn mit Mausdrags hoch-und runterdrehen kann (und das warppt sogar über die Bildschirmgrenze :cool: )

und natürlich eine handvoll weitere utility-Funktionen.

Nochmal: Das ganze sollte nicht als „öffentliche, stabile API“ angesehen werden, aber … ist eben schrittweise entstanden, im Rahmen der Projektchen, an denen ich so bastle, und dient vielleicht als Steinbruch für das eine oder andere nützliche Codeschnipselchen.

Sie liegen jetzt auch in der Maven Central,


<dependency>
  <groupId>de.javagl</groupId>
  <artifactId>common</artifactId>
  <version>0.0.1</version>
</dependency>

und


<dependency>
  <groupId>de.javagl</groupId>
  <artifactId>common-ui</artifactId>
  <version>0.0.1</version>
</dependency>

Außerdem habe ich Tests für die Table-Sortierungs-Helper und die LocationBasedAction hinzugefügt.

Updates:

<dependency>
  <groupId>de.javagl</groupId>
  <artifactId>common</artifactId>
  <version>0.0.2</version>
</dependency>
<dependency>
  <groupId>de.javagl</groupId>
  <artifactId>common-ui</artifactId>
  <version>0.0.4</version>
</dependency>

Interessant für Außenstehende sind ggf. die AccordionPanel und CollapsiblePanel-Klassen in der UI-Lib. Ich finde, wenn man “viele” GUI-Komponenten hat, ist es toll und praktisch, ein Accordion zu haben, wo man einzelne Panels ein- und ausklappen kann.

1 „Gefällt mir“

Ein paar updates mit ein paar vergleichsweise “sophisticateten” Klassen:

<dependency>
  <groupId>de.javagl</groupId>
  <artifactId>common-ui</artifactId>
  <version>0.0.6</version>
</dependency>
  • Added JOptionPanes class with a method to show an option pane that does an input validation
  • Added a ToggleListSelectionModel that allows toggling the selection state with clicks
  • Added GenericTableModel that builds the table contents with accessor functions
  • Added CustomizedTableHeader that allows adding custom components to a table header
  • Added a MultiColumnRegexFilter that allows adding text fields to table columns that may be used to filter a table based on regular expressions
  • Added various table cell renderers
  • Added text component utilities: An UndoRedoHandler that generically adds undo/redo functionality to text components, and a SearchableTextComponent that adds a simple search functionality to text components

Die Suchfunktionalität in Textkomponenten war ein bißchen frickelig, und da gibt’s eigentlich die meisten Freiheitsgrade, was man vielleicht anders machen oder konfigurieren können will, aber die Basisfunktionalität ist da:

SearchableTextComponent

Der mehr-Spalten-Tabellen-Regex-Filter ist auch fancy. Tatsächlich war das komplizierteste da, die Textfelder in den Tabellenheader zu kriegen:

gif

1 „Gefällt mir“

Thema neu beleben?

Die letzte Antwort in diesem Thema war vor über 3 Jahren.

Ja, will ich. Es gibt halt ab und zu noch updates hier, für die Leute :older_man: die noch Swing verwenden.

Das letzte update fügt eine Klasse PropertiesManager hinzu. Die bietet einige generische Funktionen, um den „Zustand einer Anwendung“ beim Schließen zu speichern und beim Öffnen wiederherzustellen. Der Schnipsel hier zeigt, wie man z.B. die ‚bounds‘ eines Frames speichert:

// Create the properties manager that will save the properties
// to a file with the given name
PropertiesManager pm =
    new PropertiesManager(PropertiesHandles.get(PROPERTIES_FILE_NAME));

frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// Register a listener to the given frame that will save all
// properties when the frame is closed
pm.saveOnClose(frame);

// (Fill the frame here...)

// Register a 'Rectangle' property, namely the 'frame.bounds', to
// be saved from 'getBounds' when the frame is closed, and to
// be set via 'setBounds' when the state is restored
pm.registerRectangle("frame.bounds", 
    frame::getBounds, frame::setBounds);

// Restore the state that was previously saved to the file
pm.restore();

frame.setVisible(true);

Damit wird die Fensterposition (d.h. die bounds) beim Schließen gespeichert, und beim Laden wiederhergestellt.

Das kann - je nach Komplexität der Anwendung - natürlich beliebig kompliziert sein: Was genau soll alles gespeichert werden?

Aber einige der „in Swing wichtigsten“ Typen sind durch die PropertiesManager#register...-Methoden abgedeckt:

  • String - z.B. der Inhalt von einem text field
  • Integer - z.B. die „divider location“ einer split pane
  • Double … nur um das halt auch zu haben…
  • Path - z.B. der ausgewählte Pfad eines file choosers. (Das nervt sonst immer tierisch, wenn man sich nach jedem Neustart der Anwendung ins gewünschte Zielverzeichnis hangeln muss…
  • Point - z.B. die Position eines Fensters
  • Rectangle - z.B. die „bounds“ eines Fensters
  • Color - z.B. eine ausgewählte Farbe in einem color chooser

Beispiele zu den meisten davon findet man im PropertiesManagerTest.