FFmpeg selber bauen

May 26th, 2009

Besonders Linuxuser haben vermutlich zumindest schonmal von FFmpeg gehört. Es ist eines der ganz großen Glanzstücke der OpenSource-Szene. Das FFmpeg-Projekt entwickelt unter anderem die libavcodec, die auch in kommerziellen Produkten wie dem DVDFabDecrypter verwendet wird (in diesem Fall liegt allerdings eine Lizenzverletzung vor!).

Mit diesem Programm lässt sich beinahe jedes existierende Video- und Audioformat in ein anderes konvertieren – seit Kurzem gibt es sogar Unterstützung für die neueren Versionen von RealVideo. Besonders praktisch erweist sich das Konvertieren von FlashVideos aus dem Internet in MP4 unter Verwendung des H.264-Videocodes, um diese dann auf moderne Portable Media Player (iPod, etc.) zu laden.

Hier wären wir auch schon beim ersten Problem: in den Ubuntu-Repartoires gibt es zwar eine FFmpeg-Version, welche allerdings aus rechtlichen Gründen beim Compilieren etwas “kastriert” wurde. Auch die Version aus den Medibuntu-Quellen kann mit H.264 nicht umgehen. Aus diesem Grund bietet es sich an eine eigene Version zu bauen, die die Möglichkeiten von FFmpeg auch ausreizen kann. Wie oben schon angesprochen, verletzt FFmpeg und seine Programmbibliotheken in diversen Ländern Urheberrechte (was in Österreich afaik nicht der Fall ist). Aus diesem Grund wird das Programm auf der Projekt-Homepage auch ausschließlich als Quelltext angeboten.

Das manuelle Bauen von Programmen aus dem Quellcode ist normalerweise den bereits fortgeschrittenen Benutzern vorenthalten, da sich Anfänger in der Regel bei Konsolenoperationen überfordert fühlen. Aber auch erfahrenen Usern kann das Compilieren viel Zeit kosten; besonders das Herausfinden von benötigten Paketen anhand (teilweise etwas unklarer) Fehlermeldungen ist oft sehr zeitraubend.
Aus diesem Grund habe ich selbst ein Shellscript zusammengestellt, welches automatisch die aktuelle SVN-Version compiliert und über die Paketverwaltung installiert.

Wichtig: Das Downloadscript benötigt diverse Pakete aus den Medibuntuquellen, aus diesem Grund müssen diese vorher den Paketquellen hinzugefügt werden. Wie das funktioniert ist hier nachzulesen: Ubuntuusers Wiki: Medibuntu
Das Script ist zu Hardy und Intrepid geringfügig inkompatibel, da bei manchen Paketen die Version erneuert wurde und diese im Paketnamen integriert ist. Bei Nicht-Jaunty-System müssen die Paketnamen also dementsprechend angepasst werden (bei Problemen einfach melden, ich helfe gerne).

Download: build_ffmpeg.sh (optimiert für Ubuntu 9.04 – Jaunty Jackalope)

Das Script einfach im Terminal ausführen und zu Beginn das Root-Kennwort eingeben. Die Installationsdauer beträgt je nach Internetverbindung und Prozessor ca. 10 Minuten. Es wird automatisch ein Ordner deb angelegt, in dem sich nach erfolgreicher Ausführung ein DEB-Paket befindet. Das Shellscript installiert dieses allerdings bereits automatisch!

Nach erfolgreicher Installation können wir endlich unser erstes Video Konvertieren.
Dieser Befehl wandelt das Video mein_video.flv in ein MP4-Video um:

ffmpeg -i mein_video.flv mein_video.mp4

Software, Tutorials , , , , , , , , ,

Hochauflösende Texturen für N64-Spiele

February 22nd, 2009

Bei neueren N64-Emulatoren ist es mittlerweile möglich hochauflösende Texturen zu verwenden. So erstrahlen alte Klassiker in neuem Glanz. Texturen sind letztlich nichts anderes als Bitmaps welche auf die dreidimensionalen Objekte „projiziert“ werden. Die Grafik wird durch die neuen Texturen also nicht weniger eckig, doch durch die feineren Oberflächen verbessert sich der Gesamteindruck enorm.

In diesem Artikel richten wir für zwei Spiele High-Resolution-Textures für den N64-Emulator Mupen64Plus ein. Ich verwende als Betriebssystem Ubuntu (Linux), Windows-User sollten besser zu Project64 und zu dieser Anleitung greifen:
http://www.tehskeen.com/forums/showthread.php?t=738

Zuerst benötigen wir den Emulator ansich. Solange dieser nicht installiert ist, läuft gar nichts. Bei den Ubuntu-Quellen ist Mupen64Plus nicht vorhanden, also werden wir das Programm aus dem Quellcode übersetzen.

Zu diesem Zweck habe ich ein kleines Shell-Script geschrieben, welches auch unerfahrenen Benutzern ermöglicht den Emulator zu kompilieren.
(Getestet unter Ubuntu 8.10; für andere Distributionen ist eine dementsprechende Anpassung des Scripts notwendig)

Build-Script: build_mupen64plus.sh (Update: 29. März 2009)

Alternativ kann ich ein selbstgebautes DEB-Paket anbieten:
Software-Paket: mupen64plus-3%3a0.svn20090329-1-1ubuntu3_i386.deb
(SVN Build vom 29. März 2009 unter Ubuntu 8.10)

Wer doch lieber zum fertigen Installationspaket greift, kann diesen Absatz überspringen.
Um den Emulator mithilfe des Shellscripts zu installieren, speichern wir dieses unter „build_mupen.sh“ in einem neuen Verzeichnis ab und machen es ausführbar. Wer Nautilus als Dateimanager verwendet kann das unter „Eigenschaften – Zugriffsrechte – Datei als Programm ausführen“ regeln. Alternativ kann man die Zugriffrechte auch in der Konsole mit chmod +x build_mupen.sh ändern. Anschließend muss das Shell-Script im Terminal gestartet und das Root-Kennwort eingegeben werden. Da das offizielle Release leider fehlerhaft ist und beim Laden der Texturen abstürzt, greift das Script auf die aktuellere SVN-Version zurück. Wurde Mupen64Plus fertig kompiliert, fragt das Script nach ob aufgeräumt werden soll (Clean up). Diese Frage mit y beantworten um die nicht mehr benötigten Pakete zu entfernen.
Zur korrekten Ausführung der Installation ist eine Verbindung zum Internet notwendig, da ansonsten die benötigten Resourcen nicht gedownloadet werden können. Der gesamte Vorgang nimmt in etwa 3-5 Minuten in Anspruch.
Nun befindet sich im Ordner deb ein DEB-Installationspaket, welches automatisch vom Script gleich installiert wird. Es ist daher notwendig vorher alle Programme die auf die Paketverwaltung zugreifen (Synaptic, Aptitude, Apt-Get, …) zu beenden!

Danach starten wir das Programm testweise über das Terminal mit dem Befehl „mupen64plus“ und stellen unter Options – Configure … – Plugins als Input Plugin „blight’s SDL input plugin“ ein. Wenn wir schon dabei sind, überprüfen wir auch ob als Graphics Plugin auch „Rice’s Video Plugin“ angewählt ist – ohne dem läuft nämlich gar nix! Damit dieses Plugin die Texturen dann auch wirklich lädt, müssen wir unter Config die Option „Load hi-res textures if available“ anhaken. Anschließend verlassen wir das Fenster über den OK-Button und klicken dann im Konfigurationsfenster auf Anwenden und OK.

Nun sollte sich in unserem Home-Verzeichnis ein versteckter Ordner „.mupen64plus“ befinden. In diesem Verzeichnis erstellen wir einen neuen Ordner „hires_texture“. In diesen Ordner kommen anschließend die neuen Texturen.

EDIT (2009-03-29): Ich habe mir die Mühe gemacht eine deutsche Sprachdatei für Mupen64Plus anzufertigen. Diese ist bereits in meinem DEB-Paket enthalten und auch das Script bindet sie automatisch ein. Um Mupen64Plus in Deutsch verwenden zu können, muss nur noch die „mupen64plus.conf“ angepasst werden, welche in „~/.mupen64plus“ liegt. Einfach den Wert Language von English auf German umschreiben und das Programm neu starten.

Gute Texturen zu finden ist gar nicht so leicht, daher habe ich schon einmal zwei Pakete mit Texturen für meine zwei Lieblings-N64-Spiele gesucht: Ocarina of Time und Majoras Mask aus der Legend of Zelda-Reihe.

Real Hires Texture für Ocarina of Time:
Oot_Hires.7z

Real Hires Texture für Majora’s Mask:
ZELDA MAJORA’S MASK Real.zip

Werfen wir zuerst ein Auge auf die Texturen für Ocarina of Time. Das Dateiarchiv muss erst entpackt werden. 7Zip gehört nicht zum Standardrepartoire von Ubuntu, daher muss es eventuell noch über das Paket p7zip-full installiert werden. Nun entpacken wir die Datei Oot_Hires.7z und wir bekommen einen Ordner „The Legend of Zelda“. Der Ersteller der Texturen war mit Sicherheit Windows-User, denn da sind Datei- und Verzeichnisnamen nicht Case-Sensitive (kein Unterschied bei Groß- und Kleinschreibung). Deswegen müssen wir den Ordner erst in „THE LEGEND OF ZELDA“ umbenennen. Nun kann der Ordner in das vorhin erstellte Verzeichnis „hires_texture“ verschoben werden. Der Ordner mit den Texturen muss deshalb genauso heißen, weil das ROM intern so heißt. Diese interne Benennung kann man einsehen indem man in der ROM-Liste von Mupen64Plus das entsprechende ROM anwählt und über das Kontextmenü (rechte Maustaste) auf Rom Properties klickt. In der Zeile Internal Name wird man fündig.

Jetzt müssen wir Ocarina of Time nur noch starten und es sollte funktionieren. Öffnet man Mupen64Plus über die Konsole, muss beim Laden des ROMs nun zu sehen sein wie der Emulator die einzelnen Bitmaps lädt. Ist das nicht der Fall, hat man etwas falsch gemacht (möglicherweise ist als Video-Plugin nicht Rice Video ausgewählt). Natürlich beansprucht das Laden der Texturen auch etwas mehr Zeit als sonst.

Um die Texturen für Majoras Mask einzuspielen verfährt man genauso wie zuvor, nur muss hier der Ordner mit den Texturen nach dem Entpacken nicht mehr umbenannt werden (Der richtige Ordner liegt innerhalb von „ZELDA MAJORA’S MASK Real“!)
Da Mupen64Plus beim Laden bestimmter Bitmaps immer abstürzt, sollten diese vor Gebrauch noch mit optipng „repariert“ werden. Dazu müssen folgende Befehle ausgeführt werden, nachdem die Texturen in das richtige Verzeichnis kopiert wurden:

sudo aptitude install optipng
cd "$HOME/.mupen64plus/hires_texture/ZELDA MAJORA'S MASK/005-Lune"
optipng *.png

Bedauerlicherweise sieht die Schrift bei diesem Texturenpaket ziemlich ärmlich aus und unterstützt auch keine Umlaute und andere Sonderzeichen wie „ß“. Daher ist es empfehlenswert stattdessen die Schrift-Texturen aus dem Texturenpaket für Ocarina of Time zu verwenden. Sind beide Texturenordner korrekt eingerichtet, erledigt dieses kleine Shellscript den Rest:

#!/bin/bash
IFS="
"
source="$HOME/.mupen64plus/hires_texture/THE LEGEND OF ZELDA/Pack One/Text"

cd "$HOME/.mupen64plus/hires_texture/ZELDA MAJORA'S MASK/001- Dialogue Tiles"

copy_and_rename() {
	rm -v "$2"/*
	cp -v "$source/$1/"THE\ LEGEND\ OF\ ZELDA*.png "$2"

	for file in $(ls "$2"); do
		mv -v "$2/$file" "$2/`echo $file | sed s/THE\ LEGEND\ OF\ ZELDA/ZELDA\ MAJORA\'S\ MASK/g`"
	done
}

copy_and_rename "Buttons - Incomplete - Needs name" "Buttons"
copy_and_rename "Capitals - Complete" "Capitals"
copy_and_rename "Lowercase - Complete" "Lowercase"
copy_and_rename "Numerals - Complete" "Numerals"
copy_and_rename "Punctuation - Complete" "Punctuation"

Wer Texturen für andere Spiele sucht sollte sich mal hier umschauen:
http://www.emutalk.net/showthread.php?t=42231
http://www.coolrom.com/forums/showpost.php?p=118328&postcount=19

Games, Software , , , , , , , , , , , , , , , , ,

Graphical interfaces in Java – chapter 3

December 28th, 2008

Zur deutschen Version dieses Artikels


English is not my mother tongue and I’m still trying to improve myself. So please leave me a comment if you find any mistakes in my text. I’d really appreciate that :)

The previous chapter was about adding graphical components to the program window. Now it’s time to learn more about the various components and possibilities of Swing.

This chapter is about two essential form elements: JButton and JTextField.

The code example below is a program which is able to change the text of the JLabel dynamically over a text field.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class TestWindow extends JFrame {
	private JLabel text;
	private JTextField input;

	public static void main( String[] args ) {
		TestWindow myWin = new TestWindow( "Hallo Welt!" );
		myWin.init();
	}

	public TestWindow( String title ) {
		super( title );

		this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		this.setBounds( 100, 100, 400, 300 );
		this.setIconImage( new ImageIcon("icon.png").getImage() );
		this.setLayout( null );
	}

	public void init() {
		this.text = new JLabel( "Das ist ein Text" );
		text.setBounds( 10, 10, 500, 25 );

		this.input = new JTextField();
		input.setBounds( 10, 40, 250, 25 );

		JButton button = new JButton( "Anzeigen" );
		button.setBounds( 10, 70, 150, 25 );
		button.addActionListener(
			new ActionListener() {
				public void actionPerformed( ActionEvent e ) {
					text.setText( input.getText() );
				}
			}
		);

		this.getContentPane().add( text );
		this.getContentPane().add( input );
		this.getContentPane().add( button );

		this.setVisible( true );
	}
}

TestWindow 03

TestWindow 03

Compared to the second chapter, the source code went through many changes. First of all we’ll take a look at the new method setLayout(). Java can use layout managers for its GUI’s to position and modify the comoponents in an adequate way. If there’s no need for such a manager, you have to set the LayoutManager to null (like we did).

Now we’re initializing the Swing components JLabel, JTextField and JButton one by one. The two latter classes are new to us. The class JTextField represents a single-row text field and JButton an ordinary button. Every class which inherits from Component (that concerns nearly every Swing component)  owns the setter setBounds(). However, this method is useless if you’re using a LayoutManager, just like setSize() and setLocation()!

We declare JLabel and JTextField as a class variable, so the code becomes a bit more clear. Besides this is necessary to get access to these components inside the nested class ActionListener (alternatively it’s possible to declare them as final, so they become constants).

The following part is the most interesting one of this chapter. We’ll attach an action event to our button. For this purpose we use the method addActionListener() which expects an ActionListener as a parameter. Already the method’s prefix add lets suppose that a button can own more than just one ActionListener.

Nested classes are especially important in graphical programming. This kind of class can be inside of other classes or even inside of methods, how our case shows. ActionListener is an interface which we have to implement. The code inside actionPerformed() will be executed when the button is klicked. Finally, I want to mention that the implementation of classes like ActionListener as nested classes inside of methods isn’t always the best way. Sometimes it can be benefitially to implement the class in its own Java source file.

So far, so good! The next chapter is about the several LayoutManager classes in Java.

Software, Tutorials , , , , , , , ,

Graphical interfaces in Java – chapter 2

December 28th, 2008

Zur deutschen Version dieses Artikels


English is not my mother tongue and I’m still trying to improve myself. So please leave me a comment if you find any mistakes in my text. I’d really appreciate that :)

Welcome to the second part of my tutorial :)

In the last chapter we’ve managed to create a window as the basis of our program. Now we wanna extend the JFrame with some new components.

In the following source code example, we add a title to our window (which is shown in the title bar) and a short text as a content. Additionally we’ll replace the little Java icon in the top left corner with our own icon.

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class TestWindow extends JFrame {
	public static void main( String[] args ) {
		TestWindow myWin = new TestWindow( "Hallo Welt!" );
		myWin.init();
	}

	public TestWindow( String title ) {
		super( title );
	}

	public void init() {
		this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		this.setBounds( 100, 100, 400, 300 );
		this.setIconImage( new ImageIcon("icon.png").getImage() );

		JLabel text = new JLabel( "Das ist ein Text" );
		this.getContentPane().add( text );

		this.setVisible( true );
	}
}

TestWindow 02

TestWindow 02

The code haven’t changed much, but the two new imported classes are noticably. At this time, we deliver a parameter of the type String to the constructor of our TestWindow class. It redirects the parameter to the constructor of the superclass (JFrame), so we set the title of our window. Alternatively, it’s also possible to set or change the title with the method setTitle().

Next we change the small icon in the title bar. For that purpose, we make use of setIconImage() which expects a parameter of the type Image. The easiest way to get this parameter, is the class ImageIcon.

Now we are ready for our first real Swing component – JLabel. This class is about showing an uneditable text. To make this component visible, we have to add it to our JFrame first.
Unfortunately this is a bit tricky. The class JFrame already contains another Swing component, which is JPanel. This  component is responsible for displaying other components. We’ll face JPanel in the next few chapters again because this class is pretty many-sided and it’s possible to interlace them. To get access to the JPanel of our JFrame we need the getter getContentPane(). Eventually we can add() our JLabel to our surface.

Therefore we’ve already managed two crucial things: how can I create a Swing component and how can I add it to my graphical surface.
In the next chapter, we’ll face some important elements for forms, like buttons and input fields.

Software, Tutorials

Graphical interfaces in Java – chapter 1

December 27th, 2008

Zur deutschen Version dieses Artikels


English is not my mother tongue and I’m still trying to improve myself. So please leave me a comment if you find any mistakes in my text. I’d really appreciate that :)

Note: This Tutorial is inappropriate for people who have no further experience with Java programming. It’s actually not very clever to start with GUI programming if you have no basic knowledge of any programming language.

Welcome to the first Part of my Java tutorial for graphical programming. When I was starting with Java, I was looking for a good tutorial about GUI programming (GUI = Graphical User Interface). Although there are some good ancillas like Java ist auch eine Insel, I was never really satisfied with them. For that reason I wanna create a good tutorial for beginners which is easy to understand.

Because the newer Swing library has so many more useful features than the AWT library, I’ll only concentrate on Swing components in this tutorial (with a few expectations).

Let’s start with the blank window first. Before we are even able to create a graphical interface, we need a window for our program. In Swing, the class JFrame represents this window.

This short example source code initializes a blank window:

import javax.swing.JFrame;

public class TestWindow extends JFrame {
	public static void main( String[] args ) {
		TestWindow myWin = new TestWindow();
		myWin.init();

	}

	public void init() {
		this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		this.setBounds( 100, 100, 400, 300 );
		this.setVisible( true );
	}
}

TestWindow 01

TestWindow 01

Let’s start with the code analysis. The program starts as usual out of the main method. There we are initializing an instance of our class TestWindow, which extends JFrame. This class has to be imported from the package javax.swing.

Furthermore we call another three methods in our method init(). The setter method setDefaultCloseOperation() influences the way how the window is closing. In our example we give the constant JFrame.EXIT_ON_CLOSE as parameter to the method. After this, the window will close normally if the user wants it to. Without this step, the user would have to kill the application manually (e.g. with the task manager) which isn’t pretty user friendly ;)

The method setBounds() gets the coordinates and the size for our window on the screen. In our example the window is located at x=100; y=100 with a width of 400 pixel and a height of 300 pixel.

To make the window visible at all, we have to call the method setVisible() with the boolean parameter true.

Wonderful! Now we’ve created our first graphical user interface. Nevertheless it has no content at all and the title bar is empty too. To handle this, check out the next chapter :)

Software, Tutorials , , , , , , ,

Grafische Programmierung mit Java – Kapitel 3

November 21st, 2008

Read the english version of this article


Im vorherigen Kapitel ging es darum, grafische Komponenten überhaupt im Programmfenster darzustellen. Nun gilt es die Vielzahl an einsetzbaren Komponenten die Swing bietet, kennen zu lernen.

In diesem Kapitel wollen wir uns mit zwei grundlegenden Formularelementen beschäftigen: JButton und JTextField.

Das folgende Codebeispiel zeigt ein Programm, mit dem der Benutzer den Inhalt des JLabels dynamisch über ein Textfeld ändern kann.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class TestWindow extends JFrame {
	private JLabel text;
	private JTextField input;

	public static void main( String[] args ) {
		TestWindow myWin = new TestWindow( "Hallo Welt!" );
		myWin.init();
	}

	public TestWindow( String title ) {
		super( title );

		this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		this.setBounds( 100, 100, 400, 300 );
		this.setIconImage( new ImageIcon("icon.png").getImage() );
		this.setLayout( null );
	}

	public void init() {
		this.text = new JLabel( "Das ist ein Text" );
		text.setBounds( 10, 10, 500, 25 );

		this.input = new JTextField();
		input.setBounds( 10, 40, 250, 25 );

		JButton button = new JButton( "Anzeigen" );
		button.setBounds( 10, 70, 150, 25 );
		button.addActionListener(
			new ActionListener() {
				public void actionPerformed( ActionEvent e ) {
					text.setText( input.getText() );
				}
			}
		);

		this.getContentPane().add( text );
		this.getContentPane().add( input );
		this.getContentPane().add( button );

		this.setVisible( true );
	}
}

TestWindow 03

TestWindow 03

Im Vergleich zum zweiten Kapitel hat sich hier nun doch schon einiges getan. Werfen wir zuerst einen Blick auf die Methode setLayout(). Java verwendet für seine GUI’s Layout-Manager, die sich darum kümmern, wie und wo die einzelnen grafischen Komponenten dargestellt werden. Möchte man die Gestaltung ganz sich selbst überlassen, setzt man den LayoutManager einfach auf null.

Nun initialisieren wir nach der Reihe die Swing-Komponenten JLabel, JTextField und JButton. Die zwei letzteren Klassen sind neu. JTextField repräsentiert ein Textfeld und JButton einen – wie könnte es anders sein – normalen Button. Jede Klasse die von Component erbt (dazu gehören die meisten Swing-Komponenten) besitzt die Methode setBounds(). Diese, wie auch die Methoden setSize() und setLocation() sind allerdings nur von Bedeutung, wenn kein LayoutManager verwendet wird!

JLabel und JTextField legen wir als Klassenvariablen an. Dies macht den Code erstens übersichtlicher und ist außerdem notwendig, da ansonsten nicht innerhalb der Inner-Class ActionListener darauf zugreifen werden kann (alternativ müssten die Variablen als Konstanten deklariert werden).

Jetzt kommen wir zum interessantesten Teil dieses Kapitels – wir weisen dem JButton eine Aktion zu. Dafür gibt es die Methode addActionListener() welche einen Parameter vom Typ ActionListener erwartet. Wie der Präfix add bereits erahnen lässt, können einem Button gleich mehrere ActionListener zugewiesen werden.

Inner-Classes haben insbesondere bei grafischer Programmierung eine hohe Bedeutung. Genaugenommen sind das Klassen innerhalb von anderne Klassen, oder sogar innerhalb von Methoden wie in diesem Fall. ActionListener ist ein Interface das hier implementiert werden muss. Der Code innerhalb von actionPerformed() wird ausgeführt, sobald auf den Button geklickt wird. Es ist allerdings nicht immer sinnvoll, Klassen wie ActionListener auf diese Weise zu implementieren. Manchmal ist es durchaus vorteilhaft, die Implementierung in eine eigene Java-Datei auszulagern.

So weit so gut. Im nächsten Kapitel widmen wir uns den LayoutManager-Klassen von Java.

Software, Tutorials , , , , , , , ,

Grafische Programmierung mit Java – Kapitel 2

November 21st, 2008

Read the english version of this article


Willkommen zum 2. Kapitel meines Tutorials :)

Im letzten Kapitel haben wir uns vorerst nur darum gekümmert, dass das Programmfenster, die Grundlage unseres eigentlichen Programms, angezeigt wird. Nun wollen wir den JFrame um ein paar Komponenten erweitern.

Im folgenden Code-Beispiel geben wir dem Fenster einen Titel (wird in der Titelleiste angezeigt), einen Text als Fensterinhalt und wechseln das kleine Java-Icon oben links gegen ein eigenes aus.

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class TestWindow extends JFrame {
	public static void main( String[] args ) {
		TestWindow myWin = new TestWindow( "Hallo Welt!" );
		myWin.init();
	}

	public TestWindow( String title ) {
		super( title );
	}

	public void init() {
		this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		this.setBounds( 100, 100, 400, 300 );
		this.setIconImage( new ImageIcon("icon.png").getImage() );

		JLabel text = new JLabel( "Das ist ein Text" );
		this.getContentPane().add( text );

		this.setVisible( true );
	}
}

TestWindow 02

TestWindow 02

Am Code hat sich nicht viel geändert, auffallend sind jedoch die zwei neu importierten Klassen. Diesmal übergeben wir dem Kontruktor unserer Klasse TestWindow einen String-Parameter. Dieser gibt den Parameter einfach an den Konstruktor der Elternklasse (JFrame) weiter. Damit weisen wir dem Programmfenster einen Titel zu. Alternativ könnte man diesen auch über die Methode setTitle() setzen bzw. verändern.

Nun wollen wir das kleine Icon in der Titelleiste auswechseln. Dies geschieht über die Methode setIconImage() welches einen Parameter vom Typ Image erwartet. Das regeln wir am einfachsten über die Klasse ImageIcon.

Nun kommen wir zu unserer ersten richtigen Swing-Kompontente – JLabel. Diese Klasse dient im Grunde dazu, einen vom Benutzer nichtveränderbaren Text darzustellen. Um diese Komponente auch anzuzeigen, müssen wir sie zuerst dem JFrame hinzufügen.
Dies funktioniert allerdings nicht ganz ohne Umwege. Die Klasse JFrame enthält bereits eine weitere Swing-Komponente, nämlich JPanel. Das ist auch jene Komponente, auf der die anderen grafischen Komponenten letztlich dargestellt werden. JPanels werden uns auch später noch begegnen, sie sind vielseitig einsetzbar und lassen sich auch beliebig ineinander verschachteln.
Um jetzt also auf das JPanel unseres JFrame zugreifen zu können, bedienen wir uns der Getter-Methode getContentPane(). Mit add() fügen wir das JLabel schlussendlich dem JPanel hinzu.

Somit wäre bereiten zwei essenzielle Dinge geklärt – wie erstelle ich eine Swing-Komponente und wie weise ich diese einer grafischen Oberfläche zu.
Im nächsten Kapitel behandeln wir die ersten wichtigen Formularelemente, wie Buttons und Textfelder.

Software, Tutorials , , , , , , , ,

Grafische Programmierung mit Java – Kapitel 1

November 20th, 2008

Read the english version of this article


Hinweis: Dieses Tutorial ist ohne bereits vorhandene Grundkenntnisse der Java-Programmierung ungeeignet! Es ist generell abzuraten, bei einer Programmiersprache gleich mit der grafischen Programmierung einzusteigen.

Willkommen beim ersten Teil von meinem Java-Tutorial für grafische Programmierung. Als ich selbst mit Java begonnen hatte, suchte ich vergeblich nach guten Tutorials für GUI-Programmierung (GUI = Graphical User Interface). Obwohl es durchaus gute Einstiegshilfen wie Java ist auch eine Insel gibt, konnte ich mich mit den Erläuterungen zur grafischen Programmierung nie sonderlich anfreunden. Deshalb möchte ich hier versuchen, Anfängern eine möglichst einfach verständliche Einstiegshilfe in die grafische Java-Programmierung zur Verfügung zu stellen.

Ich werde, aufgrund des ungleich größeren Umfangs an Möglichkeiten, allerdings nur Swing anstatt von AWT-Komponenten verwenden. (Mit Ausnahme von diversen fehlenden Äquivalenten)

Beginnen wir zuerst mit dem Grundfenster. Bevor wir überhaupt einmal ein grafisches Interface erstellen können, brauchen wir ein Programmfenster. Dieses wird in Swing durch die Klasse JFrame repräsentiert.

Hier ein kleines Code-Beispiel welches ein leeres Programmfenster initialisiert:

import javax.swing.JFrame;

public class TestWindow extends JFrame {
	public static void main( String[] args ) {
		TestWindow myWin = new TestWindow();
		myWin.init();

	}

	public void init() {
		this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		this.setBounds( 100, 100, 400, 300 );
		this.setVisible( true );
	}
}

TestWindow 01

TestWindow 01

Wollen wir uns diesen Quellcode einmal näher ansehen. Das Programm startet wie gewöhnlich in der main-Methode. Dort initialisieren wir zuerst eine Instanz von unserer Klasse TestWindow, welche von  JFrame erbt. Diese Klasse muss zuerst aus dem Package javax.swing importiert werden.

Über die selbstprogrammierte Methode init() werden anschließend drei Methoden aufgerufen. Durch die Setter-Methode setDefaultCloseOperation() wird bestimmt, wie sich das Fenster verhält wenn der Benutzer es schließen möchte. Im Beispiel wird als Parameter die Konstante JFrame.EXIT_ON_CLOSE übergeben, so wird das Programm beim Schließen des Fensters einfach beendet. Würde diese Zeile im Code fehlen, müsste man das Programm extra abwürgen (zB über den Task-Manager) – nicht besonders benutzerfreundlich ;)

Der Methode setBounds() übergeben wir die Koordinaten und die Größe des Fensters auf dem Bildschirm. Im Beispiel wird das Fenster an der Position X=100; Y=100 mit einer Breite von 400 Pixel und einer Höhe von 300 Pixel gezeichnet.

Damit das Fenster letztendlich überhaupt sichtbar wird, muss noch die Methode setVisible() mit dem boolschen Parameter true aufgerufen werden.

Wunderbar, jetzt haben wir unsere erste grafische Benutzeroberfläche! Allerdings hat es noch keinerlei Inhalt und die Titelleiste ist ebenfalls leer. Um das wollen wir uns im nächsten Kaptiel kümmern :)

Software, Tutorials , , , , , ,