% 0:01:54 D4: Wie habt ihr denn das jetzt generell gemacht. Weil, äh, irgendwie, habt ihr da jetzt eigentlich mehr ne SWT-Oberfläche als Eclipse, oder so? Und ähm (!...!) % 0:02:06 D3: Also <**Software-Name**> an sich ist ja SWT-basiert. Der Kalender, da nutzen wir diese (~) Kalender-Komponente (!!...!!) D4: Das ist Swing. D3: Nee, ja, also im Prinzip AWT. D4: Achso, ok. AWT sogar. D3: Und, ja, da gibt's halt diesen SWT-to-AWT-Container-Schnitzel und dadurch wird der im Prinzip eingebunden. Wie dieser SWT-to-AWT-Dings funktioniert kann ich dir allerdings auch nicht genau sagen. Aber den können wir uns nachher auch mal angucken. D4: OK. Aber kann man dann da Kontextmenü und sowas auch einbinden? Jetz nen SWT- Kontextmenü, oder so? D3: Kann ich dir nicht hundertprozentig sagen. Müssen wir uns mal angucken. % 0:02:47 % 0:04:21 D4: Wie lange machst du das jetzt? Drei Monate? D3: Bin jetzt seit 1.7. hier. Programmiert habe ich aber schon Jahre vorher. Angefangen halt mit HTML, PHP, und dann rüber zu Delphi. % 0:04:34 % 0:05:00 D3: Jetzt sitz ich hier bei Java. In zwei Monaten sitze ich wieder in VB. D4: Ach dann bist du drüben oder was? D3: Dann bin ich PS, ja. D4: Ach dann in Service dann, nicht Entwicklung? D3: Naja, Professional Services, die machen auch ein bisschen Entwicklung. % 0:05:17 % 0:05:40 D3: Vor allem, wenn ich bedenke, das SVN-Repository liegt auf <**Computername**>. Im Prinzip ist das nur nen Rüberschaufeln von Daten! % 0:05:47 % 0:06:20 D3: Wir haben ja auch keine Glasfaseranbindung ans Internet. Wir haben ja bloß drei DSL- Leitungen. % 0:06:26 % 0:06:50 D3: Eigentlich, <**Computername**> ist schon nicht schlecht. Der müsste das eigentlich locker. Mal gucken, was hat denn der hier, zwei Kerne <*öffnet Systemsteuerung*> D4: Hier, 2.4 [GHz], zwei mal. % 0:07:29 % 0:09:09 D4: Und das ist jetzt AWT? <*zeigt auf gestartete Anwendung*> D3: Das ist eine AWT-Komponente, ja. D4: Ach du Scheiße. D3: Ach was heißt, ach du Scheiße? Ist halt (!...!) D4: Na dann zeig mir mal kurz die (!!...!!) % 0:09:23 D3: Im Prinzip soll jetzt hier oben noch so ne Toolbar hin. Zeig dir dann gleich mal, wie die beim alten Kalender aussah. D4: Zeig mir auch dann noch mal, was der bis jetzt alles kann (und kurz was der können soll.) % 0:09:37 D3: Jaja, ich zeig dir am besten erstmal wo es hin (!...!) wo die Reise hingehen soll <*öffnet wieder IDE*> Muss ich grad mal gucken, wo das hier mit den Menüpunkten war, genau, (#Calendar#), ok, doch nicht, (#CalendarWeek#), <*öffnet Konfiguration eines ExtensionPoints*> genau (#CalendarTestView#), und dann, das alte hieß, genau (##CalendarView##), genau. <*ändert Konfiguration eines ExtensionPoints*> % 0:10:11 D4: Ist das jetzt noch nen Eclipse-View? Nee? D3: <*zuckt mit den Schultern, schaut lächelnd zu D4*> D4: <*schnaubt*> D3: Ich hab wirklich keine Ahnung von wegen ExtensionPoints und so, da bin ich nicht wirklich konform mit, also da kann ich dir keine große Information geben. <*startet Anwendung neu*> D4: <*klickt mit Kugelschreiber, schaut auf Bildschirm*> % 0:10:26 % beide warten darauf, dass die Anwendung startet % 0:10:59 D4: Nee, ich hatte hier gerade noch mal in dem Buch gelesen, also, dass du das ja dann auch so ähnlich machen könntest, dass du dann (!...!) zeig noch mal das Eclipse D3: <*navigiert in Anwendung zu Kalenderansicht, Fehlermeldung wird angzeigt, klickt Fehlermel- dung weg, wechselt zur IDE*> D4: Dass du hier so Contributions hast und wenn du dann den Kalender aktivierst, dass die dann halt auch hier reinkommen. Aber ich weiß halt nicht ob generell überhaupt ne Toolbar geplant ist? D3: Das kann ich dir auch nicht sagen. Bin ja auch erst seit drei Monaten hier. <*wechselt zur Anwendung*> D4: Aber wo soll denn die dann hin, hier oder was? D3: Eigentlich dachte ich, genau, sollte die hier so hin. <*hovert schmale Leiste über dem Kalender*> und eigentlich, weiß auch gar nicht warum sie jetzt nicht <*klickt herum, Fehlermeldung erscheint*> (!...!) Was haben wir hier überhaupt für'n Fehler? D4: (#ClassCastException#) D3: (#Cannot be cast to CalendarTest#) achso <*schließt Fehlermeldung*> wahrscheinlich <*schließt Anwendung, geht zur IDE zur ExtensionPoint-Konfiguration*> (#CalendarView#) D4: Für was sind jetzt hier die Navigation-Sachen, also sind das Actions, oder? D3: Mhm. D4: Sind das Actions? Die dann (!...!) wo erscheinen die dann? D3: Na die werden dann hier durch diese Klasse verarbeitet <*selektiert Klassennamen einer Action*> und dann wird halt die entsprechende Methode aufgerufen, also da gibt's ne (!...!) wie heißt die? <*öffnet Package Explorer*> nee, nicht hier, sondern (!...!) <*navigiert zu einer Methode*> genau, aber ist noch nicht die (!...!) Moment <*sucht weiter*> D4: Na die muss dann irgendnen Interface erfüllen. % 0:12:52 D3: Ja, gibt's auch. <*öffnet Datei*> (#CalendarTestView#) <*setzt Cursor in Zeile mit LicenseKey und scrollt nach unten*> D4: (#LicenseKey#)? D3: <*markiert drei Methoden*> Genau, die werden im Prinzip aufgerufen. Und von da aus, <*markiert einzelne Zeile*> geht's dann in die entsprechende Klasse, also bei mir jetzt in den Test-Kalender. <*scrollt hoch, LicenseKey ist wieder sichtbar*> (#viewpart#), da isser, der Kalender. OK, jetzt haben wir den natürlich wieder geschlossen. D4: Ah, LicenseValidatorist von der Komponente, oder was? D3: Ja, richtig. % 0:13:21 D3: Die Komponente ist halt gekauft worden, und die haben da so'n setLicenseKey. Den siehst du hier auch noch öfters. Fast jede Komponente, die will noch mal ihren License-Key haben. D4: Wie? Musst du den kopieren, oder was? D3: Inwiefern kopieren? Das ist im Prinzip so'n String (!!...!!) D4: Nee, aber, wenn du ne neue Klasse machst, dass du das dann jedes Mal hast, oder (!...!) D3: Du hast im Prinzip hier (!...!) ja, können wir ja einfach mal nach googeln <*startet Textsuche*> zum Beispiel hier, die MonthDateAreakriegt den, und (!...!) war's das schon? OK, eigentlich kriegen die noch mehr Komponenten. D4: Wie, da musst du es für jede Komponente den gleichen LicenseKey setzen? D3: Ähm, war ich eigentlich der Meinung, aber kann natürlich sein, dass das schon veraltet ist. Muss ich gerade mal eben gucken. <*scrollt*> OK, dann hat sich das schon geändert. Gut, dann war es doch nur diese eine Komponente, sehr schön. Hätte mich auch gewundert, wenn jetzt jede Komponente das hat. Weiß gar nicht, was ist das überhaupt? 'Nen DateAreaBean? <*hovert Variable, Tooltip er- scheint*> (#DateAreaBean#), ja. (..) OK, so, wo waren wir stehen geblieben? <*sieht Stacktrace am unteren Bildschirmrand*> Die Exception, genau. <*liest in Stacktrace*> (#Cannot be cast to CalendarTestView#) achso, (#AbstractOpenCalendarView#), müssen wir hier natürlich auch ändern, in die CalendarView <*ändert Statement, Fehlermeldung erscheint*>. % 0:15:02 D3: Hm? <*öffnet Details der Fehlermeldung*> Checkstyle funktioniert nicht, ok. Dann scheißen wir mal auf Checkstyle, würde ich sagen . D4: % 0:15:15 D3: <*versucht Anwendung zu starten, Fehlermeldung erscheint*> Achso jetzt haben wir noch nen ParseError. D4: Du hast hier <*zeigt auf Bildschirm*> das musst du noch. D3: Mhm. D4: Hier, da ist doch immer noch ‘Test'. D3: Ach. <*ändert Code*> Daran sollte es aber eigentlich nicht (!...!) <*Fehlermeldung erscheint*> doch, cool! Alles klar. D4: Mach noch mal ‘Organize Imports', dann hast du die weg. D3: Macht er eigentlich beim Speichern automatisch. Ja. D4: Hast du so eingestellt, oder? D3: Also auf meinem Rechner ja. Wie es hier eingestellt ist, weiß ich nicht. Aber ich denke mal genauso. D4: Weil standardmäßig ist nichts, nichts eingestellt. D3: <*Fehlermeldung erscheint beim Versuch zu speichern.*> Hm? D4: Och, was ist das denn? D3: Was hat er denn? Er buildet doch gar nicht. Jetzt haben wir hier schon wieder nen Error. Achso. D4: OK. D3: Ah nee, das tue ich mir jetzt nicht an, dass Ganze umzustricken. Ich zeig's dir woanders. D4: Aber was ist denn (!...!) D3: <*macht Code-Änderungen rückgängig*> Dann schauen wir uns einfach die Toolbar bei der Wiedervorlage an. Weil bis wir das jetzt alles geändert haben. D4: Hast du das auf deinem Rechner schon geändert, oder? D3: Naja, das ist ja die alte Version, die ich gerade wiederhergestellt habe, der alte Kalender. Und wir machen jetzt hier (##CalendarTestView##), ok. Dann zeige ich dir's in der Wiedervorlage, da ist die glaube ich schon eingebaut die Toolbar. D4: Aber das ist jetzt, gut, das ist ja immer noch nen Eclipse-View, ne? D3: Mhm. D4: Das ist ja abgeleitet von dem ExtensionPoint, oder erfüllt den ExtensionPoint. D3: Mhm. Kann's ja auch. Hier ist ja jetzt wieder die CalendarTestView drin. D4: Aber deine View ist jetzt der gesamte Kalender, oder? D3: Ja. D4: Und warum kein Editor? Ach die Editoren habt ihr ganz verworfen, oder? D3: Wir arbeiten hier, also ich arbeite hier komplett unabhängig von dem eigentlichen Produkt. <*öffnet Quellcode*> Das ist hier im Prinzip von nem Panelund hier ist im Prinzip schon alles AWT. Im Prinzip haben wir angefangen damit (!...!) es gibt Demos von diesem ( ~ ) Kalender. Und da habe ich mir die Demo, die am dichtesten an unseren Kalender rankommt, übernommen, hab den hier rein kopiert und dann im Prinzip Stück für Stück angepasst. Weil Problem war ja am Anfang, ich hatte keine Ahnung von Java und mit irgendwas musste ich ja anfangen. D4: Achso, hast du vorher noch gar kein Java gemacht? D3: Nee, ich war vollkommen unbeleckt in Sachen Java. Deswegen ist der Code auch total für'n Arsch. Wenn du hier siehst, wie viele Zeilen wir inzwischen haben (!...!) D4: God-Methods und God-Klassen, oder? D3: Das ist (!...!) ja, 1917, müsste man mal refactorn. <*wechselt zur Anwendung*> So, Wiedervorlage. Obwohl, bei Positionabsrechnung hat man's auch gesehen. % 0:18:17 D3: <*hovert Toolbar im Bereich Wiedervorlage*> Im Prinzip, so 'ne Toolbar. Die haben sie jetzt also da oben hingemacht. D4: OK, und das sind jetzt (!...!) ist das jetzt ne Toolbar oder Coolbar oder sowas und dann die eigenen Widgets drin, oder was ist das? D3: Ähm, ich vermute, ja. Sicher sagen kann ich es dir auch nicht, weil wie gesagt ich hab das auch noch nicht gemacht bisher. Müssen wir uns einfach mal angucken, wie das in der Wiedervorlage zum Beispiel geschehen ist. D4: Aber, ähm, soll es dann nicht mal Ziel sein, dass du immer diese Dinger hast? D3: Ja, genau. D4: Aber dann ist doch von dem Kalender hier (!!...!!) D3: Ja, das war Quatsch was ich dir vorhin erzählt habe. D4: Dann soll das ja da auch oben hin, ne? D3: Wir machen das dann nicht in diese schmale Leiste hin, sondern doch da oben. % 0:18:57 % 0:19:27 D3: Hast du sowas schon mal gemacht, so ne Toolbar-Erstellung? D4: Ich hab mir gerade hier (!...!) das hab ich mir mal im Urlaub reingezogen das Buch, aber wenn du das natürlich alles nicht nachprogrammierst, dann vergisst du das alles, aber ich hab's mir gerad noch mal durchgelesen. Also zumindest stehen hier die Standardschritte drin. % 0:19:49 % 0:21:23 D4: Wer hat denn das gemacht? D3: Die ExtensionPoints? D4: Nee, generell die ToDo-Liste? Also das mit oben einfügen und so. % 0:21:30 % 0:40:03 D3: Ähm, okay? Ich sehe, du bist mehr mitgekommen als ich Ja, dann probier mal. % 0:40:18 % 1:14:25 D4: <*benennt Methodenparameter in "lista" um, IDE markiert zwei Compiler-Fehler*> OK, also da holt er sich noch die (!...!) Objekte dann, wahrscheinlich <*macht Umbenennung rückgängig*> D3: Warum hattest du das gerade umbenannt in lista? D4: Nee, nur um zu gucken ob der (!...!) was er hiermit macht. D3: Achso. % 1:14:44 D4: Ist normalerweise gar nicht meine Vorgehensweise. Normalerweise schreibe ich echt immer nen Test. D3: Machen wir hier fast gar nicht. Auch wenn wir es eigentlich sollten. Aber, naja. % 1:15:04 % 1:24:24 D4: Ja, willst du dann noch mal machen, oder? D3: Ich glaube, du bist da mehr involviert in diese ganze Sache. Ich bin da (!...!) für mich ist das schon oberste Wissenskante . % 1:24:34 % 1:29:55 D4: Warum steht denn hier AbstractListnoch davor? <*selektiert und löscht den Präfix, die IDE meldet einen Compilerfehler*> Nee <*macht Änderung rückgängig*> Achso, ok. Weil wir in der anonymen Klasse sind. D3: In 'ner anonymen Klasse? Was ist ne anonyme Klasse? D4: <*selektiert das newStatement, das den Anfang der anonymen Klasse markiert*> Na, sobald du hier, z.B. so nen SelectionAdapterimplementierst, dann ist das ja ne anonyme Klasse <*selektiert den Rumpf der anonymen Klasse*> weil die Klasse keinen Namen hat. D3: Achso, ja, richtig. D4: Deshalb hatte ich mich gerade gewundert, weil ich das nicht gesehen hatte. Und wenn ich jetzt natürlich this mache <*entfernt Präfix nochmal*>, dann ist das der SelectionAdapter, also bzw. die Implementierung davon. <*fügt Präfix wieder ein*> % 1:30:25 D3: Ja, ist richtig. D4: Gut, warum das jetzt ne listPreviewhat, müssen wir ja nicht verstehen . <*öffnet nächsten Compiler-Fehler, hovert Fehler-Meldung*> D3: ‘Import' einfach. D4: Jetzt müsste ich ja nen Import machen können <*wendet vorgeschlagene Autokorrektur an*> ja. % 1:30:49 D4: Kennst du das denn, mit dem OSGi-Class-Loading? D3: Class was? Nicht wirklich, nee. D4: Soll ich kurz sagen, oder? D3: Na, ja klar. D4: [...] Jedes Bundle [...] hat nen eigenen ClassLoader und der kann nur Klassen aus anderen Bundles laden, wenn [...] das andere Bundle, wo du die Klasse haben willst, davon das Package exportiert und wenn dein eigenes Bundle das explizit importiert. Und dann hast du hier halt immer in den Manifest-Dateien [...] da kannst du einmal Import-Package machen [...] dann sagst du, dass dieses Package haben willst. D3: M-hm. D4: [...] und normalerweise sollte man immer Import-Package nehmen, hier ist es immer Require-Bundle. So bestimmst du halt den logischen Namen von dem Bundle was du importieren willst, so bist du explizit von diesem Bundle abhängig. Also du kannst jetzt nicht sagen, ich nehme das Bundle weg und nehme dann ein anderes Bundle, das auch dieses Package exportiert, dann würde sich OSGi dieses Bundle nehmen. [...] Deswegen ist Import- Package eigentlich immer schöner. Weil mit Require-Bundle importierst du meistens auch mehr Packages als du brauchst. [...] Dann kannste halt zur Laufzeit nichts mehr austauschen. Naja, aber, egal. % 1:35:15 D4: Äh, so <*öffnet nächsten Compiler-Fehler*> ach jetzt musste BusinessAction (!...!) na gut <*öffnet nächsten Compiler-Fehler, lässt automatisch Methodenstummel erstellen*> % 1:35:42 D4: Also, sag, wenn du jetzt machen willst, ne? D3: Nee, mach mal erst mal weiter. Ich sag, wenn ich wieder voll drin bin. Dann schrei ich schon. % 1:35:52 % 1:36:35 D4: Kennst du denn das Pattern? [...] Weil das ist ja so ne Art Template Method. Also ich hab das hier halt ausgelagert, die gemeinsame Logik. <*navigiert zu abstrakter Klasse, selektiert Aufruf einer abstrakten Methode*> D3: H-hm. D4: [...] internalExecuteist ja praktisch meine Template Method. [...] Und dann kannst du halt sehr schön immer Sachen, die allgemein sind, auslagern und machst dann für die Sachen, die du noch nicht weißt, dann die abstrakte Methode, und die implementieren dann einfach deine Oberklassen. D3: H-hm. D4: Ist halt sehr schön, weil du kein Copy-Paste machen musst. D3: Richtig. % 1:37:58 % 1:41:17 D4: Ja aber, wenn du willst, kannst du jetzt auch (!!...!!) D3: Ja [...] lass uns mal kurz die Seiten tauschen. % 1:41:22