Ich entwickele das Applet weiter.
Gute Literatur hilft ungemein das man die echt komplexe Swing-API richtig beherrscht(Manning Swing 2nd ed. sowie "Graphic Java 2 von Geary", 3rd ed.).
Ich meine hier Dinge wie: Wie bringe ich das häßliche grau im Hintergrund der JTable, die in einer JScrollPane liegt. Geht so:
scrollPaneTable.getViewport().setBackground(table.getBackground());
Aber wie soll man darauf kommen ???
Netbeans3.5 ist völlig in Ordnung.
Vermisse folgendes dringend:
- In Eclipse kann ich automatisch getter- und setter-Methoden generieren. Hier muß ich tippen.
- Refactoring Unterstützung fehlt. Umbenennung von Variablen in einem Projekt geht in Eclipse z.B. besser.
- Oft muß ich auf "Compile Project" drücken, damit Änderungen in Helferklassen bei Test da sind. Nervt ein bißchen.
- Eclipse hat auch einfach viele interessante Zusatz-plugins. Nur eben keinen graphichen GUI-Editor, der es mit Netbeans aufnehmen kann.
Mein LayoutManagement ist noch nicht so wie ich will. Irgendwie ende ich immer damit, daß ich GridBagLayout benutzen will. ::)
Ich sehe ein, daß eine Komponente wie JTable komplex sein muß. Mußte aber gestern nacht erst einmal vor AbstractTableModel kapitulieren und habe DefaultTableModel benutzt. Weiß aber jetzt wie es geht. Hoffentlich. :)
Auslagern von bestimmter Funktionalität in helper-Klassen ermöglicht die einfache Einbindung in Notes-Agenten, Notes-Applets und eigentlich allen beliebigen Java-Progs.
Nun muß ich das in Notes einbinden. Denke da über best-practices nach.
- Eine eigene Klasse ist für die Responsabiltiy "mit Notes kommunizieren ist klar". Objekt einfach als 1-1 unidirektionale Association GuiClass has-a NotesClass.
- werde sicher invokeLater() und invokeAndWait() benutzen. Das gehört wohl in die GUI-Klasse. Hat schon jemand damit gearbeitet?
- Ich zeige Daten aus Domino-Dokumenten in einer JTable an. Wie reagiere ich darauf, wenn sich etwas in den Daten in Notes ändert. Geht da eventuell ein über weite Zeiträume schlafen-gelegter Thread, der sagen wir alle 2 Minuten Notes abfragt? Das wäre nett. Hat jemand Erfahrungen damit?
FRAGE AN RALF: Wie stelle ich bei Netbeans ein, daß es die Notes-VM benutzt (vereinfacht das Testen).
Hatte nun die erwartete Begegnung der 3. Art.
In der ComboBox cbWoche tausche ich an einer Stelle alle Items aus (wenn der User ein neues Jahr wählt).
Etwa so:
cbWoche.removeAllItems();
for (int i=0; i < selectionWeeks.size(); i++) {
WeekInfoVO temp = (WeekInfoVO) selectionWeeks.get(i);
cbWoche.addItem(temp.getFormatedElement());
}
JComboBox.addItem() ruft intern das entsprechende ActionPerformed-Event auf. Sowas muß man natürlich wissen. Steht nur leider nirgendwo. Dies führte in meinem code dann dazu, daß das Modell der ComboBox während des Item-Wechsels auf einen ItemIndex gesetzt wurde, der nicht existiert.
Die Java14 VM hält diesen unstabilen Zustand aus, ohne einen ArrayIndexOutOfBound-Exception zu werfen. Die 1.3-VM in Notes leider nicht. Bücher und Newsgroups schwiegen zu diesem speziellen Problem. Habe jetzt einen workaround gefunden. Das Finden der Ursache hat aber jetzt genau 5 Stunden 30 Minuten gedauert.
Erwarte noch weitere solcher Subtilitäten in der komplexen Swing-API.
Vorsätze für Besserung:
- immer die gleiche VM für Entwicklungs- und Targetplattform zu verwenden.
- Log4U einsetzen. Der debugger startet mir einfach zu langsam. Debuggen dauert mir zu lange. Deshalb arbeite ich derzeit mit System.out.println(). Eine vernünftige Strategie mit log4U ist vermutlich das beste.
O.k. vielleicht brauche ich das von einem Performance-Standpunkt für diese Applikation nicht. Vielleicht aber schon. Ich habe 768 MB Arbeitsspeicher. Notes-Client und -Server sind auf einer Maschine.
Caching von Notes-Objekten in Instanzvariablen?
Wie wäre es damit (bin mir echt nicht so sicher, ob ich das alles richtig verstehe):
So in der Art, ohne daß ich es jetzt ausprobiere:
package de.aja.db;
import java.util.*;
import lotus.domino.*;
public class NotesConnection extends NotesThread {
Database nDbCurrent;
Session nSession;
View nViewMAs;
String serverName;
String serverPath;
public static NotesConnection factory(HashMap appletParameters) {
if (nConnection == null) {
nConnection = new NotesConnection(appletParameters);
}
return nConnection;
}
/** Creates a new instance of NotesConnection */
public NotesConnection(HashMap appletParameters) {
serverName = (String) appletParameters.get("dbServerName");
serverPath = (String) appletParameters.get("dbPathName");
this.serverName = serverName;
this.serverPath = serverPath;
}
runNotes () {
try {
if (nSession == null) {
nSession =NotesFactory.createSession();
}
if (nDbCurrent == null) {
nDbCurrent.getDatabase(serverName, serverPath);
}
if (nViewMAs == null) {
nViewsMAs = nDbCurrent.getView("vMAs");
}
Vector vecMAs = new Vector();
Document nDoc = null;
nDoc = nViewMAs.getFirstDocument();
while (nDoc != null) {
vecMAs.add(nDoc.getItemValueString("userNameAbb"));
nDoc = nViewMAs.getNextDocument(nDoc);
}
// do more business logic stuff
// von hier TableModel über invokeLater() evtl. invokeAndWait() aktualisieren.
// weil Swing-Komponenten nur so von einem anderen Thread
// als dem berühmten event dispatch thread sicher aufgerufen
// werden können
} catch (NotesException e) {
// do recycle() stuff
e.printStackTrace();
} finally {
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
//
}
}
Diese Klasse wird von TableModel initialisiert. Von dort wird auch die runNotes-Methode aufgerufen.
Am besten im init() des Applets (erzeugt das TableModel und delegiert zu ihm die Initialisierung des Notes-Thread. Und Notes-Thread in destroy von der Applet-Klasse beenden. Einfach ist das nicht. ::)
Axel
Mit Netbeans für Notes entwickeln.
Sobald man anfängt aus dem Applet auf LoNo zuzugreifen, wird es ein bischen kompliziert.
Da spielt die Sandbox nicht mit, was auch zu erwarten war.
SecurityAccessControlException. JaJa.
Es gibt ja nun seit Java2 Möglichkeiten, die Sandbox policies liberaler zu gestalten. Beschäftige mich damit aber später (Ralf weißt du wie das geht?).
Es erschien mir weniger risikoreich (Donnerstag soll jemand präsentieren) einfach zusätzlich eine standalone gui zusammenzuklicken und damit zu testen. Hat 1 Stunde gedauert. Läuft. Dabei habe ich auch gleich noch den Applet code ein bischen ausgemist ...öhem refaktoriert.
---
Nicht Corba - Applets müssen den Servernamen, Pfad der Datenbank von aussen bekommen? Also nicht wie in Agenten
Database db = AgentContext.getCurrentDatabase() // oder so ähnlich
Bin mir da ziemlich sicher. Das kann man aber ganz einfach lösen, da die Appletparameter in der Notes-Maske auch mit Formelsprache geschrieben werden können. @Subset(@dbName; 1); und @Subset(@dbName; -1);
Die packe ich dann alle in eine HashMap und schicke sie dahin, wo ich sie brauche. Man kann die HashMap dann auch als statisches Property in eine für alle interessierten zugängliche ConfigKlasse legen. Ärgerlich ist nur, daß ich mich gestern nacht genau 4 mal bei den Namen verschrieben habe. ::) Da beginnt einen der jar-Editor von Netbeans zu nerven. Werde glaub ich auf Ant umsteigen. Das hilft aber auch nix in Notes. Da muß man alles von Hand machen. Applet in Ressourcen der db legen. Applet in Seite einbinden. Parameter eintippen (mit Formel).
Vielleicht kann man diesen Notes-Arbeiten auch via Database als xml rausschreiben, xml ändern, aus xml wieder Datenbank machen automatisieren. Ich glaube das ist relativ viel Arbeit.
Btw: Applets in Notes sind wirlich nicht schlecht. In Notes finde ich es oft so nervig, dauernd irgendwelche Dokumente zu öffnen und auf Buttons zu klicken. Mit Applets kann man die GUI eben wesentlich besser auf die wirklichen User-Bedürfnisse customizen.
Swing macht mir auch bedeutend mehr Spaß als vor 1.5 Jahren. Allgemeines Java/OO-Wissen hilft eben für alle Java-Aufgaben :) .
Außerdem ist das wegen VM-Verbesserungen und so wesentlich schneller geworden.
Hier ist eine interessante Diskussion zum Thema Swing vs. SWT:
http://www.logemann.info/day/archives/000008.html
Es existieren eben eine Reihe von Tools/Libraries/Frameworks und alle haben ihre Vor- und Nachteile.
Man kann sich sicher auch noch darüber Gedanken machen, ob man auf Swing noch weitere Helferlein draufsetzt (z.B. existieren frameworks, wo man die GUI als xml Dok beschreibt. Aber da kenne ich mich noch nicht so aus mit.
Axel
Look and Feel von Applets zusammengefaßt:
- Das default look and feel mit dem Sun-Lila und dem TU-dunkelgrau als dominierende Farben, ist IMHO auf Dauer eine schlechte Idee. Es paßt einfach nicht zu den sonstigen Windows-Anwendungen.
Da springt dem Sachbearbeiter der Kaffeelöffel auf der Tasse, wenn er das sieht!!!
- Das in Sun jdk mitgelieferte Windows-L&F ist auch nicht gut. Es funktioniert nur unter Windows und sieht noch nicht mal gut aus. Die ComboBoxen sind riesig.
- Man kann das L&F bis zu einem gewissen (und relativ hohen) Grade Windows-Liker machen.
Ein einfacher Trick ist sowas, bevor die Komponenten gepainted werden.
javax.swing.UIManager.put("ScrollBar.thumb", new Color(204, 204, 204));
Man kann sich die keys herausgeben lassen.
UIDefaults uiDefaults = UIManager.getDefaults();
Enumeration e = uiDefaults.keys();
TreeSet s = new TreeSet();
while (e.hasMoreElements()) {
String val = e.nextElement().toString();
s.add(val);
}
Iterator it = s.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
Man kann aber auch mit dem Trick nicht die Farben aller lightweight components verändern (z.B. die ArrayButtons von JComboBox nicht). Dafür muß man wohl ein eigenes L&F schreiben (wohl nicht so trivial).
- Als Icons sind die von Eclipse super (Eclipse runterladen, nach*.gif suchen, und dann hat man den Ordner). Man hat keine Lizenzprobleme.
- Man kann sich ein wirklich professionelles L&F von JGoodies kaufen. Preis schätzungsweise 500 Euro, bin mir aber noch nicht 100% sicher. Diese Lösung eines unabhängigen deutschen Entwicklers wird auch international in blogs gelobt.
After some technical talks and some more researching and testing with the JGoodies LooksPro Suite, i ve come to the conclusion that a lot of stuff inside this package is coded very well and the idea behind is just good. Its not only the look&feel which makes JGoodies apps look like sophisticated Windows applications, but also the way of handling things like layouts and dispatching best practices.
Also damn interessting were the tech talks with Karsten Lentzsch, the author of the jgoodies packages. He seems to be one of the most dedicated Frontend developers around. Hopefully he will be more involved with J2SE/Swing in the future, i think even the Swing team at sun could use some insights from karsten.
BTW my very own application is beginning to see the ray of lights and using JGoodies makes it look very pretty.
Als Alternative kann man SWT & JFace von IBM nehmen. Das benutzt Standard-Widgets des OS (heavyweight-component Ansatz). Für SWT & JFace existiert aber z. Zt. wenig Toolunterstützung und die Dokumentation ist auch deutlich schlechter als für swing. Es wird aber besser. Leute die beides kennen, sagen das swing vom Entwicklerstandpunkt aus komfortabler ist.
Gruß Axel
Ich habe mir eine primitive Profiling-Klasse für Performance-Messungen gebaut. Dies ist zwar nicht sonderlich komfortabel, aber einfach.
/*
* SimplePerfChecker.java
*
*
*/
package de.aja.system;
/**
*
* @author Axel Janssen
*/
import java.text.*;
public class SimplePerfChecker {
public static long startTime;
public static String nameTest;
/** Creates a new instance of SimplePerfChecker */
public SimplePerfChecker() {
}
public static void start(String name) {
nameTest = name;
startTime = System.currentTimeMillis();
}
public static String stop() {
if (startTime == 0) return "Error SimplePerfChecker: start wurde nicht aufgerufen";
long endTime = System.currentTimeMillis();
double deltaTime = endTime - startTime;
return nameTest + " dauerte " + DecimalFormat.getInstance().format(deltaTime/1000.) + " Sekunden";
}
}
Das kann aus jeder Java-Anwendung aufgerufen werden (auch von Notes-Agenten).
Wird wie folgt aufgerufen:
SimplePerfChecker.start("namensBezeichner");
// [...] code der gemessen werden soll.
System.out.println(SimplePerfChecker.stop());
Wird dann auf die Konsole geschrieben.