Sep 27 2010

Lexicon Omega Studio und Midi

Was mein neues Lexicon Soundinterface an Hardware mitbringt, das läßt sie an Software-Architektur vermissen. Zwar ist das Aufnehmen von Audio nicht so das Problem, da das Teil einen Ausgang mitbringt, über den man direkt das aufgenommene Signal hört bevor es zum Rechner geschickt wird, das Timing bei Midi-Aufnahmen ist allerdings unter aller Kanone. Mag sein, das dies ein wenig mit der verwendeten Aufnahmeumgebung zu tun hat, da ich mich aber an mein gutes, altes Sonar gewöhnt habe, suche ich den Fehler natürlich als erstes bei der neuen Hardware. Und es war nicht zu machen. Auch bei extrem geringer Latenz (was bei diesem Teil als Größe der Aufnahmebuffer ausgedrückt wird) schwimmt das Timing, wie Nieselregen auf der Straße nach langer Trockenzeit.

Das Timing meiner alten E-MU-Karte war dagegen um einiges besser. Also lag der Gedanke nahe, für Midi-Aufnahmen weiterhin das Teil zu benutzen. Prinzipiel erlauben moderne Sequencer das Umschalten der verwendeten Treiber, wenn mehr als eine Soundkarte auf dem Rechner installiert ist. Was Softwaremäßig noch ganz einfach geregelt werden kann, wird im Hinblick auf die Abhöre aber ein echtes Problem. Man kann die Treiber nämlich nicht mischen. Also ein Karte für Midi und ein für Audio zu verwenden. Es ist zwar möglich einfach den Midi-Eingang der alten Karte zu nutzen, die Stärke dieser ist aber nur die Timing-Kontrolle, der Audio-Klang der neuen Karte ist um einiges besser. Dafür braucht man jedoch die Audio-Treiber. Schaltet man jetzt alles auf die alte Karte zurück, so wird auch das Audio-Signal über diese Karte wieder gegeben und man muß auch umgehend die Abhöre an die Ausgänge der alten Karte anschließen. Das ist natürlich immer ein ziemlich nervtötender Akt, da muß es andere Lösungen geben.

Versuche einfache die Ausgänge der alten Karte in zwei der Eingänge vom Lexicon zu schicken, gelangen zwar, jedoch ging das mit einem impertinentem Brummen einher, was auf Dauer doch genervt hätte. Lösung war schließlich, den Digital-Ausgang (SPDIF) mit dem Digital-Eingang der neuen zu verbinden. Das klappt zwar, aber mal ehrlich…das muß doch einfacher gehen. Die Karte hat 180 € gekostet und die Sequencer-Software nochmal das dreifache…


Sep 26 2010

Argentinische Piraten

So so, es gibt also auch einen Argentinischen Ableger der Piraten-Partei. Wußte ich vorher auch nicht, bis sie urplötzlich auf mein Blog verlinkt haben. Wenn ich das richtig verstehe, geht es da abermals um die Gewinner des “Free! Music! Contest!“. Interessanter Gedanke, das jetzt vielleicht irgendwo in Buenos Aires ein paar Kids zu “Gib Laut” moschen und keinen blassen Schimmer haben, was der Text bedeuten könnte.

Ich stelle es mir zumindest ulkig vor.


Sep 26 2010

MKV-Files und Windows 7

Heute bin ich auf etwas gestoßen, was nach meinem Dafürhalten ein echter Bug in Windows 7 ist. Bei Bild- und Video-Dateien ist es bei modernen Betriebssystemen ja üblich eine kleine Vorschau im Datei-Explorer anzuzeigen. Bei der Vorschau von .mkv-Dateien im Windows-Explorer scheint es Probleme zu geben. Die Vorschau wird nicht angezeigt. Das wäre nicht das Problem. Windows scheint aber im Hintergrund eine solche Vorschau erstellen zu wollen und greift dazu auf diese Dateien zu. Will man jetzt diese Files verschieben oder löschen, so bekommt man die Meldung, das die Datei bereits geöffnet sei und zwar vom Windows-Explorer. Jetzt steht man natürlich etwas doof da. Um den Dateizugriff zu beenden muß man das Programm beenden, welches den Zugriff verursacht. Dummerweise ist der Explorer bei den meisten Leute die einzige Möglichkeit, die Dateien auf der Festplatte zu verwalten. Zumindest, die Einzige die sie kennen. Wie schafft man es, den Explorer zu beenden und die Dateien dennoch zu löschen?

Ich konnte das Problem lösen, idem ich zunächst den Explorer beendet habe. Ja, das geht. Auch wenn der Explorer Windowsmäßig omnipräsent ist, ist der Explorer nicht gleich Windows. Das System beendet sich nicht, nur weil der Explorer beendet wird. Um den Explorer zu beenden einfach “strg-alt-ent” gleichzeitig drücken und den Task-Manager öffnen (Bei Windows 7 ganz am Ende der Liste). Im Taskmanager unter Prozesse den Eintrag “explorer” ausfindig machen, markieren und auf “Prozess beenden”-klicken. Wie können wir nun die Dateien kopieren und löschen? Mit Hilfe der Konsole. Um das Konsolen-Fenster zu öffnen geht man im Taskmanager auf “Datei” und wählt den ersten Menüpunkt “Neuer Task (Ausführen)” und gibt im darauffolgenden Dialog “cmd” ein. Es öffnet sich ein Fenster mit einem schwarzen Hintergrund. Hier kann man per Tastatur-Kommandos Änderungen am Datei-System vornehmen (und noch eine ganze Menge mehr aber alles zu seiner Zeit). Die wichtigsten Kommandos sind folgende:

1. dir – zeigt den aktuellen Verzeichnisinhalt.
2. ren – damit lässt sich eine Datei oder ein Verzeichniss um benennen.
3. cd – wechselt in ein anderes Verzeichnis (“..” – Wechselt in das übergeordnete Verzeichnis).
4. del – löscht eine Datei.
5. copy – kopiert eine Datei von A nach B.
6. help – zeigt eine Übersicht aller verfügbaren Kommandos an.

Ausgabe von "dir /?"

Ausgabe von "dir /?"

Jedes dieser Kommandos kann mit dem Parameter “/?” aufgerufen werden, dann erscheint eine Hilfe zum jeweiligen Befehl. “dir /?” erzeugt zum Beispiel die nebenstehende Ausgabe. Und jetzt heißt es frickeln. So lange die Verzeichnisse wechseln, bis man in dem Verzeichnis ist, in dem die Datei lagert und dann entweder umbennen, kopieren oder löschen. Mit dem entsprechenden Befehl. Zum Beispiel “ren a.txt b.txt”. Die Datei “a.txt” wird zu “b.txt”.
Oder eben “del a.txt”, bzw. “copy a.txt b”. Kopiert “a.txt” nach b, wenn b ein Verzeichnis ist.

Anschließend kann man wieder den Taskmanager hervorholen und mit “Datei”-> “Neuer Task” den Windows-Explorer wieder starten. Dazu einfach “explorer” als auszuführenden Task angeben. Der Explorer sollte  umgehend starten und die Änderungen am Dateisystem sichbar werden.

Beim Googeln habe ich gesehen, das das Problem wohl schon zu Vista-Zeiten aufgetreten sein soll. Da allerdings im Zusammenhang mit DivX-Installationen.

Hmm…wenn ich so die Installierten Programme bei mir durchgehe…DivX ist hier ja auch installiert. Vielleicht ist diesmal nicht Windows schuld, sondern dieses Codec-Geraffel?

Gleichgültig, ihr wisst euch ja jetzt zu helfen.


Sep 9 2010

Free! Music! Sampler!

Der Musikpiraten e.V. hat die Playlist für ihren neuen Free! Music! Sampler! veröffentlicht. Der Sampler kann per Bittorrent-Netzwerk herunter geladen werden oder direkt als gepresste CD bestellt werden. Alle Stücke sind unter CC-Lizenz veröffentlich, herunterladen ist also völlig legal und sogar erwüscht. An dem Contest haben 130 Künstler aus “aller Welt” teilgenommen und der Sampler soll einen möglichst abwechslungsreichen Querschnitt verschiedener Musikstile repräsentieren. Ich bin in der Kürze der Zeit nicht dazu gekommen alle Stücke anzuhören; was ich bisher gehört habe klingt aber sehr vielversprechend.
Bei der Menge an Musik war ich ja schon etwas überrascht, meinen eigenen Namen auf der Tracklist wieder zu finden. Freut mich natürlich, wenn hier und da mal ein Stück von mir durchaus anklang findet.


Aug 6 2010

Spass mit Swing und Eclipse

Manchmal ist es zum Verrückt werden. Die abgegebene Programmieraufgabe kam zurück mit dem Hinweis, das das Schließen des Fensters der graphischen Benutzeroberfläche bei jeder Option der Sicherheitsabfrage zum Programmende führt. Ok, der Fehler war recht schnell gefunden.  Für das Hauptfenster (ein JFrame) war als DefaultCloseOperation EXIT_ON_CLOSE eingestellt. Das Überlagern der entsprechenden Methode über einen WindowListener erzeugte zwar einen Dialog, jedoch scheint dann die ursprüngliche Methode wieder aufgerufen worden zu sein, die das Programm beendet hat. Also umgestellt und die Operation auf DO_NOTHING_ON_CLOSE gesetzt. Das Programm verhielt sich hinterher genauso. Hä?
Einige Stunden und etliche Versuche mit dem Hauptfenster später, stellt sich heraus, das der Fehler nicht bei mir lag. Mit einem Testfenster hatte ich nämlich das gleiche Problem. Scheinbar tritt das Problem immer dann auf, wenn der entsprechende Frame einmal mit der Zeile setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) compiliert wurde. Dann läßt sich dieser Wert nicht mehr auf etwas anderes bringen. Ich konnte es mehrfach reproduzieren, indem ich einfach einen Frame zunächst mit “Do-nothing” und anschließend mit “Exit” aufgerufen habe. Stellt man nach dem zweiten Programmaufruf wieder auch “do-nothing” wird die Option nicht mehr geändert.

Ich weiß nicht ob es an Java oder Eclipse liegt. Lösung war jedenfalls: Quelltext kopieren, die Klasse löschen und eine neue Klasse mit gleichem Namen hinzugefügt, in die der alte Quelltext wieder eingefügt wird. Da muß man erstmal darauf kommen.


Aug 1 2010

Tarifwechsel

Bisweilen ist es ja zumVerzweifeln. Da war ich neulich am Überlegen, ob ich bei meinem jetzigen DSL-Anbieter nicht einfach mal ein VDSL-Paket buchen sollte. Das Angebot sah recht nett aus, nur etwa 10 € teurer als jetzt und es hätte eine neue FritzBox gegeben. Frohes Mutes also den Bestelldialog durchgeklickt und versucht den Tarif zu buchen. Im Anschluß korrekterweise dargelegt, das ich bereits Kunde bei betreffender Firma bin und die Reaktion abgewartet. Das System stellt fest, dass meine Kundennummer bereits mit einem DSL-Vertrag verknüpft ist und fragt, ob ich den neuen Vertrag “dazu” buchen möchte. Nein, möchte ich nicht. Daraufhin verweist mich das System auf das Kundencenter. Ok, versuche ich hier mal einen Tarifwechsel. Ein Wechsel zu VDSL wird mir hier nicht angeboten. Ich kann den gleichen Tarif wie bisher für 5 € weniger im Monat bekommen, weitere Optionen gibt es hier nicht.
Zugegeben. Technisch betrachtet ist der Wechsel von DSL auf VDSL etwas mehr als ein schnöder Tarifwechsel. Bevor mein Anbieter VDSL anbieten kann, müssen sie zunächst die entsprechende Technik von der Telekom mieten und hoffen, das die sich nicht einfach quer stellen. Jedoch hätte ich es ziemlich gut gefunden, wenn man irgendwo im Kundencenter den Button hätte: “So Kollegen, jetzt schaut mal, ob ich VDSL bei euch bekommen kann und wenn ja, dann schaltet mir eine Leitung.” Vermutlich wird die VDSL-Geschichte aber ausschließlich für Neukunden angeboten, so dass Bestandskunden in die Röhre schauen.
Dummerweise gibt es keinen Kündigen-Button im Kundencenter. Na gut, dann muss ich mal über einen Anbieterwechsel nachdenken.


Jul 18 2010

Layoutmanager in Java

Ohne die gefürchteten Layout-Manager geht bei der Entwicklung von graphischen Benutzeroberflächen in Java herzlich wenig. Wer nicht gern auf die Arbeit mit entsprechenden GUI-Editoren zurückgreift, der steht schnell vor dem Problem, das zwar die Layoutmanager von Java zweckmäßig ihren Dienst verrichten, die Anordnung der einzelnen Komponenten innerhalb zum Beispiel eines Fenster eine echte Geduldsprobe ist. Daneben bläht sich der Quelltext schnell auf, da man gezwungen ist, die angezeigten Komponenten in weitere Komponenten einzubetten, um das gewünschte Gestaltungsziel zu erreichen. In jede Fall bekommt man schnell das Gefühl: Die Layoutmanager von Java machen einfach was sie wollen.
Gelegentlich sieht man Entwickler daher in die sogenannten “Null-Layouts” flüchten. Mit “Null-Layouts”  kann man zwar Position und Größe der einzelnen Elemente genau bestimmen, jedoch bleiben sie fix. Finden Größenänderungen an der aufnehmenden Komponente statt, wirken sich diese nicht auf die Komponenten aus, die innerhalb der Komponente platziert wurden. Es steht eben kein Layoutmanager mehr zur Verfügung, der die Herrschaft über das Desing übernimmt. Diese Überlegungen führten mich im Rahmen meines Programmierpraktikums dazu, mich ein wenig mit der Entwicklung von Layoutmanagern zu befassen.

Ich für meinen Teil finde die Lösung mit den Null-Layouts eigentlich ziemlich reizvoll, da sie eine einfache und übersichtliche Möglichkeit bieten Komponenten auf dem Bildschirm zu platzieren. Insofern trug mich der Gedanke zu einem Layoutmanager, der alle Objekt anfangs über die setBounds()-Methode platziert und ausrichtet, im Falle einer Größenänderung der umgebenen Komponente jedoch in der Lage ist, die Verhältnisse neu anzupassen. Nach Möglichkeit der Gestalt, das die ürsprünglichen Größen- und Abstandsverhältnisse beibehalten werden. Eine passende Lösung habe ich mittlerweile gefunden und will hier kurz beschreiben, wie das Implementieren eines entsprechenden Layoutmanagers in Java von statten geht.

In Java werden die Layoutmanager als Strategie zur Gestaltung von Anzeigeelement aufgefaßt und als Interface realisiert. Es gibt zwei Typen von Layoutmanagern (LayoutManager und LayoutManager2), die wir für die Implementierung heranziehen können. LayoutManager2 ist dabei von LayoutManager abgeleitet und bietet mehr Methoden an, bzw. erfordert vom Entwickler mehr Methoden zu implementieren. Will man einen Layoutmanager implementieren, so realisiert man eine Klasse und läßt diese per Implements-Statement von den LayoutManagern “erben”. Durch das Ausarbeiten der einzelnen Methode definiert man dann das Verhalten des Managers.

Der Kern beider Layoutmanager bildet die Methode “layoutComponent()“. Diese Methode bekommt eine Referenz auf jene Komponente übergeben, für das der Layoutmanager ein Layout berechnen soll. Vorher muß der Manager natürlich wissen, welche Komponenten er da eigentlich verwalten soll. Zu diesem Zweck muss der Manager buch über alle Komponenten führen, die einem Design hinzufügt wurden. Dafür ist die addLayoutComponent()-Methode zuständig, die offenkundig innerhalb der add()-Methode aufgerufen wird, über die jede von Container abgeleitete Klasse verfügt. Für die Entwicklung eines Layout-Managers, der initial mit Bounding-Boxes arbeiten soll, müssen wir jeder Komponente weitere Informationen mitgeben. Namentlich sind das die Angabe, wo sie im Anzeigebereich mit welchen Abmessungen platziert werden soll. Das Problem hier ist, das die add()-Methode neben der Übergabe der eigentlich Komponente lediglich ein weiteres Objekts als Parameter zuläßt (in der Dokumentation “Constrains” genannt). Ist die Komponente dem Layout hinzugefügt, können wir jedoch nicht mehr so einfach darauf zugreifen, um Einstellungen darauf vorzunehmen. Wir brauchen also ein Objekt (diesmal auch vom Typ Object) über die wir diese Informationen an den Layoutmanager herantragen können. Da es keine Standardklasse gibt (bzw. ich keine gefunden habe), die unsere Anforderungen erfüllt, müssen wir sie selbst implementieren. Wir erzeugen also eine Klasse und haben wir damit unseren Informationsträger, den wir der add()-Methode übergeben können. Per Default erben schließlich alle Klassen in Java von Object.  Die so erzeugten Objekte enthalten die absolute Position innerhalb des darstellenen Komponente, sowie deren Höhe und Breite als Attribute und stellen Methode bereit, um diese zu verändern. Für die Implementierung sind es reine “Wegwerf”-Objekte, die direkt im Aufruf der add()-Methode annonym erzeugt werden und vom Garbage-Collector wieder eingesammelt werden können, sobald die entsprechenden Informationen beim Layoutmanager angekommen und ausgelesen wurden. Hier der komplette Quelltext der Klasse:


public class Bounds
{
	private int x, y, width, height;

	public Bounds(int x, int y, int width, int height)
	{
		this.x = x;		// x Position
		this.y = y;		// y Position
		this.width = width;	// Breite
		this.height = height;	// Höhe
	}

	// Getter
	public int getX()
	{
		return x;
	}
	public int getY()
	{
		return y;
	}
	public int getWidth()
	{
		return width;
	}
	public int getHeight()
	{
		return height;
	}
}

Objekte dieses Typs werden die benötigten Informationen direkt im Konstruktor übergeben. Die Werte werden gespeichert und können dann vom Layoutmanager über die Getter genutze werden, um die Komponente zu platzieren. Man sieht: Eine recht einfache Klasse, die uns nur als Informationsträger dient.

Für die Verwaltung unserer Komponenten reichen diese beiden Klassen allerdings noch nicht aus. Unsere Layoutstrategie orientiert sich an der ursprünglichen Position aller Komponenten innerhalb der darstellenden Komponente und soll die Verhältnisse, die jede Komponente in Relation zu Höhe und Breite der umgebenen Komponente hatte, beim Neuberechnen des Layouts beibehalten (Den Satz kann man übrigens gern dreimal lesen…). Es reicht also nicht, wenn der Layoutmanager nur eine Referenz auf die verwalteten Komponente und deren ursprüngliche Position speichert, auch die Verhältnisse im ursprünglichen Anzeigebereich muß festgehalten werden. Zu diesem Zweck wird eine dritte Klasse benötigt. Die dritte Klasse speichert eine Referenz auf die verwaltete Komponente selbst und gleichzeitig für X und Y Koordinate, sowie für Höhe und Breite einen double Wert, der das Verhältnis von Höhe, Breite und Position in Relation zur aufnehmenden Komponente speichert. Hier einmal der Quelltext:


public class LayoutManagerComponent
{
	Component myComponent;
	double relativeX, relativeY;
	double relativeHeight, relativeWidth;
	double relativeFontSize;		

	public LayoutManagerComponent(Component comp)
	{
		myComponent = comp;
		relativeX = 0.0;
		relativeY = 0.0;
		relativeHeight = 0.0;
		relativeWidth = 0.0;
		relativeFontSize = 0.0;
	}
	// Setters
	public void setRelativeX(double relativeX)
	{
		this.relativeX = relativeX;
	}
	public void setRelativeY(double relativeY)
	{
		this.relativeY = relativeY;
	}
	public void setRelativeHeight(double relativeHeight)
	{
		this.relativeHeight = relativeHeight;
	}
	public void setRelativeWidth(double relativeWidth)
	{
		this.relativeWidth = relativeWidth;
	}
	public void setRelativeFontSize(double relativeFontSize)
	{
		this.relativeFontSize = relativeFontSize;
	}

	// Getters
	public Component getComponent()
	{
		return myComponent;
	}
	public double getRelativeX()
	{
		return relativeX;
	}
	public double getRelativeY()
	{
		return relativeY;
	}
	public double getRelativeHeight()
	{
		return relativeHeight;
	}
	public double getRelativeWidth()
	{
		return relativeWidth;
	}
	public double getRelativeFontSize()
	{
		return relativeFontSize;
	}
}

Wie man sieht, habe ich etwas gelogen. Diese Klasse speichert neben der relativen Position und relativen Größe auch einen Wert, der die relative Schriftgröße angibt. In der Tat ist auch die Größe der Schrift eine Aufgabe, die der Layoutmanager im Zweifel übernehmen muß, sonst passen sich zwar die Komponenten, die Schrift aufnehmen, der umgebenen Komponente an, der angezeigte Text bleibt jedoch unverändert. In jedem Fall sieht man auch hier, das die Klasse ein reiner Informationsträger ist und keinen Code enthält, der mehr mach als die Attribute zu verändern und diese von Außen zugänglich zu machen. Die Implementierung dieser Klasse erfolgt nun in Objekten des Layoutmanagers selbst. Werfen wir einen Blick auf den Quellcode des Layoutmanagers:



public class RelativeScaleAndPlacementLayout implements LayoutManager2
{
	ArrayList compsToCalc;
        double firstWidth, firstHeight;	

	public RelativeScaleAndPlacementLayout()
	{
		firstWidth = -1;
		firstHeight = -1;
		compsToCalc = new ArrayList();
	}
	public void addLayoutComponent(Component toAdd, Object bounds)
	{
		// Wir müssen erst casten.
		Bounds theBounds = (Bounds) bounds;
		// Anschließend Fonts ermitteln und dessen Größe speichern.
		// Die Relative Größe wird anhand der Höhe des Containers ermittelt.
		if (toAdd.getFont() != null)
		{
			Font tmpFont = toAdd.getFont().deriveFont(0, theBounds.getHeight() / 2);
			toAdd.setFont(tmpFont);
		}
		// Anschließend Platzieren.
		toAdd.setSize(theBounds.getWidth(), theBounds.getHeight());
		toAdd.setLocation(theBounds.getX(), theBounds.getY());
		compsToCalc.add(new LayoutManagerComponent(toAdd));
	}
	public Dimension maximumLayoutSize(Container parent)
	{
		int x, y;
		x = 0;
		y = 0;
		for (LayoutManagerComponent comp: compsToCalc)
		{
			y = y + comp.getComponent().getHeight();
			x = x + comp.getComponent().getWidth();
		}
		return new Dimension(x,y);
	}
	public void layoutContainer(Container parent)
	{
		Bounds tmpBs = new Bounds(0,0,0,0);
		float tmpFontSize = 0;
		Font tmpFont;
		// Wurde dieses Objekt schon initialisiert?
		if (firstWidth == -1 || firstHeight == -1)
		{
			// Nein, also speichern wir die augenblickliche Größe.
			firstHeight = parent.getHeight();
			firstWidth = parent.getWidth();
		}
		for (LayoutManagerComponent comp: compsToCalc)
		{
			if (comp.getRelativeX() == 0.0 && comp.getRelativeY() == 0.0)
			{
				comp.setRelativeX(comp.getComponent().getLocation().x / firstWidth);
				comp.setRelativeY(comp.getComponent().getLocation().y / firstHeight);
			}
			if (comp.getRelativeHeight() == 0.0 && comp.getRelativeWidth() == 0.0)
			{
				comp.setRelativeHeight(comp.getComponent().getHeight() / firstHeight);
				comp.setRelativeWidth(comp.getComponent().getWidth() / firstWidth);
			}
			if (comp.getRelativeFontSize() == 0.0)
			{
				comp.setRelativeFontSize(comp.getComponent().getFont().getSize2D() / firstHeight);
			}
			// Anschließend berechnet die neuen Bounds...
			tmpBs.setX((int)(parent.getWidth() * comp.getRelativeX()));
			tmpBs.setY((int)(parent.getHeight() * comp.getRelativeY()));
			tmpBs.setHeight((int)(parent.getHeight() * comp.getRelativeHeight()));
			tmpBs.setWidth((int)(parent.getWidth() * comp.getRelativeWidth()));
			// ...und die neue Schriftgröße...
			tmpFontSize = (float) (parent.getHeight() * comp.getRelativeFontSize());
			tmpFont = comp.getComponent().getFont().deriveFont(tmpFontSize);
			// ...dann wende sie auf das betrachtete Objekt an.
			comp.getComponent().setBounds(tmpBs.getX(), tmpBs.getY(), tmpBs.getWidth(), tmpBs.getHeight());
			comp.getComponent().setFont(tmpFont);
		}
	}
	public Dimension minimumLayoutSize(Container parent)
	{
		return maximumLayoutSize(parent);
	}
	public Dimension preferredLayoutSize(Container parent)
	{
		return maximumLayoutSize(parent);
	}
	public void removeLayoutComponent(Component comp)
	{
		for (LayoutManagerComponent comps : compsToCalc)
		{
			if (comps.getComponent() == comp)
			{
				compsToCalc.remove(comps);
				return;
			}
		}
	}
	public void addLayoutComponent(String name, Component toAdd)
	{
	}
	public float getLayoutAlignmentX(Container parent)
	{
		return 0;
	}
	public float getLayoutAlignmentY(Container parent)
	{
		return 0;
	}
	public void invalidateLayout(Container parent)
	{
	}
}

Gehen wir mal durch was diese Klasse tut. Es ist nicht viel. Eines der wichtigsten Attribute des Layoutmanages ist die ArrayList, die mit “LayoutManagerComponent” parametrisiert ist. Innerhalb des Layoutmanagers werden also alle Komponenten in einem Objekt vom Typ der zuvor besprochenen Klasse verwaltet. Wird dem Manager eine Komponente über die addLayoutComponent()-Methode hinzugefügt, wird die übergebenen Komponente zunächst auf die entsprechenden Abmessungen und Koordinaten eingestellt und ein neues LayoutManagerComponent-Objekt erzeugt, das die hinzugefügte Komponenten im Konstruktor als Parameter erhält und der ArrayList “compsToCalc” hinzugefügt wird. Im Konstruktor des LayoutManagerComponent-Objekts geschieht nichts weiter, als das die Referenz auf die zu verwaltende Komponente gespeichert wird und alle sonstigen Attribute auf 0.0 eingestellt werden. Damit sind zwar die Objekte initialisiert, aber noch nicht die richtigen Werte ermittelt und eingestellt. Diese Aufgabe wird in der layoutContainer()-Methode nachgeholt. Die layoutContainer()-Methode ist das Herzstück eines jeden Layoutmanagers. Diese Methode durch das Eventsystem jedesmal dann aufgerufen, wenn das Container-Objekt neugestaltet werden muß, da sich zum Beispiel die Größe geändert hat oder das Objekt zuvor verdeckt war und nun neu gezeichnet werden muß.

Wird die layoutContainer()-Methode dieses Layoutmanagers das erste mal aufgerufen (in der Regel also, wenn das Objekt zum ersten Mal auf dem Bildschirm angezeigt wird), so stehen noch die beiden Attribute “firstWidth” und “firstHeight” auf -1. Daran erkennt die Methode, das für diese Layoutmanager-Objekt noch keine initialen Werte gespeichert wurden und holt dies nach. Anschließend wird für jedes Objekt innerhalb der ArrayList geprüft, ob bereits die Werte für die relative Postion und Größe, sowie die relative Schriftgröße gespeichert wurden. Ist dies nicht der Fall, so werden diese Werte jetzt ermittelt und stehen ab dann für die Platzierung der Elemente zur Verfügung. Als Verhältnis wird einfach die aktuelle Position und Größe geteilt durch die initiale Höhe und Breite der Komponente angenommen. Die jeweiligen absoluten Positionen werden anhand der neuen Abmessungen des aufnehmenden Containers ermittelt, indem die entsprechenden Werte mit den relativen Werten multipliziert werden. Dieses Vorgehen wird auf alle Komponenten innerhalb der ArrayList angewandt und dies bei jedem Aufruf von layoutContainer.

Alle weiteren Methoden sind lediglich zier. Durch das LayoutManager-Konzept von Java sind sie zwingendermaßen zu implementieren und machen bei näherer Betrachtung auch Sinn. Für meine Fall waren sie aber einigermaßen bedeutungslos, auch wenn hier die ein oder andere Methode dennoch implementiert wurde.  Näheres dazu entnimmt man jedoch am Besten der Java-Dokumentation.

Softwareentwicklung ist eine komplizierte Sache, ich hoffe dennoch, ich konnte die Arbeit von Layoutmanagern in Java etwas veranschlaulichen. Wer sich den Quelltext der drei Klassen mal mit Kommentaren anschauen möchte, kann die Dateien unten herunterladen.

Bounds.java
Manager.java
ManagerComponent.java


Jul 13 2010

Kleine Änderung

Mir zwittscherte gerade ein Vöglein, das moderne Browser mittlerweile die Möglichkeit bieten, eingebettete Schriftarten anzuzeigen und also auch in einem Blog zu nutzen. Das war mir irgendwie entgangen. Nichts desto trotz ist das eine der wichtigsten Gestaltungsmöglichkeiten innerhalb des HTML und CSS-Komplexes, auf die ich schon seit Jahren warte. Insofern kam ich nicht umhin, die Möglichkeit zu nutzen und mal eine von Googles Webfonts in das Blog einzubinden. Ich hoffe es gefällt und niemand stößt sich daran, das die Schriftart von einem Google-Server geladen wird.


Jul 6 2010

Netzlaufwerk und Printserver

Nachdem ich vor ein paar Monaten einen zweiten Rechner angeschafft habe, wurde es Zeit auch den Drucker und ein externes USB-Laufwerk im Netzwerk verfügbar zu machen. Es ist ja nicht ganz so praktisch für jedes Dokument, das man mal eben ausdrucken möchte, den Desktop-Rechner hochzufahren, die Datei dort hin zu kopieren und anschließend zu drucken. Da meine FritzBox noch keine USB-Anschlüsse hat, stand die Anschaffung eines kleinen Printservers auf dem Programm. Entsprechende Netzwerkadapter gibt es zu Hauf, vielen sagt man jedoch nach, das sie nicht sehr zuverlässig seien. Daneben verfügen die meisten lediglich über 100 MBit Schnittstellen und es läßt sich in der Regel nur ein Gerät anschließen. Nach etwas suchen kam ich auf ein Gerät, welches Conrad vertreibt und wohl auch herstellen läßt. Bei dem Preis konnte man nicht viel falsch machen, also habe ich es kurzer hand bestellt. Heute ist das Gerät angekommen, zusammen mit einem einfachen Intelli-Switch, da meine FritzBox nur einen LAN-Anschluß besitzt. Beides ist jetzt in Betrieb genommen und sowohl Drucker als auch Laufwerk sind bei mir jetzt über das Netzwerk erreichbar.

Wie es bei solch einfachen Geräten asiatischer Herkunft oft so ist: Die Dokumentation ist wieder ziemlich sparsam. Insofern zeige ich hier mal kurz, wie man den Print-Server und das Laufwerk unter Window 7 zum Laufen bekommt. Nachdem das Gerät mit der FritzBox verbunden ist, beschafft es sich sofort eine Netzwerkadresse und bietet seine Dienste im Netz an. Die Konfiguration läuft auch bei diesem Gerät über eine HTML-Seite, die man aufrufen kann, wenn man die IP-Adresse des Gerätes in die Adresszeile des Browsers eintippt. Leider weiß man am Anfang nicht, welche Adresse das Gerät zugewiesen bekommen hat. Normalerweise könnte man die Adresse im Router selbst Auslesen, dieser fungiert bei den meisten als DHCP-Server und führt Buch über die vergebenen IP-Adressen. In meinem Fall spinnt die FritzBox etwas und läßt mich nicht mehr ins Routermenü, wo man solche Daten abfragen könnte. Abhilfe schafft hier der ARP-Befehl von Windows.

Unter Start "cmd" eingeben.

Unter Start "cmd" eingeben.

Über ARP lassen sich alle Netzwerkgeräte im lokalen Netz ausfindig machen (Wer mehr Hintergründe haben möchte, schau bitte hier.), solange sie über IP- oder MAC-Adresse verfügen. Ausgeführt wird er unter der Eingabe Aufforderung “CMD” von Windows. Unter Windows 7 geht man dazu auf “Start”, klickt in das “Suchen”-Feld ganz unten und gibt hier “cmd” ein. Nach dem Drücken der Eingabe-Taste sollte sich ein kleines Fenster mit schwarzem Hintergrund öffnen. Hier geben wir einfach den Befehl ein, zusammen mit der Option -a. Also:

“arp -a”

und Enter. Anschließend sehen wir eine Übersicht der Gerät im Netz, im Zweifel für jeden Netzwerkadapter eine. Es ist nicht sofort ersichtlich welches das Gerät ist, welches wir eigentlich suchen, da hier eine Menge mehr angezeigt wird, als wir eigentlich gewohnt sind. So sehen wir bei mir, als zweite Schnittstelle den LAN-Adapter, der in diesem Beispiel nicht verbunden ist. Dennoch gibt es einen statischen Eintrag im Bereich 169.254.x.x. Normalerweise würde Windows diesem Adapter eine 169.er Adresse zuweisen, wenn das Gerät keine IP-Adresse bekommt. Ich vermute, der statische Eintrag am Ende des Adressraums reserviert Windows gleich für den DHCP-Request. Das aber nur am Rande.

Übersicht der Adressen im lokalen Netzwerk.

Übersicht der Adressen im lokalen Netzwerk.

Um das Richtige zu ermitteln, ist es hilfreich nur einen Rechner, den Router und eben den NAS-Adapter im Netz zu haben. Dann nämlich läßt sich die Adresse relativ leicht herausfinden. Wir konzentrieren uns bei der Suche auf die Geräte, die eine dynamische Adresse bezogen haben. Im Bereich 192.168.178.x sind dies genau zwei. Einmal die FritzBox selbst und der NAS-Adapter (mein Laptop hatte in diesem Beispiel die Adresse  192.168.178.21, diese steht oben drüber). Die FritzBox ist auf die 192.168.178.1 geeicht, also kann der Adapter nur 192.168.178.25 haben. Wir schnappen uns die Adresse und tippen sie in die Adresszeile des Browsers ein. Der Adapter begrüßt uns mit einer Anmeldemaske und fordert Benutzername und Kennwort. Standardmäßig ist dies “admin” und “admin”. Diese Daten sollten wir beim ersten Anmelden sofort ändern.

Menü des NAS-Adapters nach der Anmeldung.

Menü des NAS-Adapters nach der Anmeldung.

Auf der Übersichtsseite kann man die ersten Informationen zu dem Gerät ablesen. Wir gehen als erstes in den Administrationsbereich und ändern das Kennwort des Standardbenutzers. Beim Passwort darauf achten, keine Umlaute zu verwenden, der Adapter ist auf englische Spracheinstellungen getrimmt. Hinterher ist es angebracht, im Menü “LAN Config” den dynamischen Adress-Bezug auf statisch zu ändern. Wir wollen Drucker und Laufwerk schließlich nicht jedes mal neu in Windows hinzufügen. Allerdings sollte man im Hinterkopf behalten, das die FritzBox unter Umständen die vergebene IP-Adresse später an ein anderes Gerät vergibt, insbesondere dann, wenn der NAS-Adapter mal ausgeschaltet sein sollte. Je nachdem, wie groß das eigene Netzwerk ist, wird diese Option Probleme machen. Dann sollte man darüber nachdenken, das gesamte Netzwerk mit statischen IP-Adressen zu betreiben. Im Menü “LAN Config” einfach den Punkt bei “Static IP as below” setzen und auf “apply” klicken. Anschließend können wir uns ein wenig im Menü umsehen und schauen, was das Gerät so macht.

Prinzipiell scheint dieser kleine Netzwerkapdater nicht ganz dumm zu sein. Gesetzt dem Fall, man schließt den Druker an die richtige USB-Buchse an, erkennt das Gerät den Drucker und macht ihn gleich im Netzwerk verfügbar. Man sieht es, wenn man auf “Print-Server” clickt. In meinem Fall hat er den Namen und Hersteller des Gerätes schon erkannt. Gut, dann fügen wir das Gerät auf dem Laptop hinzu. Das Hinzufügen ist unter Windows meiner Meinung nach etwas verwirrend, da man bei Einrichten von Netzwerkdruckern keinen Netzwerkdrucker installiert, sondern einen lokalen Drucker. Aber alles der Reihe nach.

Wir fügen einen lokalen Drucker hinzu!

Wir fügen einen lokalen Drucker hinzu!

Wir klicken auf “Start->Geräte” und Drucker und dort auf “Drucker hinzufügen” und gehen den Assistenten durch. Es beginnt, wie ich schon sagte, mit der verwirrenden Option “Einen lokalen Drucker hinzufügen”. Auf der nächsten Seite sollen wir den Anschluß am Rechner auswählen. Auch hier ist die Verwirrung erstmal groß, da der Druck ja nicht am Rechner angeschlossen ist und die Netzwerkkarte ist nicht dabei. Wir erstellen uns also wir einen neuen Anschluß. Ja, wir erstellen ihn einfach. Ohne auf die Details einzugehen: Aus Sicht des Betriebssystems sind alle Anschlüsse am Rechner nur als Software verfügbar, die über die Treiber der Hardware zur Verfügung gestellt werden. Für Windows macht es keinen großen Unterschied, ob das Gerät tatsächlich am Rechner angeschlossen ist oder nicht, das Betriebssystem muß nur wissen, wie es mit dem Gerät kommunizieren soll. Für Drucker hat sich bereits ein Standard entwickelt, der von so gut wie allen Netzwerkkarten unterstützt wird. Wir können diesen Standard nutzen. Der Begriff “Anschluß” ist hier mehr eine Metapher.

Standard TCP/IP-Porr wählen.

Standard TCP/IP-Porr wählen.

Wir wählen also als Option “Standard TCP/IP-Port”, da wir den Drucker ja über das Netzwerkprotokoll nutzen möchten. Und klicken auf “weiter”. Anschließend möchte Windows von uns wissen, wo der Drucker wohl zu finden ist. Hier tragen wir wieder die IP-Adresse des NAS-Adapters ein. Der Adapter weiß schon, was er zu tun hat, wenn wir ihn mit dem entsprechenden Print-Server-Protokoll ansprechen. Wir lassen den Haken bei “Drucker abfragen und den verwendeten Druckertreiber automatisch auswählen”. Vermutlich wird Windows nicht in der Lage sein, den Treiber automatisch auszuwählen, einen Versuch ist es jedoch wert. Hiernach versucht Windwos eine Verbindung zu dem Gerät aufzubauen. Dies kann eine Zeit dauern, man sollte also Geduld haben. Wurde der Drucker im Netz gefunden, wird Windows auf den Dialog “Abschließende Anschlussinformationen erforderlich” wechseln. Hier ändern wir die Option “Standard” auf “Benutzerdefiniert” und klicken auf “Einstellungen”. Im Nachfolgenden Dialog sind dann nochmal ein paar Optionen von Nöten, wie sie auch schon aus der “Dokumentation” des NAS-Adapters ersichtlich sind.

Einstellungen für den Druckerport.

Einstellungen für den Druckerport.

Ich habe mich hier (ohne genau zu wissen, wofür die einzelnen Optionen da sind) einfach an die Vorgaben aus der Anleitung gehalten. Dabei habe ich den Portnamen wie in der Anleitung auf “IP_192.168.178.25″ geändert. Den Punkt bei “LPR” gesetzt, den Queue Name “LRxxxx” vergeben und den Byte-Zähler aktiviert. Anschließend auf “Ok” und im vorigen Dialog auf “weiter”. Windows sollte jetzt fragen, welchen Druckertreiber er für diesen Drucker verwenden soll. Bei meinem Drucker war es recht leicht, da er gleich in Windows 7 integriert war, ich mußte ihn nur noch auswählen. Sollte der Drucker nicht in der Auswählliste erscheinen, sollte man den entsprechenden Treiber installieren.

Am Schluß wird Windows eine Übersicht anzeigen und die Möglichkeit geben, eine Testseite zu drucken. Den Testdruck nehmen wir mit. Im Idealfall fängt der Drucker gleich an zu rödeln. Anschließend speichern; der Drucker sollte nun als Drucker in der Systemsteuerung verfügbar sein und damit von allen Anwendungen aus nutzbar sein.

Ein Problem bei diesen Printservern ist natürlich, das Multifunktionsgeräte etwas Stiefmütterlich behandelt werden. So kann der NAS-Adapter lediglich Drucken und nicht den Scanner an meinem Gerät bedienen (heißt ja auch Print-Server das Teil). Das nehme ich in Kauf, wenn ich doch mal etwas Scannen muß, wird der Drucker kurz direkt an den Laptop angeschlossen. Das kommt allerdings recht selten vor, deshalb mache ich mir darum noch keine Gedanken. Schauen wir einmal weiter, wie wir das Laufwerk einbinden können.

Unter dem Menüpunkt “Disk Tool” im Menü des Adapters können wir unser USB-Laufwerk im Idealfall bereits sehen. Dummerweise verlangt der Adapter von uns, das wir das Laufwerk als erstes Formatieren. Der Adapter unterstützt nur FAT32-Formatierungen und selbst, wenn das Laufwerk bereits im entsprechenden Format vorliegt, müssen wir die Platte erst formatieren. Offenbar wird durch die Formatierung ein Prozess angestoßen, durch den die Rechteverwaltung für das Laufwerk installiert wird. Augenscheinlich läuft auf diesem Apater ein abgespecktes Linux (oder ähnliches), welches die Ressourcen verwaltet. How ever. Wir müssen die Platte formatieren, gleichgültig ob es ein FAT32-Laufwerk ist oder nicht. Erst dann können wir auf das Laufwerk über diesen Adpater zugreifen.

Rechtsklick auf "Netzwerk".

Rechtsklick auf "Netzwerk".

Bei mir ging die Formatierung recht fix und ist sie abgeschlossen, kann man sich die beiden Optionen “File Server” und “FTP-Server” anschauen. Für beide Servertypen hat der Adapter Benutzer eingereichtet, die auf entsprechende Verzeichnisse zu greifen können. Auch hier gehen wir als erste daran und ändern die Kennwörter. Wenn wir beim Fileserver (übrigens ein Samba-Server, weshalb ich auf den Gedanken mit dem abgespeckten Linux gekommen bin) den Standardbenutzer  markieren und auf “modify” klicken, können wir oben das Kennwort ändern. In der Auswahl darunter sehen wir die Verzeichnisse, auf die der Benutzer Zugriff haben soll. Wir merken uns den Namen des Verzeichnisses, welches standardmäßig vergeben ist. Bei mir war es “public” und auf dieses Verzeichnis konnte sowohl der FTP-Benutzer als auch der Samba-Benutzer zugreifen. Es ist jedoch auch möglich hier neue Verzeichnisse anzulegen und entsprechende User dafür anzulegen. Je nachdem, wie man es mag. In Windows wird das entsprechende Verzeichnis später als Laufwerk zu sehen sein. Es ist also möglich mehrere Verzeichnisse anzulegen und entsprechend viele Netzwerklaufwerke einzubinden. Wenn wir den Benutzernamen und das Verzeichnis kennen, öffnen wir den Dateibrowser von Windows und schauen auf der linken Seite nach dem Menüpunkt “Netzwerk”. Darauf machen wir einen Rechtsklick und wählen die Option “Netzlaufwerk verbinden”. Nun geht ein Dialogfenster auf, in das wir die Adresse des Laufwerks eintragen müssen. Die Adresse ist abermals die IP-Adresse, die wir für den NAS-Adapter ermittelt haben.

Adresse und Pfad zum Laufwerk eintragen.

Adresse und Pfad zum Laufwerk eintragen.

In meinem Fall also wieder die “192.168.178.25″. Wichtig ist hierbei, die Adresse mit zwei Schrägstrichen zu versehen (“Alt GR” + “ß”), sonst findet Windows nichts. Nach der Adresse selbst müssen wir noch das Verzeichnis angeben, welches wir vorhin im Menü “File Server” in den Benutzereinstellungen gefunden haben. In meinem Fall war dies “public”. Ist beides eingetragen, gehen wir auf “Fertig stellen” und Windows sollte anfangen das Laufwerk zu suchen. Hat Windows das Lauferk gefunden, fragt das Betriebssystem sofort nach den Anmeldedaten. Hiermit sind abermals die Daten gemeint, die in der Benutzerverwaltung des File Servers hinterlegt wurden. Sind diese Daten richtig eingetragen, fügt Windows das Laufwerk im Dateibrowser unter dem angegebenen Laufwerksbuchstaben hinzu. Ab jetzt kann normal darauf zugegriffen werden. Wir können also Dateien speichern, löschen und von dort kopieren. Verzeichnisse erstellen und entfernen. Gerad so, wie man es von Windows gewohnt ist.

Und jetzt probiere ich mal aus, was passiert, wenn man den Adapter vom Strom nimmt und zur Arbeit fährt…

Update: Alles Prima. Übrigens: Auf XP-Systemen läuft das Einbinden von Netzlaufwerk und Einrichten des Druckers genauso. Die Dialog sehen auch fast genauso aus.


Jul 1 2010

Free! Music!

Die Musikpiraten veranstalten auch dieses Jahr wieder ihren Musikwettbewerb für CC-Lizensierte Musik. Der Musikpiraten eV ist ein gemeinnütziger Verein, der sich der Verbreitung von lizenzfreier Musik verschrieben hat. Der Musikwettbewerb soll CC-Musiker in der Breite bekannter machen.
Die Teilnahmebedingungen sind denkbar einfach: Jeder, der seine Musik unter CC-Lizenz veröffentlicht, kann teilnehmen. Die teilnehmenden Werke werden von einer Jury begutachtet und haben die Chance auf dem Free! Music!-Sampler zu landen. Dieser wird nach Ende des Wettbewerbs im Oktober als kostenloser Download angeboten bzw. kann als gepresste CD bezogen werden. Der Wettbewerb soll mit einem großen Konzert in Wiesbaden enden auf dem auch die CC-Künstler spielen sollen.

Mehr Infos gibt´s auf den Wettbewerbsseiten selbst oder hier.