2013-06-24

Ultimate Swing, Teil 25

Erinnern Sie sich noch an meine lose Folge von Posts zu Swing? Nach einer längeren Pause möchte ich den Faden wieder aufnehmen und in den folgenden Monaten den einen oder anderen Kniff zum Besten geben. Außerdem gibt es ja noch das im Rahmen der Serie begonnene Notes and Tasks, das schon in seinem frühen Stadium zu schön ist, um es nicht zu vollenden. Die Quelltexte habe ich in ein Subversion-Repository gepackt, auf das Sie über die Projekthomepage von Notes and Tasks zugreifen können.

Sie erinnern sich vielleicht, dass sich die letzten Folgen um Look and Feels gedreht haben. Ich habe auf Basis von Synth einige Komponenten so gestaltet, dass sie an den (schon länger nicht mehr so genannten) Metro-Look von Microsoft erinnern. Mir ging und geht es dabei nicht darum, eine möglichst genaue Kopie anzufertigen. Eher ist es eine Verneigung vor dem Mut Redmonds, diesen radikalen Neubeginn zu wagen. Sicher gibt es an Windows 8 noch das eine oder andere zu drehen, aber die UI ist wegweisend.

In diesem Post möchte ich mein Look and Feel, das ich übrigens UTLAF (raten Sie doch einmal, wofür UT steht) getauft habe, um die Fähigkeit erweitern, Radio buttons zu rendern. Auch Windows Store apps kennen Radio buttons. Sie sind wie eh und je rund. Diese Seite gibt einen schönen Überblick über die so genannten selection controls, die Windows Store apps zur Verfügung stehen.

UTLAF wird mit der langen Tradition runder Radio buttons brechen. Wie die korrespondierenden Grafiken aussehen, ist im folgenden Screenshot dargestellt. Ich greife dabei das von mir schon mehrfach verwendete Orange (ffa000) wieder auf.

Screenshot: die Grafiken für Radio buttons
Screenshot: die Grafiken für Radio buttons

Wenn Sie wie ich ein Kind der 70er sind, hegen Sie an diese Farbe wahrscheinlich ähnliche Erinnerungen.

Smiley

Um die Grafiken anzuzeigen, müssen wir die XML-Datei des Layouts folgendermaßen erweitern:

      <!-- RadioButton -->  
      <style id="radiobuttonStyle">  
           <opaque value="TRUE" />  
           <imageIcon id="radiobutton_off" path="radiobutton_off.png"/>  
           <imageIcon id="radiobutton_mouse_over_off" path="radiobutton_mouse_over_off.png"/>  
           <imageIcon id="radiobutton_pressed_off" path="radiobutton_pressed_off.png"/>  
           <imageIcon id="radiobutton_on" path="radiobutton_on.png"/>  
           <imageIcon id="radiobutton_mouse_over_on" path="radiobutton_mouse_over_on.png"/>  
           <imageIcon id="radiobutton_pressed_on" path="radiobutton_pressed_on.png"/>  
           <property key="RadioButton.icon" value="radiobutton_off"/>  
           <state>  
             <color type="TEXT_FOREGROUND" value="#505050"/>  
           </state>  
           <state value="PRESSED">    
                <property key="RadioButton.icon" value="radiobutton_pressed_off"/>  
           </state>       
           <state value="PRESSED and SELECTED">    
                <property key="RadioButton.icon" value="radiobutton_pressed_on"/>  
           </state>       
           <state value="SELECTED">    
                <property key="RadioButton.icon" value="radiobutton_on"/>  
           </state>       
           <state value="MOUSE_OVER and SELECTED">    
                <property key="RadioButton.icon" value="radiobutton_mouse_over_on"/>  
           </state>       
           <state value="MOUSE_OVER">    
                <property key="RadioButton.icon" value="radiobutton_mouse_over_off"/>  
           </state>       
      </style>  
      <bind style="radiobuttonStyle" type="region" key="RadioButton"/>      

Wenn Sie meinem Post zu Checkboxen gefolgt sind, werden Ihnen viele Parallelen auffallen. Letztlich geht es auch bei Radio buttons nur darum, zum aktuellen Status die passende Grafik auszuwählen.

Screenshot: Radio buttons go 70s
Screenshot: Radio buttons go 70s

Und – was sagen Sie?

Zwinkerndes Smiley

2013-06-21

10 PRINT CHR$(205.5+RND(1)); : GOTO 10

Der Titel dieses Posts ist eine Hommage an die 80er. Eine Verneigung vor einer Zeit, in der Computer zum ersten Mal zu einer Art Massenphänomen wurden. Es ist auch der Titel eines grandiosen Buches, das sich ausschließlich dieser Zeile Code widmet. Sie können das Buch in gedruckter Form kaufen oder als PDF von dieser Seite herunterladen.

10 PRINT CHR$(205.5+RND(1)); : GOTO 10
10 PRINT CHR$(205.5+RND(1)); : GOTO 10

Ich möchte dieses Buch alten Hasen und Neulingen gleichermaßen ans Herz legen – für mich war es eine wohlige Reise in die eigene Vergangenheit.

2013-06-18

Noch mehr Spaß mit Schriften

In meinem Post Retro-Spaß mit Schriften habe ich Ihnen gezeigt, wie Sie die charakteristische Commodore 64-Schrift in Swing-Textfeldern zur Anzeige bringen. Auch Android kann nachgeladene Schriften darstellen. Mit ganz wenigen Zeilen Quelltext machen Sie aus…

Screenshot: Android App mit normaler Systemschrift
Screenshot: Android App mit normaler Systemschrift

Screenshot: Android-App mit C64-Schrift
Screenshot: Android-App mit C64-Schrift

Nachdem Sie die einzubindende Schrift heruntergeladen und entpackt haben, kopieren Sie diese in den Ordner assets. Ziehen Sie hierzu die entsprechende Datei einfach auf den Ordnernamen im Package Explorer. Sie sehen nun den Dialog File Operation. Stellen Sie sicher, dass Copy files markiert ist und schließen den Dialog mit OK.

Screenshot: Datei in das Verzeichnis assets kopieren
Screenshot: Datei in das Verzeichnis assets kopieren

Screenshot: die Zeichensatzdatei im Package Explorer
Screenshot: die Zeichensatzdatei im Package Explorer

Die kopierte Datei ist unter assets im Package Explorer zu sehen. Nun müssen Sie die Schrift nur noch laden und mit einem Textfeld verknüpfen.

      @Override  
      protected void onCreate(Bundle savedInstanceState) {  
           super.onCreate(savedInstanceState);  
           setContentView(R.layout.activity_main);  
           Typeface typface = Typeface.createFromAsset(getAssets(),  
                     "C64_User_Mono_v1.0-STYLE.ttf");  
           TextView textview = (TextView) findViewById(R.id.tv);  
           textview.setTypeface(typface);  
      }  

Die Methode createFromAsset() bekommt den Namen der zu ladenden Schrift übergeben. Sie liefert ein Objekt des Typs Typeface. Diese muss nur durch Aufruf von setTypeface() an eine passende View gebunden werden.

Einfach, oder?

PS: die wunderschöne Commodore 64-Schrift finden Sie unter style64.org/c64-truetype.

2013-06-15

Retro-Spaß mit Schriften

Meine Antwort auf einen Kommentar zum vorangehenden Post hat mich veranlasst, etwas zu spielen. …folgen Sie mir auf einem kleinen (Achtung: Wortwitz) be-Swing-ten Spaziergang in die Vergangenheit. Ziel ist, das folgende Fenster (bzw. seinen Inhalt) wie die Bildschirmausgabe eines Commodore 64 aussehen zu lassen.

Screenshot eines JFrame
Screenshot eines JFrame

Der Java-Quelltext sieht folgendermaßen aus:

 package com.thomaskuenneth;  
 import javax.swing.JFrame;  
 import javax.swing.JScrollPane;  
 import javax.swing.JTextArea;  
 import javax.swing.SwingUtilities;  
 public class C64FontDemo extends JFrame {  
   private static final String CODE = "10 PRINT \"HELLO, WORLD \";\n20 GOTO 10";  
   public C64FontDemo() {  
     super(C64FontDemo.class.getName());  
     JTextArea ta = new JTextArea(CODE);  
     getContentPane().add(new JScrollPane(ta));  
     pack();  
   }  
   public static void main(String[] args) {  
     SwingUtilities.invokeLater(new Runnable() {  
       @Override  
       public void run() {  
         new C64FontDemo().setVisible(true);  
       }  
     });  
   }  
 }  

Hier nun ein Blick auf das (emulierte) Original:

C64 nach dem Systemstart und Eingabe eines kurzen Programms
C64 nach dem Systemstart und Eingabe eines kurzen Programms

Lassen wir das Programm zum Spaß kurz laufen und unterbrechen es dann.

Bildschirmausgaben des Programms
Bildschirmausgaben des Programms

Die markanten Blautöne lassen sich leicht in das Java-Programm übernehmen. Die beiden Methodenaufrufe finden am besten nach dem Erzeugen des Textfeldes ihren Platz.

     ta.setBackground(new Color(0x525ce6));  
     ta.setForeground(new Color(0xb0b3ff));  

Das sieht schon ein wenig echter aus. (Starten können wir es freilich nicht.)

Screenshot: typische Vorder- und Hintergrundfarbe
Screenshot: typische Vorder- und Hintergrundfarbe

Den letzten Schliff erhält das Ganze mit einer Commodore 64-Schrift. Sie können sich mehrere Varianten von style64.org/c64-truetype herunterladen. Nach dem Entpacken müssen Sie den Pfad im folgenden Quelltextschnipsel anpassen. Dieser findet seinen Platz übrigens nicht im Konstruktor der Klasse, sondern innerhalb der main()-Methode. Ich mache das, um Ihnen zu zeigen, wie Sie die Schrift für alle Textfelder ersetzen können. Wenn Sie lieber die Finger von Manipulationen am UIManager lassen möchten, können Sie den geladenen Font einfach mit ta.setFont() setzen (dann aber wieder im Konstruktor).

         String filename = "/Users/thomas/Downloads/C64_TrueType_v1.0-STYLE/fonts/C64_User_Mono_v1.0-STYLE.ttf";  
         File file = new File(filename);  
         try {  
           Font f = Font.createFont(Font.TRUETYPE_FONT, file);  
           f = f.deriveFont(36f);  
           UIManager.put("TextArea.font", f);  
         } catch (FontFormatException ex) {  
           Logger.getLogger(C64FontDemo.class.getName()).log(Level.SEVERE, null, ex);  
         } catch (IOException ex) {  
           Logger.getLogger(C64FontDemo.class.getName()).log(Level.SEVERE, null, ex);  
         }  

Hier das Ergebnis:

Screenshot des Java-Programms nach allen Anpassungen
Screenshot des Java-Programms nach allen Anpassungen

Sieht cool aus, oder?

Lassen Sie mich zum Schluss noch kurz zusammenfassen, was wir hier gesehen haben. Swing kann nämlich auch Zeichensätze laden, die nicht im Wirtssystem installiert sind. Hierfür müssen Sie nur Font.createFont() aufrufen. Im Anschluss an das Erzeugen leiten Sie die gewünschte Größe ab. Achten Sie darauf, das die Größe als float gesetzt wird. Ein vergessenes f hat schon viel Kopfzerbrechen verursacht. Wenn Ihnen nicht klar ist, was ich meine, werfen Sie doch einmal einen Blick auf die verschiedenen Parameter, die möglich sind.

2013-06-14

Lieblingsschriften?

Nicht nur in der IT gibt es das beliebte Spiel “Was ist der beste abc oder die beste xyz? Kürzlich bin ich über den Post 13 fonts to make a programmer smile gestolpert. Nach der Lektüre habe ich mich gefragt, warum ich keine Lieblingsschrift fürs Programmieren habe. …habe ich nämlich nicht. …haben Sie? Gibt es eine Schrift, die Sie besonders gerne für das Programmieren nutzen? Schreiben Sie mir…

2013-06-13

Unboxing… Anwoody

…gestatten, Anwoody…
Unboxing Anwoody: Die äußere Verpackung
Unboxing Anwoody: Die äußere Verpackung
Unboxing Anwoody: Ein erster Blick auf die Box
Unboxing Anwoody: Ein erster Blick auf die Box
Unboxing Anwoody: Die Box
Unboxing Anwoody: Die Box
Unboxing Anwoody: Gemütlich, oder? :-)
Unboxing Anwoody: Gemütlich, oder? :-)
Unboxing Anwoody: Hallo, Welt!
Unboxing Anwoody: Hallo, Welt!
Unboxing Anwoody: Da bin ich
Unboxing Anwoody: Da bin ich
Unboxing Anwoody: ...nochmal... ;-)
Dieses Unboxing zeigt eine handgedrechselte Android-Figur aus Holz. Sie kann auf http://www.androidfiguren.de/ bestellt werden. Man kann aus Ahorn, Buche und eiche wählen. Im Gegensatz zu den kleineren Kameraden aus Vinyl sind die Holz-Droiden größer und schwerer. Mein Exemplar bringt stolze 237 Gramm auf die Briefwaage.

2013-06-09

Mit der Zeit gehen: Kalender im neuen Gewand

Wenn Sie meinem Weblog schon länger folgen, wissen Sie, dass mich Kalender und Kalenderkomponenten interessieren. Google hat vor Kurzem eine neue Version der Kalender-App für Android veröffentlicht. Ich möchte sie Ihnen anhand von ein paar Screenshots vorstellen.

Schön ist, dass man direkt auf dem mobilen Gerät Farben für Ereignisse festlegen kann. Die entsprechende Auswahl ist im Folgenden zu sehen.

Screenshot: Terminfarbe
Screenshot: Terminfarbe

Tagesdatum, Monat und Jahr werden in einer vertikal scrollenden Monatsfolge ausgewählt

Screenshot: Tages- und Monatsauswahl (1/2)
Screenshot: Tages- und Monatsauswahl (1/2)

Screenshot: Tages- und Monatsauswahl (2/2)
Screenshot: Tages- und Monatsauswahl (2/2)

Wenn Sie das Jahr antippen, öffnet sich eine Jahresauswahl, die ebenfalls als vertikal scrollende Liste realisiert ist.

Screenshot: Jahresauswahl
Screenshot: Jahresauswahl

Das Aufteilen auf mehrere Sichten ist praktisch, weil der Bildschirm aufgeräumt wirkt, man aber trotzdem schnell seine Wahl treffen kann. Neu ist das freilich nicht, Microsoft tut dies schon sehr lange.

Wirklich nett ist die Auswahl der Terminzeit. Hier hat sich Google vom alten Wählscheibentelefon inspirieren lassen.

Screenshot: Uhrzeit auswählen
Screenshot: Uhrzeit auswählen

Ohne Frage bringen die neuen Eingabemethoden ein Plus an Komfort und Geschwindigkeit. Es macht ganz ehrlich gesagt Spaß, Termine auf diese Weise einzugeben. Schade ist allerdings, dass andere Apps nicht von den neuen Dialogen profitieren. Bis Google vielleicht seine Datums- und Zeitauswahldialoge in Android selbst aufbohrt, hat Google Kalender in diesem Punkt einen Vorsprung. Fragmentierung auf eine andere Weise?