Mittwoch, 17. Dezember 2014

Alte Dateiformate: .mdi

Beim Aufräumen meiner Festplatte bin ich über eine Datei mit der Endung .mdi gestolpert. MDI steht hier für Microsoft Office Document Imaging, ein proprietäres Format, das mit Office 2010 eingestellt wurde. Ein Doppelklick bewirkt also in Verbindung mit modernen Office-Versionen gar nichts mehr. Allerdings gibt es von Microsoft ein Commandline-Tool, das solche Dateien in TIFF umwandeln kann. Die Daten sind also dank dieses MDI to TIFF File Converters nicht verloren. Der Setup-Assistent installiert das Programm nach C:\Program Files (x86)\modiconv. Bitte bei der Nutzung in der Eingabeaufforderung beachten, dass der Vorgang nur startet, wenn der Parameter –log … mit angegeben wird. Sonst werden nur die Aufrufparameter ausgegeben. Wenn Sie das Tool nicht mehr benötigen, können Sie es wie gewohnt über die Systemsteuerung deinstallieren.

Sonntag, 14. Dezember 2014

Tipp: Navigationsproblem in der Android-Kontakte-App lösen

Meine App TKBirthdayReminder delegiert das Anlegen von Kontakten an die dafür zuständige App. Das – immer noch geniale - Intent-System macht dies möglich. Nachdem der Anwender einen neuen Kontakt hinzu gefügt hat, erscheint in der App ein Dialog, der das Geburtsdatum abfragt. So zumindest die Theorie. Ganz offenkundig hat das schon seit geraumer Zeit nicht mehr funktioniert. Da ich das Programm etwas fitter für Lollipop machen wollte, habe ich mal wieder damit  gespielt, und bin prompt in das Problem gelaufen. Die Doku weiß hierzu folgendes zu berichten:

In Android 4.0 (API version 14) and later, a problem in the contacts app causes incorrect navigation. When your app sends an edit intent to the contacts app, and users edit and save a contact, when they click Back they see the contacts list screen. To navigate back to your app, they have to click Recents and choose your app.

Glücklicherweise folgt postwendend die Lösung:

To work around this problem in Android 4.0.3 (API version 15) and later, add the extended data keyfinishActivityOnSaveCompleted to the intent, with a value of true. Android versions prior to Android 4.0 accept this key, but it has no effect.

Also ein simples…

editIntent.putExtra("finishActivityOnSaveCompleted", true);

Freitag, 12. Dezember 2014

HTML-Dialoge mit Feinschliff

Erinnern Sie sich noch an meine Frage aus meinem vorangehenden Post, was mit dem dort gezeigten Dialog nicht 100%-tig passt? Gucken Sie sich mal diese Version an:

Screenshot: HTML-Dialog mit "richtigen" Font

Es ist die Schrift. Die hier hat keine Serifen.

Swing beizubringen, in HTML nicht Times New Roman zu verwenden, ist einfach. Zum einen gibt es die Client Property HONOR_DISPLAY_PROPERTIES. Außerdem kann die Zeichensatzfamilie auch in HTML selbst gesetzt werden:

<body style="font-family: ...">

Freitag, 5. Dezember 2014

Breite von Dialogen

Was ist eine geeignete Breite für Dialoge? Die Frage mag sich komisch anhören. Was ich meine, ist folgendes… Nehmen wir an, Sie haben eine Menge Fließtext, zum Beispiel die Linzenzbestimmungen Ihrer Software. Um die anzuzeigen, bietet es sich an, sie in Swing in eine JEditorPane zu packen, die wiederum von einer JScrollPane (denken Sie an meinen vorherigen Post) gekapselt wird. Mit der JEditorPane können prima einfache HTML-Texte angezeigt werden, deren Links sogar anklickbar sind. Die Breite der Komponente ergibt sich aus der Breite der scroll pane; diese bezieht sie vom Layoutmanager des übergeordneten Containers. Hat der Dialog also in sich eine passende Größe, bekommt auch der Fließtext eine geeignete Breite. Was aber, wenn ein entsprechendes ordnendes Element fehlt?

Screenshot: viel zu breiter Dialog

Solche Monster möchte und sollte man niemandem zumuten. Zumal die Lösung recht einfach ist. Die Basis vieler Swing-Komponenten, java.awt.Component, kennt seit Java SE 5 die Methode setPreferredSize(). Der kann man eine bevorzugte Größe mit auf den Weg geben.

Nur – sind wir jetzt wirklich weiter? Woher sollen wir im Zeitalter von Hoch-DPI-Anzeigen passende Pixelwerte nehmen? Mein pragmatischer Vorschlag ist, sich am verwendeten Zeichensatz und einem Stück Text mit geeigneter Länge zu orientieren. Ich habe das in Notes and Tasks umgesetzt, der entsprechende Code ist eingecheckt. Als Text verwende ich den berühmten Blindtext Lorem ipsum: Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy. Hier die Methode, die die Größe berechnet:

 private static final String LOREM = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy";  
   
 /**  
  * Gets the rectangle for one line of lorem ipsum  
  *  
  * @param font font  
  * @return size  
  */  
 public static Rectangle2D getSizeForLoremIpsum(Font font) {  
     Graphics2D g = (Graphics2D) Application.getInstance().getGraphics();  
     return font.getStringBounds(LOREM, g.getFontRenderContext());  
 }  

Und so wird sie verwendet:

 Rectangle2D r = FontUtilities.getSizeForLoremIpsum(pane.getFont());  
 pane.setPreferredSize(new Dimension((int) r.getWidth(), 12 * (int) r.getHeight()));  

Screenshot: Dialog mit geeigneter Breite

Sieht hübsch aus, oder?

Anmerken möchte ich noch, dass sich die grundsätzliche Idee auch in anderen Frameworks prima umsetzen lässt. Gefällt Ihnen meine Idee? Schreiben Sie mir.

Sonntag, 30. November 2014

UI-Schluckauf, Ausgabe 30.11.14

Regelmäßige Leser dieses Blogs wissen ja, dass ich gelegentlich auf UI-Faux pas hinweise, um Entwickler zu sensibilisieren. Heute ist es wieder einmal soweit. Gesehen im (nach wie vor grandiosen) True Image von Acronis. Zunächst… der Klassiker… ja wo isses denn?

Screenshot: Acronis True Image 2015 für PC (1/2)

Lokalisierungen sprengen oft Grenzen (unsichtbarer) Container. Warum bei so viel Platz überhaupt etwas fehlt, ist zwar ein Rätsel. Eine pragmatische Lösung wäre zumindest (wenn es schon feste Boxen sein müssen), den Inhalt scrollbar zu machen. Das scheint hier nicht möglich. Übrigens hat die Größe des Anwendungsfensters hier keine Auswirkungen. Ja, bzw. nein, natürlich lassen wir nicht den Text über die gesamte Breite fließen. Aber abschneiden sollten wir ihn trotzdem nicht.

Zweitens… …äh.. ja, wer bist du denn?

Screenshot: Acronis True Image 2015 für PC (2/2)

Haben Sie das rotierende Kreischen bemerkt? Nein? Gucken Sie nochmal… Haben Sie eine Ahnung, wofür das ist? Ich auch nicht. Es mag sein, dass in bestimmten Situationen ersichtlich ist, wofür es steht. Ich habe aber nicht herausbekommen, was dazu passieren muss. Merke: jede Komponente sollte einen erkennbaren Sinn haben. Keine Funktion – keine Komponente.

Was halten Sie von meinen Findlingen? Schreiben Sie mir…

Donnerstag, 20. November 2014

Lektüretipp: Android 5 in der aktuellen iX

In der seit heute erhältlichen Ausgabe 12/2014 der iX stelle ich spannende neue Funktionen in Android 5 (Lollipop) für Anwender und Entwickler vor.

Leider hat an drei Stellen das Fehlerteufelchen seine Spuren hinterlassen:

  1. Im Satz Sie lässt sich über die Attribute elevation und translation... muss es translationZ heißen.
  2. Bei Listing 1 ist der Dateiname falsch, es ist nicht ix.html, sondern natürlich ix.xml.
  3. Der Begleittext zu Abbildung 3 ist nicht ganz korrekt, der Screenshot zeigt nicht den Batterie Historian, sondern die Aufrufseite des Battery Savers. Der Fließtext hingegen ist korrekt.

Ich wünsche trotzdem viel Spaß bei der Lektüre des Artikels.

Sonntag, 2. November 2014

Eclipse-Quicktipp: Pextools

Manchmal sind es ganz kleine Dinge, bei denen man sich fragt, warum sie nicht einfach da sind. Zum Beispiel das Anzeigen des Verzeichnisses, in dem eine bestimmte Datei liegt. Oder das Öffnen einer Shell mit diesem Verzeichnis als Start. Oder das Ablegen des Pfades auf dem Clipboard?

Sei’s drum, das Schöne an Eclipse sind die unzähligen Plug-ins, die solche Dinge unkompliziert nachrüsten. Zum Beispiel Pextools.

Screenshot: Pextools

Die Installation via Update-Site ist unkompliziert. Das Plug-in erweitert das Kontextmenü des Package Explorers um das Untermenü PexTools.

Freitag, 31. Oktober 2014

Batteriestatus im Android-Emulator

Für einen Artikel wollte ich einen Screenshot des neuen Battery Savers von Lollipop machen. Eigentlich kein Ding. …sollte man meinen… Wie ich herausgefunden habe, muss aber zunächst in der Konfiguration des AVDs hw.battery=yes eingetragen werden. Dann kann man in einer Telnet-Sitzung (zum Beispiel mit PuTTY, localhost 5554) den Befehl power ac off eingeben. Nun steht der Battery Saver zur Verfügung.

Screenshot #1

Screenshot #2

Screenshot #3

Screenshot #4

Bei aktivierter Stromsparfunktion erscheinen Statuszeile (und ggf. die Buttonleiste am unteren Rand) in orange. Ein letzter Tipp: setzen Sie in den PuTTy-Einstellungen unter Telnet den Telnet Negotiation mode auf Psssive.

Mittwoch, 15. Oktober 2014

Gut oder nicht gut?

Heute hat das Java-AutoUpdate eine neue Version der JRE installiert. Dabei ist mir zum ersten Mal folgender Dialog begegnet:

Screenshot: Warnhinweis auf zu alte Java-Versionen

Kennen Sie den?

Ein Klick auf Siehe Liste mit Java-Versionen zeigt bei mir:

Screenshot: Liste veralteter Java-Versionen

Tatsächlich gäbe es einen neueren Patchlevel für Java 7. Nur, warum wird nicht einfach angeboten, den zu installieren? Die Aufforderung zur Deinstallation halte ich für verfrüht, zumal in der Oracle Java SE Support Roadmap Stand 16. April 2014 öffentliche Updates bis mindestens April 2015 in Aussicht gestellt werden.

Was denken Sie?

Sonntag, 12. Oktober 2014

Back to … BASIC

Ein kleiner Wochenendend-Spaß. Als die Pixel noch groß wie Bauklötzchen waren.
 10 LET FARBE = 2  
 11 MODE(1) : COLOR FARBE,0  
 12 LET X = 64  
 13 LET Y = 32  
 20 IF X < 0 THEN LET X = 127  
 21 IF X > 127 THEN LET X = 0  
 22 IF Y < 0 THEN LET Y = 63  
 23 IF Y > 63 THEN LET Y = 0  
 24 SET(X,Y)  
 40 LET A$ = INKEY$  
 41 IF A$ < "1" OR A$ > "4" THEN GOTO 50  
 42 LET FARBE = ASC(A$) - 48  
 43 COLOR FARBE  
 44 GOTO 20  
 50 IF A$ = "A" THEN LET X = X - 1 : GOTO 20  
 51 IF A$ = "S" THEN LET X = X + 1 : GOTO 20  
 52 IF A$ = "W" THEN LET Y = Y - 1 : GOTO 20  
 53 IF A$ = "Z" THEN LET Y = Y + 1 : GOTO 20  
 98 IF A$ = " " THEN GOTO 999  
 99 GOTO 40  
 999 END  

Screenshot des Emulators VZEM

Das Malprogramm in Aktion

Ja, damals (1983) konnte man sich als 13-Jähriger gut damit die Zeit vertreiben. Dem Familien-Farbfernsehgerät die drei öffentlich-rechtlichen Kanäle genommen, stattdessen ein Ding namens Homecomputer daran angeschlossen. Und eine völlig neue Welt entdeckt.

Samstag, 11. Oktober 2014

Benachrichtigungen auf Wearables

In meinem vorherigen Post hatte ich Ihnen berichtet, dass Min Time nun Benachrichtigungen zum zeitlichen Verlauf eines Talks ausgibt, und dass diese auch auf Android Wear-Geräten erscheinen. Letzteres ist grundsätzlich unspektakulär, weil es – eigentlich – von Haus aus geschieht. Natürlich wäre dies nicht bloggenswert, wenn es nicht ein entscheidendes Caveat gäbe. Hierzu ein Beispiel:
1:  NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(  
2:      context).setPriority(NotificationCompat.PRIORITY_HIGH)  
3:      .setContentTitle(context.getString(R.string.app_name))  
4:      .setContentText(str)  
5:      .setOngoing(true)  
6:      .setWhen(resumed)  
7:      .setSmallIcon(R.drawable.ic_launcher_mintime)  
8:      .setContentIntent(notificationClickedIntent);  
9:  NotificationManagerCompat notificationManager = NotificationManagerCompat  
10:      .from(context);  
11:  notificationManager.notify(CountdownActivity.NOTIFICATION_ID,  
12:      notificationBuilder.build());  
Fällt Ihnen an diesem Stück Quelltext irgendetwas auf? Wer Android kennt, wundert sich vielleicht, dass nicht mehr der Builder aus der Android-Standardbibliothek verwendet wird. sondern NotificationCompat.Builder. Das ist Absicht. Tatsächlich fordert Google in der Dokumentation ausdrücklich dazu auf. Im Klartext bedeutet dies, dass man die Bibliothek android-support-v4.jar einbinden muss. Obiger Code erzeugt tatsächlich eine Benachrichtigung; dummerweise erscheint die aber nicht auf einem Wearable. Den Grund habe ich nach langer Suche in dem Posting How to Create a Custom Ongoing Notification on Android Wear von Carlos Hwa gefunden. Wohlgemerkt, Google schreibt diesbezüglich (Stand 11.10.14) nichts:
Screenshot der Seite http://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html
Wenn man es weiß, ist die Lösung einfach. Aus meinem Quelltextfragment einfach setOngoing() entfernen, und die Benachrichtigung erscheint wie erwartet auf der Uhr. *AUTSCH* Die Nutzung des Kompatibilitätspakets verläuft zum Glück schmerzfrei. Dass die Größe der App zunimmt (von 0,11 MB auf 0,37 MB im Falle von Min Time) ist unschön, aber vor dem Hintergrund aktueller Bandbreiten sicher zu verschmerzen. Übrigens hatte die Integration des Jars eine Zeitlang den Effekt, dass eine App angeblich für viele (> 30) Sprachen lokalisiert war, obwohl es in der eigentlichen Anwendung gar keine Vorkehrungen hierfür gab (wohl aber im Jar). Das scheint aber behoben worden zu sein.

Freitag, 10. Oktober 2014

Neues von Min Time

Ich hatte Lust, mal wieder an Min Time zu schrauben. Hier zwei Teaser-Fotos; die App landet demnächst in aktualisierter Version im Store.

Min Time auf einer LG G

Screenshot: Min Time-Benachrichtigung

Dabei “durfte” ich auch wieder ein paar Android-Merkwürdigkeiten kennenlernen; lassen Sie sich überraschen.

Sonntag, 5. Oktober 2014

Geschichte der Homecomputer. Spielen.

Für meinen Vortrag Geschichte der Homecomputer habe ich heute ein paar Fotos gemacht. Hier das Spiel Dragonriders of Pern aus dem Jahr 1983. Leider kann ich keine Bilder des laufenden Spiels zeigen, weil ich zwar einen 800XL, aber kein Diskettenlaufwerk, habe.

Dragonriders of Pern 1

Dragonriders of Pern 2

Dragonriders of Pern 3

Hier nun das Spiel Crossbow. Diesmal als Modul.

Crossbow 1

Crossbow 2

Crossbow 3

Zum Schluss noch zwei Joysticks. Ein Competition Pro, und ein eher seltenes Stück, ein Speedking.

Competition Pro

Speed King

Applets mit selbst signierten Zertifikaten wieder ausführbar machen

Seit Java SE 7 Update 51 (also schon eine ganze Weile) werden Applets und Web Start-Anwendungen mit selbst signierten Zertifikaten blockiert. In einer idealen Welt könnte ich mich beim Hersteller als Entwickler registrieren, würde mich entsprechend legitimieren, und bekäme dafür im Gegenzug ein “echtes” Code Signing-Zertifikat für meine Java-Anwendungen. …es soll ja Plattformen geben, auf denen es tatsächlich so läuft.

Smiley

Leider ist der von Sun vor vielen Jahren begonnene Java Store nie weiter verfolgt worden (für die Nostalgiker unter uns: ich meine Project Vector). Deshalb bleibt Entwicklern eigentlich nur, sich selbst ein Zertifikat zu besorgen. Aber mal ehrlich, unter 150 EURO geht gar nichts, und das nur für ein paar Open Source-Programme? Ich gebe zu, mir ist das zu viel. Deshalb hier noch ein kurzer Walkthrough, wie man die Java-Client-Sicherheit entsprechend rekonfiguriert. Ausgangspunkt ist das Java Control Panel:

Screenshot: Java Control Panel

Auf der Registerkarte Sicherheit befindet sich die zunächst leere Liste der ausgenommenen Websites:

Screenshot: Registerkarte Sicherheit

Die Schaltfläche Siteliste bearbeiten öffnet einen weiteren Dialog, Liste der ausgenommenen Websites.

image

Nach dem Anklicken von Hinzufügen geben Sie die URL der Seite, die ein Applet enthält, ein. Falls die Adresse “nur” http als Protokoll verwendet, erscheint folgende Warnung:

Screenshot: Sicherheitswarnung - HTTP Websites

Klicken Sie auf Fortfahren. Danach schließen Sie den Dialog Liste der ausgenommenen Sites mit OK. Das Java Control Panel sieht nun folgendermaßn aus:

Screenshot: Java Control Panel mit einer Site-Ausnahme

Schließen Sie das Kontrollfeld mit OK. Wenn Sie die Website besuchen, erscheint wieder eine Warnmeldung:

Screenshot: Warnmeldung Nummer 2

Setzen Sie ein Häkchen vor Ich akzeptiere das Risiko und möchte diese Anwendung ausführen, und klicken dann auf Ausführen.

Nicht schön, aber immerhin kann man auf diese Weise seine Applets und Web Start-Anwendungen weiter benutzen.

Freitag, 3. Oktober 2014

Eclipse DTP

DTP steht hier (ausnahmsweise) nicht für Desktop Publishing, sondern für Data Tools Platform. Das Einbinden von Datenbanken in Eclipse ist mit wenigen Handgriffen erledigt. Welche dies sind, zeige ich Ihnen in der folgenden Bilderstrecke.

Zu installierende Pakete auswählen

Zu installierende Pakete auswählen

Treiber-Definition auswählen oder erstellen

Treiber-Definition auswählen oder erstellen

Einen Treiber wählen; hier für Derby bzw. JavaDB

Einen Treiber wählen; hier für Derby bzw. JavaDB

Korrespondierendes Jar auswählen

Korrespondierendes Jar auswählen

In die Perspektive Database Development wechseln

In die Perspektive Database Development wechseln

Neues Verbindungsprofil anlegen (1/2)

Neues Verbindungsprofil anlegen (1/2)

Neues Verbindungsprofil anlegen (2/2)

Neues Verbindungsprofil anlegen (2/2)

Neues Derby-Verbindungsprofil anlegen (1/2)

Neues Derby-Verbindungsprofil anlegen (1/2)

Neues Derby-Verbindungsprofil anlegen (2/2)

Neues Derby-Verbindungsprofil anlegen (2/2)

Mit einer Datenbank verbinden oder die Verbindung trennen

Mit einer Datenbank verbinden oder die Verbindung trennen

Ein Schema anlegen

Ein Schema anlegen

Eine .sql-Datei anlegen (1/2)

Eine .sql-Datei anlegen (1/2)

Eine .sql-Datei anlegen (2/2)

Eine .sql-Datei anlegen (2/2)

SQL-Anweisungen absetzen

SQL-Anweisungen absetzen

Eclipse-Tipp: Schriftgröße bequem einstellen

Man traut es sich ja kaum zu schreiben, aber auch im Jahre 2014 muss man in Eclipse einen Einstellungsdialog öffnen, um die Schriftgröße in einem Editor zu verändern. Naja, man müsste, wenn es nicht findige Entwickler gäbe, die solche Probleme mit einem Plug-in lösen. eclipse-fonts gibt es schon eine Weile, und sehr wahrscheinlich kennen es Viele auch schon. Trotzdem hier der Link auf die Projekthomepage auf Google Code.

Donnerstag, 2. Oktober 2014

Java 9 und JSON

Ich bin eigentlich eher durch Zufall über die Ankündigung gestolpert, dass in Java 9 eine leichtgewichtige JSON-API Einzug halten soll: JEP 198: Light-Weight JSON API. Im aktuellen Early Access Releases Build b32 konnte ich noch nichts davon entdecken. Was mich hierbei vor allem umtreibt, ist die Frage “Warum?”. Mit JSR 353: Java API for JSON Processing und der zugehörigen Referenzimplementierung gibt es doch eine durch den JCP legitimierte JSON-Bibliothek. Und die ist ja sogar in Java EE 7 enthalten. Im Netz findet man derzeit relativ wenig Infos zu den Hintergründen. Haben Sie etwas darüber gelesen? Teilen Sie Ihre Links mit mir…

Mittwoch, 1. Oktober 2014

…was da wohl drin ist…?

Ein neues Spielzeug?

Ein neues Spielzeug?

Auch die 5. Auflage macht einen Autor noch stolz.

Auch die 5. Auflage macht einen Autor noch stolz.

Ich freue mich sehr, Ihnen eine neue Ausgabe von Einstieg in Eclipse zeigen zu können.

Ich freue mich sehr, Ihnen eine neue Ausgabe von Einstieg in Eclipse zeigen zu können.

Ich bin sicher, auch alte Eclipse-Hasen finden hier frisches Futter ;-)

Ich bin sicher, auch alte Eclipse-Hasen finden hier frisches Futter ;-)

Samstag, 27. September 2014

TKWeek ab sofort kostenlos

Als ich 2009 mit der App-Entwicklung angefangen habe, wollte ich in erster Linie eigene Erfahrungen sammeln. Das ist gelungen. Auch die Monetarisierung von Apps konnte ich so erproben. Dass sich das ganze finanziell nur selten rechnet, habe ich 2011 in meinem Vortrag Für eine Handvoll Dollar dargestellt. Seitdem sind die Verpflichtungen, die ein Entwickler eingeht, nicht kleiner, sondern größer geworden. Wer neugierig ist, kann sich beispielsweise eine der vielen Hilfsseiten zum Thema Steuern ansehen. Das ist nur einer von vielen möglichen Fallstricken.

Ich jedenfalls habe genug gelernt. Smiley Spannend wird sein, wie sich ab jetzt die Download-Zahlen entwickeln. In der Zeit, in der TKWeek kostenpflichtig war, haben etwas mehr als 1000 Leute die App heruntergeladen.