Montag, 7. Juli 2008

Swing: Nimbus Look And Feel

Mit dem Java-Update-Release Java SE 6 update 10 kann ein neues Look And Feel genutzt werden. Das Nimbus Look And Feel basiert auf Synth Look And Feel und kann mit Hilfe der Anweisung

UIManager.setLookAndFeel("
  com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel
");

genutzt werden. Die folgenden drei Screenshots zeigen der Reihe nach die Swing Look And Feels: Metal, Nimbus, Windows.

Metal (Ocean) Look And Feel

Nimbus Look And Feel

Windows Look And Feel

Donnerstag, 14. Februar 2008

Android-SDK: Neuer Milestone (SDK-M5-RC14)

Auf den SDK-Milestone M3-RC37a vom 14.12.2007 folgt nun SDK-M5-RC14. Das neue Android-Upgrade beinhaltet Änderungen der Developer-Tools und der Android-API (siehe RELEASENOTES und API-Änderungen). Es gibt u.a. einige Neuerungen für Manifest-Dateien (AndroidManifest.xml). Z.B.

vorher (M3-RC37a):

<intent-filter>
  <action android:value="android.intent.action.INSERT"/>
  <category android:value=
      "android.intent.category.DEFAULT"/>
  <type android:value=
      "vnd.android.cursor.dir/vnd.google.note"/>
</intent-filter>

nachher (M5-RC14):

<intent-filter>
  <action android:name="android.intent.action.INSERT"/>
  <category android:name=
      "android.intent.category.DEFAULT"/>
  <data android:mimeType=
      "vnd.android.cursor.dir/vnd.google.note"/>
</intent-filter>

Auch wird innerhalb von XML-Layoutdateien das Attribut id durch android:id ersetzt.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id=id="@+id/layout"
  android:orientation="horizontal"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">

  <Button android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button1"/>
  
  ...
  
</LinearLayout>

Die SDK-Upgrade-Prozedur wird auf der Seite Upgrading the SDK beschrieben.

Sonntag, 10. Februar 2008

the Da Vinci Machine

Die Da Vinci Machine ist eine neue virtuelle Maschine!? Schaut man sich im Netz ein wenig um, fällt sofort der Untertitel "a multilingual renaissance for the Java Virtual Machine architecture" auf.

(Quelle: Wikipedia-Bild, public domain)

Sun Microsystems arbeitet an einer Weiterentwicklung der bekannten virtuellen Java-Maschine (JVM). Die JVM ist speziell auf die Programmiersprache Java zugeschnitten. Im Gegensatz dazu soll die Da Vinci VM sowohl Java als auch andere Sprachen besser unterstützen. Dabei sollen vor allem dynamische Sprachen mit der gleichen Effizienz wie die Programmiersprache Java selbst abgearbeitet werden können (zum derzeitigen Zeitpunkt gibt es eine Vielzahl von Programmiersprachen für die virtuelle Java-Maschine: http://robert-tolksdorf.de/vmlanguages.html).

Programmiersprachen wie z.B. Ruby, Perl oder Python werden als Skriptsprachen oder auch dynamische Sprachen bezeichnet. Stichworte sind hier "Static Typing" und "Dynamic Typing". Bei dynamischen Programmiersprachen erfolgt z.B. das Type Checking während der Laufzeit (Late Binding). Die derzeitige virtuelle Java-Maschine besitzt keine built-in-Unterstützung für "Dynamic Typing".

Fazit der JVM-Weiterentwicklung: Die Da Vinci Machine als universelle und effiziente VM, sowohl für Java als auch für zusätzliche Programmiersprachen.

Freitag, 8. Februar 2008

Applet: DroidDraw

Unter der Adresse droiddraw.org wird ein Applet zur Verfügung gestellt, mit dem online grafische Benutzeroberflächen (GUIs) für einen Android-Screen erstellt werden können.

DroidDraw ist in drei Bereich unterteilt. Auf der linken Seite ist ein Display des Android-Emulators dargestellt in dem per Drag and Drop einzelne grafische Elemente (Widgets) platziert werden können. Über der Display-Box kann das Grundlayout der Anzeige, z.B. LinearLayout, ausgewählt werden. Auf der rechten Seite im unteren Bereich kann anschließend der Button Generate betätigt werden, um das Layout im XML-Format zu erhalten. Die folgende erzeugte Beispielausgabe enthält als Grundlayout LinearLayout. Darin ist ein Button und ein ScrollView eingebettet. Innerhalb des XML-Elements ScrollView könnte z.B. ein TextView eingebettet werden. Bei entsprechend vielem Anzeigetext kann der Text dann gescrollt werden.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
id="@+id/widget27"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffffff"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
>
<Button
id="@+id/widget30"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
>
</Button>
<ScrollView
id="@+id/widget29"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffffffff"
xmlns:android="http://schemas.android.com/apk/res/android"
>
</ScrollView>
</LinearLayout>

Donnerstag, 31. Januar 2008

Android-Gemeinden

(Quelle: Android Goodies)

Heute möchte ich drei Verweise auf Foren posten, die sich mit der Plattform Android beschäftigen. Die Suchmaschinen-Experten kennen diese natürlich ;-) bereits. Zunächst stehen die englischsprachigen "Google-eigenen" Groups "Android Beginners" und "Android Developers" zur Verfügung:

http://groups.google.com/group/android-beginners/topics?gvc=2
http://groups.google.com/group/android-developers/topics?gvc=2

Ein weiteres Android-Forum ist unter

http://www.anddev.org

erreichbar. Es enthält interessante Unterforen zu Tutorials. Auch zur Nutzung von 3D-Grafiken auf der Android-Plattform mit OpenGL ES steht ein Unterabschnitt bereit.

Mittwoch, 23. Januar 2008

Android: DEX Intern

Die Java/Linux-Plattform Android enthält die Dalvik Virtual Machine. Die virtuelle Maschine verarbeitet Dateien im Dex File Format. Diese DEX-Dateien können mit dem vorgefertigten Tool dexdump näher untersucht werden. Das Tool kann mit Hilfe der Shell der Android Debug Bridge (adb) aufgerufen werden. Ein Beispieldump einer DEX-Datei könnte dann wie folgt aussehen:

DEX version '009'

DEX file header:

magic               : 'dex
009'
checksum            : 8d233641
signature           : 3c8d...8111
file_size           : 2364
header_size         : 92
link_size           : 0
link_off            : 0 (0x000000)
string_ids_size     : 36
string_ids_off      : 92 (0x00005c)
string_objects_size : 1
class_ids_size      : 9
class_ids_off       : 380 (0x00017c)
field_ids_size      : 3
field_ids_off       : 416 (0x0001a0)
method_ids_size     : 13
method_ids_off      : 452 (0x0001c4)
class_defs_size     : 6
class_defs_off      : 608 (0x000260)



Class #0 header:
class_idx           : 0
access_flags        : 131073 (0x20001)
superclass_idx      : 7
interfaces_off      : 0 (0x000000)
sfields_off         : 0 (0x000000)
ifields_off         : 0 (0x000000)
dmeths_off          : 800 (0x000320)
vmeths_off          : 820 (0x000334)

Class #0            -
  Class name        : 'test/android/hello/HelloAndroid'
  Access flags      : 0x20001 (PUBLIC OPTIMIZED)
  Superclass        : 'android/app/Activity'
  Interfaces        -
  Static fields     -
  Instance fields   -
  
  
  
  Direct methods    -
    #0              : (in test/android/hello/HelloAndroid)
      name          : '<init>'
      type          : '()V'
      access        : 0x0001 (PUBLIC)
      code          -
      registers     : 3
      ins           : 1
      outs          : 1
      source_idx    : 7
      insns         : 6 16-bit code units
      
      0005fc:                 |[0005fc] test/android/hello/
                               HelloAndroid.<init>:
                               ()V
      000600: 0720            |0000: move-object v0, v2
      000602: 0701            |0001: move-object v1, v0
      000604: 6f01 0000 0100  |0002: invoke-direct {v1}, 
                               android/app/Activity.
                               <init>:()V 
                               // method@0000
      00060a: 0e00            |0005: return-void
      
      exceptions    : (none)
      positions     : 1
        0x0000 line=7
      locals        : 1
        0x0001 - 0x0006 reg=0 this Ltest/android/hello/
                              HelloAndroid;



  Virtual methods   -
    #0              : (in test/android/hello/HelloAndroid)
      name          : 'onCreate'
      type          : '(Landroid/os/Bundle;)V'
      access        : 0x0001 (PUBLIC)
      code          -
      registers     : 9
      ins           : 2
      outs          : 2
      source_idx    : 7
      insns         : 29 16-bit code units
      
      00060c:                 |[00060c] test/android/
                               hello/HelloAndroid.
                               onCreate:(Landroid/os/
                               Bundle;)V
      000610: 0770            |0000: move-object v0, v7
      000612: 0781            |0001: move-object v1, v8
      000614: 0703            |0002: move-object v3, v0
      000616: 0714            |0003: move-object v4, v1
      000618: fa02 4c00 4300  |0004: 
                               +invoke-super-quick {v3, v4},
                               [004c] // vtable #004c
      00061e: 2103 0300       |0007: new-instance v3, 
                               android/widget/TextView 
                               // class@0003
      000622: 0736            |0009: move-object v6, v3
      000624: 0763            |000a: move-object v3, v6
      000626: 0764            |000b: move-object v4, v6
      000628: 0705            |000c: move-object v5, v0
      00062a: 6f02 0200 5400  |000d: invoke-direct {v4, v5}, 
                               android/widget/TextView.
                               <init>:(Landroid/
                               content/Context;)V 
                               // method@0002
      000630: 0732            |0010: move-object v2, v3
      000632: 0723            |0011: move-object v3, v2
      000634: 1804 0000       |0012: const-string v4, 
                               "Hello Android!" // string@0000
      000638: f802 e900 4300  |0014: 
                               +invoke-virtual-quick {v3,v4},
                               [00e9] // vtable #00e9
      00063e: 0703            |0017: move-object v3, v0
      000640: 0724            |0018: move-object v4, v2
      000642: f802 6200 4300  |0019: 
                               +invoke-virtual-quick {v3,v4},
                               [0062] // vtable #0062
      000648: 0e00            |001c: return-void
      
      exceptions    : (none)
      positions     : 5
        0x0000 line=11
        0x0007 line=12
        0x0011 line=13
        0x0017 line=14
        0x001c line=15
      locals        : 3
        0x0001 - 0x001d reg=0 this Ltest/android/hello/
                              HelloAndroid;
        0x0002 - 0x001d reg=1 icicle Landroid/os/Bundle;
        0x0011 - 0x001d reg=2 tv Landroid/widget/TextView;



Class #1 header:
...

Der Dalvik-Bytecode bezüglich des Code-Arrays ist im Dexdump rot markiert. Es kann festgestellt werden, dass die folgenden Abbildungen bzw. Umkehrabbildungen (Dalvik-Bytecode --> Dalvik-Assemblersprache) gelten:

0720             -->   move-object v0, v2
0701             -->   move-object v1, v0
6f01 0000 0100   -->   invoke-direct {v1}, 
                       android/app/Activity.<init>:()V
0e00             -->   return-void

0770             -->   move-object v0, v7
0781             -->   move-object v1, v8
0703             -->   move-object v3, v0
0714             -->   move-object v4, v1
fa02 4c00 4300   -->   +invoke-super-quick {v3, v4}, 
                       [004c]
2103 0300        -->   new-instance v3, 
                       android/widget/TextView
0736             -->   move-object v6, v3
0763             -->   move-object v3, v6
0764             -->   move-object v4, v6
0705             -->   move-object v5, v0
6f02 0200 5400   -->   invoke-direct {v4, v5}, 
                       android/widget/TextView.<init>:
                       (Landroid/content/Context;)V
0732             -->   move-object v2, v3
0723             -->   move-object v3, v2
1804 0000        -->   const-string v4, "Hello Android!" 
f802 e900 4300   -->   +invoke-virtual-quick {v3,v4},
                       [00e9]]
0703             -->   move-object v3, v0
0724             -->   move-object v4, v2
f802 6200 4300   -->   +invoke-virtual-quick {v3,v4},
                       [0062]
0e00             -->   return-void

Durch den Dexdump wird auch deutlich, dass die wichtige Methode onCreate als "virtuelle Methode" eingestuft ist. So, genug von Androiden für heute. ;-)

(Quelle: Android Goodies)

Dienstag, 22. Januar 2008

Android-GUI mit XML-Layoutdatei

Android ermöglicht es, grafische Benutzeroberflächen (GUIs) mit Hilfe von XML-Dateien zu designen. Diese Vorgehensweise ähnelt damit dem Design von Webseiten, z.B. mit HTML. Eine XML-Datei main.xml zur Layoutgestaltung befindet sich dabei im Unterverzeichnis res/layout/. Das Display des Emulators soll eine einfache Textausgabe, ein Eingabefeld und zwei Buttons anzeigen.

Die für das Layout zuständige Datei main.xml könnte dann wie folgt aussehen:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" 
android:layout_height="wrap_content"
android:background="#ffc5d1d4" 
android:padding="10px">

  <TextView id="@+id/label" 
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content" 
            android:text="Your Input:"/>
  <EditText id="@+id/input" 
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content" 
            android:layout_below="@id/label"/>
  <Button   id="@+id/ok" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"
            android:layout_below="@id/input"
            android:layout_alignParentRight="true"
            android:layout_marginLeft="10px"
            android:text="OK"/>
  <Button   id="@+id/cancel"
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"
            android:layout_toLeft="@id/ok"
            android:layout_alignTop="@id/ok"
            android:text="Cancel" />
</RelativeLayout>

Jetzt fehlt nur noch das kurze Java-Listing, das die Layout-Ressource lädt bzw. verarbeitet. Innerhalb der Methode onCreate ist hierzu der Aufruf von setContentView nötig. Die Applikation ist damit vollständig und kann aus Eclipse heraus gestartet werden.

/* RelativeLayoutExample.java */

package examples.android.relativelayoutexample;

import android.app.Activity;
import android.os.Bundle;

public class RelativeLayoutExample extends Activity {
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    
    setContentView(R.layout.main);
  } 
}

Montag, 21. Januar 2008

Android: Widget ListView

Das Android-SDK stellt verschiedene sogenannte Views zur Verfügung, darunter auch das grafische Steuerelement ListView. Die zugehörige Klasse befindet sich im Paket android.widget. Ein ListView zeigt eine vertikale Liste im Display des Emulators an.

/* ListViewExample.java */

package examples.android.listviewexample;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;

public class ListViewExample extends ListActivity {
  @Override
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    
    String[] str = new String[]{"Alida", 
                                "Dennis", 
                                "Clara"};
    
    this.setListAdapter(new ArrayAdapter<String>(this,
        android.R.layout.simple_list_item_1, str));
  }
}

Das String-Array str enthält die Zeichenketten, die im Display angezeigt werden sollen. Um auf eine Auswahl eines Listenelements reagieren zu können, müsste die Methode onListItemClick überschrieben (überlagert) werden. Ein Screenshot des Android-Emulators könnte dann wie folgt aussehen:

Freitag, 18. Januar 2008

Android ist grün!?

Naja, zumindest das Android-Logo hat einen helleren grünen Farbton.

(Quelle: Android Goodies)

Um bei der Farbe grün zu bleiben: Das anschließende kurze Java-Listing ist auch ein Android-Listing und erzeugt einen fließenden Hintergrundverlauf auf dem Display des Android-Emulators (Android-SDK, Eclipse und Plugin ADT).

/* GradientExample.java */

package examples.android;

import android.app.Activity;
import android.os.Bundle;

import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.GradientDrawable.Orientation;
import android.graphics.Color;


public class GradientExample extends Activity {
  @Override
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);

    GradientDrawable grad = new GradientDrawable(
      Orientation.TOP_BOTTOM,
      new int[] {Color.GREEN, Color.WHITE}
    );
  this.getWindow().setBackgroundDrawable(grad);
  }
}

Dann ist ja doch alles grün - naja zumindest fast. ;-)

Montag, 14. Januar 2008

Androiden in Dalvik?

Am 5. November 2007 ist der öffentliche Startschuss für die neue Smartphone-Plattform Android gefallen. Android basiert auf dem Betriebssystem-Kern Linux und besitzt eine virtuelle Maschine mit dem Namen Dalvik. Zur Erstellung von Applikationen wird auf die Programmiersprache Java zurückgegriffen. Doch was bzw. wo ist Dalvik? Gibt man mal "Dalvik" in Google-Maps ein erscheint eine Karte von Island auf dem Bildschirm - Dalvik ist eine kleinere Stadt im Norden von Island. Der bzw. die Entwickler der Dalvik Virtual Machine scheinen eine Verbindung zur besagten Gemeinde zu haben. Der zur virtuellen Maschine gehörende Bytecode wird als Dalvik-Bytecode bezeichnet und ist für eine Registermaschine ausgelegt. Dalvik-Bytecode wird in Dateien mit der Endung .dex abgelegt (dalvik executable). Dabei unterliegen die einzelnen Zahlenwerte der .dex-Datei einem eigenen Format, dem Dex File Format. Für eine Beispieldatei classes.dex kann dieses Format gegliedert sein zu:
classes.dex

header:
  header_file_signature (bytes): 100 101 120 10 48 48 57 0
  header_1 (bytes): 65 54 35 141
  header_2 (bytes): 60 141 61 87 68 75 195 95 199 97 5 66 32 
                    252 0 100 245 158 129 17
  header_length_file: 2364
  header_length_header: 92
  header_padding (bytes): 0 0 0 0 0 0 0 0
  header_string_table_entries: 36
  header_string_table_offset: 92
  header_8 (bytes): 1 0 0 0
  header_class_list_entries: 9
  header_class_list_offset: 380
  header_field_table_entries: 3
  header_field_table_offset: 416
  header_method_table_entries: 13
  header_method_table_offset: 452
  header_class_definition_table_entries: 6
  header_class_definition_table_offset: 608

string table:
  0. offset: 1806, length: 14, Hello Android!
  1. offset: 1692, length: 3, ()V
  2. offset: 1696, length: 28, (Landroid/content/Context;)V
  3. offset: 1725, length: 22, (Landroid/os/Bundle;)V
  4. offset: 1748, length: 22, (Landroid/view/View;)V
  5. offset: 1771, length: 27, (Ljava/lang/CharSequence;)V
  6. offset: 1799, length: 6, 
  7. offset: 1821, length: 17, HelloAndroid.java
  8. offset: 1839, length: 1, I
  9. offset: 1841, length: 19, Landroid/os/Bundle;
  10. offset: 1861, length: 25, Landroid/widget/TextView;
  11. offset: 1887, length: 33, Ltest/android/hello/
                                HelloAndroid;
  12. offset: 1921, length: 27, Ltest/android/hello/R$attr;
  13. offset: 1949, length: 31, Ltest/android/hello/
                                R$drawable;
  14. offset: 1981, length: 29, Ltest/android/hello/R$layout;
  15. offset: 2011, length: 29, Ltest/android/hello/R$string;
  16. offset: 2041, length: 22, Ltest/android/hello/R;
  17. offset: 2064, length: 6, R.java
  18. offset: 2071, length: 20, android/app/Activity
  19. offset: 2092, length: 23, android/widget/TextView
  20. offset: 2116, length: 8, app_name
  21. offset: 2125, length: 6, icicle
  22. offset: 2132, length: 4, icon
  23. offset: 2137, length: 16, java/lang/Object
  24. offset: 2154, length: 4, main
  25. offset: 2159, length: 8, onCreate
  26. offset: 2168, length: 14, setContentView
  27. offset: 2183, length: 7, setText
  28. offset: 2191, length: 31, test/android/hello/
                                HelloAndroid
  29. offset: 2223, length: 20, test/android/hello/R
  30. offset: 2244, length: 25, test/android/hello/R$attr
  31. offset: 2270, length: 29, test/android/hello/R$drawable
  32. offset: 2300, length: 27, test/android/hello/R$layout
  33. offset: 2328, length: 27, test/android/hello/R$string
  34. offset: 2356, length: 4, this
  35. offset: 2361, length: 2, tv

class list:
  0. string pool index: 28, test/android/hello/HelloAndroid
  1. string pool index: 32, test/android/hello/R$layout
  2. string pool index: 29, test/android/hello/R
  3. string pool index: 19, android/widget/TextView
  4. string pool index: 30, test/android/hello/R$attr
  5. string pool index: 33, test/android/hello/R$string
  6. string pool index: 31, test/android/hello/R$drawable
  7. string pool index: 18, android/app/Activity
  8. string pool index: 23, java/lang/Object
...
Die DEX-Datei beginnt mit den Zahlenwerten 100 101 120 10 48 48 57 0. Beachtet man die Codierung nach ASCII folgt: d e x LF 0 0 9 NULL. Der Datei-Header gibt schon die Struktur der Datei wieder: String-Tabelle, Klassenliste, Feldtabelle, Methodentabelle und ein Byteabschnitt zur Defintion von Klassen. In der Beipiel-DEX-Datei sind sechs Klassendefinitionen vorhanden. Eine .class-Datei enthält die Defintion einer einzigen Klasse (Interface). Aber Androiden sind keine Aliens: Mit Hife des im Android-SDK enthaltenen Tools dx können .class-Dateien in .dex-Dateien konvertiert werden.