Java Getriebe

Java und NetBeans

Streams und Maps

Es gibt gefühlt hunderte Seiten, die sich mit der Streams API aus Java 8 befassen. Alle haben furchtbar tolle Tipps und vor allem Beispiele, wie man die Daten aus seinen Listen über Streams und den unausweichlichen Lambdas verarbeiten, filter und umwandeln kann. In unserer (gewachsenen) Anwendung verwenden wir allerdings weniger oft Listen und Sets als viel mehr etliches an Maps. Der Großteil unserer Daten sind als Schlüssel-Wert Paare gespeichert. Wenig ist eine „beliebige“ Datenmenge sondern explizit benannte Daten.

Die Stream sind allerdings auf einzeln aufgereihte Objekte ausgelegt und nicht auf Name-Value-Datenpaare. Dies macht das Handling innerhalb der Streams etwas unhandlich, vor allem, wenn man zwar durch die Values iterieren möchte, diese auch gerne per map() in andere Datentypen umwandeln möchte, aber der Schlüssel darf dabei nicht verloren gehen, da dieser unbedingt mit den zugehörigen Daten bzw. Objekten verknüpft bleiben sollte oder gar muss.

Für die Verarbeitung dieser Paare innerhalb der Streams bedeutet dies meist, dass man irgendwie mit Map.Entry<> 1 hantiert. Diese sollte man in der Regel allerdings als Immutable betrachten, so dass man bei jeder Änderung von Key oder (häufiger) Value eine neue Instanz erstellen muss. Leserlicher wird der Code dadurch selten.

Mein Ansatz für einen etwas leserlicheren Code ist der folgende:

1
2
3
4
5
6
7
8
9
10
11
12
13
public static <K, V> Map.Entry<K, V> toEntry(K key, V value) {
  return new AbstractMap.SimpleImmutableEntry<>(key, value);
}

public static <K, V, M> Map.Entry<M, V> mapKey(
        Map.Entry<K, V> org, Function<K, M> mapper) {
  return toEntry(mapper.apply(org.getKey()), org.getValue());
}

public static <K, V, M> Map.Entry<K, M> mapValue(
        Map.Entry<K, V> org, Function<V, M> mapper) {
  return toEntry(org.getKey(), mapper.apply(org.getValue()));
}

Damit lässt sich der Quelltext mit den Streams deutlich kürzer schreiben und enthält keine new Aufrufe die in diesem Zusammenhang nur den Lesefluss stören.

Ein Beispiel

In „parameters“ ist eine Menge von „Parameter“ Objekten die jeweils ein „Name“-„Wert“ Paar darstellen. Für eine Fremdbibliothek müssen unsere Namen in „deren“ Namen umgewandelt werden und dann diese neuen Schlüssel mit allen nicht-null Werten von „Parameter“ in eine bestehende Map „data“ (die bereits andere Daten enthält) geschrieben werden.

1
2
3
4
5
6
7
8
9
10
11
parameters.stream()
    // get all Mapping (m) to all Parameter (p)
    .map(p -> toEntry(p, mappingManager.get(p)))
    .filter(pm -> pm.getValue() != null)
    .map(pm -> mapValue(vm, m -> m.getKey()))
    .map(pk -> mapKey(pk, p -> p.getValue()))
    .filter(vk -> vk.getKey() != null)
    // write all Values (v) with the mapped keys (k) to data
    .collect(() -> data,
        (map, vk) -> map.put(vk.getValue(), vk.getKey()),
        Map::putAll);

ps: Ich will nicht behaupten, dass das Beispiel guter Code ist. Er soll nur zeigen, dass die Hilfsmethoden die Übersichtlichkeit beim Arbeiten mit Key-Value-Paaren erhöht.

Is An Agile Java Standard Possible? – Simon Ritter

Java Champion und JUG Leader der JUG London, Simon Ritter hat in einem Blogpost auf „DZone Java“ über die Zukunft der Entwicklung von Java und seine Plattform geschrieben. In Is An Agile Java Standard Possible? schreibt er davon, dass es denkbar sei, dass nicht mehr bis zu einem „Major Release“ der Java Plattform gewartet wird bis ein „JDK Enhancement Proposal“ (JEP) für jederman nutzbar wird, sondern dass diese JEPs bereits vorher schon in die aktuelle JDK eingepflegt werden.

Even programming languages need to adapt to the more modern methodologies. See how Java, through JEPs, is making the change and what challenges lie ahead.

Read More

NetBeans will ein Apache Projekt werden

Quelle: NetBeansProposal – Incubator Wiki

Im Incubator Wiki der Apache Foundation steht seit heute morgen ein Antrag von Oracle um das Projekt NetBeans komplett unter der Schirmherrschaft der Foundation zu stellen.

Es stehen in der Liste der Unterstützer neben diversen Mitgliedern des NetBeans DreamTeams auch etliche Mitarbeiter von Oracle auf der Liste. Somit wird der aktuelle Besitzer wohl auch weiterhin der der NetBeans IDE und Plattform weiter arbeiten.

Spannend ist dies auf jeden Fall. Vor allem auf so kurz vor der JavaOne Konferenz. Über die Gründe von Oracle lässt sich nur spekulieren, aber ich persönlich hoffen, dass die NetBeans IDE auch weiterhin die Referenz-IDE für neue Java Versionen bleibt.

Nicht lokalisierte Zeichenketten finden in NetBeans Anwendungen

Jeder Anwendungsentwickler wird früher oder (selten) später auf das Thema der Mehrsprachigkeit stoßen. Java bietet mit den ResouceBundle Konzept dankenswerterweise eine sehr einfach Lösung hierzu an. Tools wie OmegaT erlauben eine einfache Übersetzung dieser Properties-Dateien so dass auch größere Anwendungen mit vergleichsweise geringem Aufwand zu übersetzen sind.

Die entscheidende Voraussetzung für eine Übersetzung ist allerdings, dass die Zeichenketten in der Anwendung nicht „hardcodiert“ im Quelltext stehen, sondern schön über die Klasse ResouceBundle aus den Propertiesdateien gelesen werden. Die Suche nach diesen „hardcodierten“ String kann gerade in komplexen und modularen Anwendungen wie einer NetBeans Rich Client Anwendung recht mühsam sein.
Read More

Korrekte Icongröße bei ProjectSensitiveActions

Mit einer ProjectSensitiveAction kann man wunderbar eine Action erzeugen, die zu einem bestimmten Projekt ausgeführt werden soll. Das schöne daran ist. dass diese Action auch dann funktionieren, wenn im Projektbaum ein Unterknoten des Projektes ausgewählt ist.

Leider hat die Utilities-Methode projectSensitiveAction den Haken, dass hier explizit ein Icon angegeben werden muss statt einer iconBase. Dies führt dazu, dass für eine solche Action in der Toolbar und im Menü nur ein einzelnes Icon anzeigt wird. Also ist das Icon entweder in der Toolbar zu klein oder im Menü zu groß. Auch die Funktion, dass man die Icongröße in der Toolbar verändern kann, kann nicht sinnvoll genutzt werden.

Bei der Suche durch die NetBeans Quellen ist mir dann aufgefallen, dass für die Buttons in der Toolbar nach einem Action-Attribut "iconBase" gesucht wird um die korrekte Größe für das Icon zu bestimmen. Setzt man dieses Attribut bei der generierten ProjectSensitiveAction, so wird auch dessen Icon korrekt in der Toolbar angezeigt:

1
2
3
4
5
ImageIcon menuIcon = ImageUtilities.loadImageIcon(iconPath, true);
Action action = ProjectSensitiveActions.projectSensitiveAction(
    performer, displayName, menuIcon);
//Workaround um in Toolbar die korrekte Groesse anzuzeigen.
action.putValue("iconBase", iconPath);

menuIcon ist dabei das „Grund-Icon“ in der Größe 16×16 Pixel, wie man es von den Actions in NetBeans gewohnt ist. Dessen iconPath ist der Resourcenpfad, welcher auch für die "iconBase" genutzt werden kann.

Aus Alt mach Neu – ProjectConverter

Wir arbeiten bei uns in der „WZL Gear Toolbox“ mit der „Project API“ von NetBeans um verschiedene Simulationsansätze und -Programme einfacher verwalten zu können. Von Zeit zu Zeit kommt es dabei vor, dass sich die Programme oder die Konzepte der Simulationen ändern und wir neue Projekttypen definieren müssen und alte verwerfen. Je nach Alter der Programme haben sich beim Enduser allerdings mit der Zeit einige Projekte angesammelt, die er eigentlich gerne weiter nutzen würde. In vielen Fällen sind die einzugebenden Daten im alten wie im neuen Projekt gleich oder ähnlich. Ein Zahnrad zum Beispiel wird hat immer das Eingabedatum „Zähnezahl“.

Ändert sich die „Projekt-ID“ 1 eines Projektes nicht, so kann man sich ganz gut mit einem ProjectOpenedHook helfen, der alle notwendigen Änderungen an den Dateien vornimmt, bevor NetBeans das Projekt in der „Projects“ Liste anzeigt. Ändert sich die ID allerdings, tauchen die alten Projekte nicht im „Projekt öffnen“-Dialog der Anwendung auf. Bisher haben wir dies durch eine eigene „Import old project“-Action gelöst, die über eigene „ToolboxProjectConverter“ Implementierungen die notwendigen Änderungen durchgeführt hat. Seit NetBeans 8.1 ist dieser Umweg nicht mehr notwendig, denn im Modul „Base Project UI API“ gibt es jetzt einen ProjectConvertor.
Read More

Notes:

  1. Also der „type“, der in der „project.xml“ steht

Plattformwechsel auf NetBeans 8.1

Das NetBeans Team hat für die Version 8.1 der NetBeans Plattform ein paar „gemeine“ Änderungen an den Modulen und deren Abhängigkeiten gemacht. Zum einen sind dies Änderungen um die verschiedenen JRE-Profile aus Java8 besser berücksichtigen zu können und zum anderen sind es (denke ich) erste Vorbereitungen für die neue Modularität von Java 9.
Read More