Mittwoch, 30. November 2011

RAD Update auf 8.0.4

Seinen RAD von 8.0.3 auf 8.0.4 upzudaten kann eine Herausforderung sein, aber bei diesem Produkt ist man ja eigentlich Kummer gewohnt.
Mein erstes Problem war folgende Fehlermeldung:

Eclipse p2 reconciler returned with error status=13

Die zugehörige IBM-Hilfeseite  empfahl den Installation Manager so zu starten:

IBMIM.exe -vmargs -Dcic.doNotReconcile=true

Leider führte das nicht zum erwarteten Erfolg, erst ein Rollback auf 8.0.1 und ein dann ein Upgrade auf 8.0.4 brachte endlich Erfolg, allerdings mußte man den Installation Manager mit den zusätzlichen Parametern starten, sonst gab es immer den  den Error Status 13.

Sieht man sich dann die Version an zeigt er zwar immer noch 8.0.1, aber die Build ID weißt zumindest auf 8.0.4 hin:








Mittwoch, 9. November 2011

Thinkpad T61 - fan error

Wenn beim Hochstarten die Fehlermeldung "fan error" kommt und dann nichts mehr geht (außer die Meldung mit Esc zu ignorieren) stimmt wahrscheinlich mit dem Lüfter etwas nicht.

Hilft sicher nicht immer, aber bei mir hats geklappt das Teil aufzuschrauben und mit dem Staubsauger mal den Lüfter bearbeiten.

Dazu muß man die Frontplastik und das Keyboard entfernen, damit man auch die richtigen Schrauben erwischt gibts hier das Hardware Maintenance Manual von Lenovo.
Die Schrauben für die Frontplastik (Palm rest) sind auf Seite 66 angegeben, für die Tasten ist Seite 70 ein guter Tip.




Dienstag, 8. November 2011

Eclipse Network connections - SOCKS Problem

Eclipse 3.7.1

Sitzt man hinter einem Proxy muß man diesen in Eclipse eintragen um zu seinem Updates oder zum Eclipse Marketplace zu kommen. Hinterhältig wird die Sache wenn man dort den Active Provider auf Manual setzt und brav Host, Port, Auth und User einträgt und dann draufkommt, da tut sich nichts beim updaten, stundenlang, ohne Fehlermeldung.

Schuld daran kann der Eintrag in der Zeile SOCKS sein, wenn der Proxy das nämlich nicht unterstützt und Host und Port eingetragen sind versucht er das zu benutzen... auch endlos.

So sollte es dann funktionieren:




Dienstag, 1. November 2011

Selenium IDE - Select

Selenium IDE 1.3.0
selenium-java 2.11.0


Eine praktische Option der Selenium IDE ist daß man JUnit Tests aus einem aufgenommen Testfall generieren kann. Leider funktioniert das mit Drop Down Listen nicht so einfach, generiert man bekommt man für diese Fälle im JUnit Test folgendes:

// ERROR: Caught exception [ERROR: Unsupported command [select]]

Liest man nach gibt es die Klasse Select, mit der man das händisch nachtragen kann, allerdings befand sich diese bei mir nicht im Klassenpfad, Problem war das ich nur den HtmlUnit Driver inkludiert hatte, das support Package ist dort nicht inkludiert.

Gibt man Maven die Anweisung das selenium-java Projekt zu inkludieren findet er auch die Select Klasse.

        
            org.seleniumhq.selenium
            selenium-java
            2.11.0
            test
        

Nun kann man die Select Klasse supereinfach zum Auswählen der entsprechenden Option verwenden:

Select select = new Select(driver.findElement(By.id("aktEntry.risiko.value")));
select.selectByVisibleText("American Football");


Freitag, 14. Oktober 2011

Ubuntu 11.10 Login Problem

Nach dem Upgrade von 11.4 auf 11.10 war es plötzlich nicht mehr möglich mich mit meinen Account anzumelden, er erkannte zwar das Passwort als richtig an, leitet mich aber sofort wieder auf den Login Screen um. Als Gast oder root gab es das Problem nicht.

Lösung war mich als root anzumelden und in meinem Homeverzeichnis die Datei .Xauthority zu löschen, danach war das Anmelden mit meinem Account plötzlich kein Problem mehr.

Freitag, 15. Juli 2011

maven-resources-plugin über pluginManagement verteilen

Das pluginManagement über parents zu handlen ist eine tolle Sache, man trägt dort gewünschte die Konfiguration ein und in den Kindprojekten gibt man einfach nur das Plugin an und es zieht dort.
Hat bis jetzt gut funktioniert.
Nun habe ich das mit dem maven-resources-plugin versucht und leider zog das Teil in allen Projekten die diesen parent hatten, egal ob es nun im pom eingetragen war oder nicht. Es blieb nichts anderes übrig als die Config im parent zu löschen und in jedem Projekt einzeln hinzuzufügen.

Erkärt habe ich es mir so: Da das maven-resources-plugin vom ganz normalen Lifecyle verwendet wird, ist es irgendwie in jedem pom implizit vorhanden und meine Config im parent zieht somit in jedem Projekt.

Eine andere Lösung als das Plugin in jedem Projekt einzeln zu konfigurieren ist noch nicht gekommen, aber vielleicht weiß ja ein geneigter Leser mehr.

Links:
Mavenseite über das resources Plugin

Samstag, 11. Juni 2011

Network Manager unterbricht ständig die wlan0 Verbindung

Ubuntu 11.04
network-manager-gnome 0.8.4
wicd 1.7.0

Seit Tagen bricht ständig die wlan0 Verbinung ab, stabilisiert sich wieder, bricht wieder ab. Recherchen im Netz brachten leider nicht den gewünschten Erfolg.
Als Grund stellte sich schlußendlich heraus das auch noch wicd installiert war, nach der Deinstallation war das Problem Vergangenheit.

Ein Auszug aus syslog falls jemand ein ähnliches Problem hat:

Jun 11 15:45:11 lenovo wpa_supplicant[1118]: Associated with xx:xx:xx:xx:xx:xx
Jun 11 15:45:11 lenovo NetworkManager[1008]: (wlan0): supplicant connection state: associating -> associated
Jun 11 15:45:12 lenovo NetworkManager[1008]: (wlan0): supplicant connection state: associated -> 4-way handshake
Jun 11 15:45:12 lenovo wpa_supplicant[1118]: WPA: Invalid EAPOL-Key MIC when using TPTK - ignoring TPTK
Jun 11 15:45:12 lenovo wpa_supplicant[1118]: WPA: Could not verify EAPOL-Key MIC - dropping packet
Jun 11 15:45:22 lenovo wpa_supplicant[1118]: Authentication with xx:xx:xx:xx:xx:xx timed out.
Jun 11 15:45:22 lenovo kernel: [ 378.768258] wlan0: deauthenticating from xx:xx:xx:xx:xx:xx by local choice (reason=3)
Jun 11 15:45:22 lenovo NetworkManager[1008]: (wlan0): supplicant connection state: 4-way handshake -> disconnected
Jun 11 15:45:22 lenovo NetworkManager[1008]: (wlan0): supplicant connection state: disconnected -> scanning
Jun 11 15:45:22 lenovo kernel: [ 378.880141] cfg80211: All devices are disconnected, going to restore regulatory settings


Dienstag, 24. Mai 2011

Verstecktes Menü in Sony Ericsson Mobiltelefonen

Telefon: Sony Ericsson W610i

Mit einer Tastenkombination kann man auf den Sony Ericsson Mobiltelefonen ein verstecktes Menü öffen:

> * < < * < *

> bzw. < stehen für die Richtung, die man die Wippe drückt,.

Dort kann man z.B. Modell und Softwareinfos abfragen, die SIM Sperren und Konfiguration betrachten und einstellen ob über USB Verbindung geladen werden darf.

Links:
Forum Eintrag zu diesem Thema

Freitag, 20. Mai 2011

Wicd durch Network Manager ersetzen um Huawei E182E zum Laufen zu bringen

Ubuntu 11.4
Huawei Mobile Broadband E182E

Vor einiger Zeit habe ich den Network Manager duch Wicd ersetzt, siehe Post.
Nun wollte ich den UMTS Stick zum Laufen bringen, da spielte Wicd nicht so ganz mit. Also Network Manager installiert, Wicd deinstalliert und Voila, fügt man über Verbindung bearbeiten eine neue "Mobiles Breitband" hinzu stellt er sich praktisch alles selber richtig ein und man ist nach ein paar Sekunden im Netz. So sollen Sachen funktionieren.

Alignment bei SSD fixen

Windows 7
Casper 6.0.2100
AS SSD Benchmark 1.6.4237

Wenn man Windows 7 auf einer SSD installiert sollte es im Normalfall kein Problem geben, spielt man aber Windows 7 durch eine Kopie von einer HD auf kann das Alignment kaputt sein. Feststellen kann man das mit dem Tool AS SSD Benchmark, nach dem Start ist im linken oberen Bereich eine Zahl und der Zusatz "bad" zu sehen wenn das Alignment falsch ist.

Hier das Ergebnis von AS SSD Benchmark bei einer SSD mit falschen Alignment vor der Reperatur:



Die meisten Anleitungen das auszubessern bewirken das man neu aufsetzen muß oder man Passwörter braucht, die man am Firmenrechner nicht immer zur Verfügung hat.

Hat man zufällig eine SSD der selben Größe zur Verfügung kann man mit dem Programm Casper auch in der 30 Tage Trail Version das Alignment fixen.

Dazu öffnet man Casper und geht zuerst auf "Explore":



Danach wählt man über Tools -> Options bei Partition Alignment den Punkt "Optimized" aus:



Dann kopiert man mit Rechtsklick auf die entsprechende Platte die gesamte Platte um:



Das dauert seine Zeit (für 128 GB brauchte ich 1 Stunde 20 Minuten). Danach bootet man von der eben bespielten Platte und kopiert sie wieder mit Caspar auf die ursprüngliche Platte drauf (Dauer ca. 20 Minuten).

Der anschließende Test mit AS SSD Benchmark ergibt:


Der Unterschied ist ziemlich eklatant.

Links:
AS SSD Benchmark Download von Heise
Download Site für die Casper Trail Version
Interessanter Artikel von Media Addicted zu diesem Thema

Samstag, 14. Mai 2011

SQLite Datenbank aus dem Eclipse Android Emulator ziehen und betrachten

Firefox 4.0.1
SQLite Manager 0.7.2
Eclipse 3.6.2
Android 2.3.1

Wenn man sich eine SQLite Datenbank aus dem Eclipse Emulator ziehen will folgt man einfach folgenden Schritten:

Man öffnet die DDMS Ansicht in Eclipse mit "Windows -> Open Perspective" und wählt DDMS:


Danach sucht man sich im Dateisystem seine Datenbank und exportiert diese:


Um diese Datei zu öffnen verwende ich das Firefox Add-On SQLite Manager:


Voila, schon kann man die Datenbank ansehen, manipulieren und über das DDMS sogar zurückspielen.


Links:
Designerandroid Beitrag

Dienstag, 3. Mai 2011

Fiddler als JMeter Proxy

Apache JMeter 2.4
Fiddler 2.3.3.5

Will man ein jmx-File ausführen und den Datenstrom noch über Fiddler leiten muß man JMeter mit einem Proxy starten.

Möglich ist das über JMeter Startparameter:

jmeter –H 127.0.0.1 -P 8888

Links:
Blog von Praveen Rajappan

Montag, 18. April 2011

Länderbeschränkungen mit Tor umgehen

Ubuntu 10.10
Firefox 4.0
Vidalia 0.2.12
Tor 0.2.1.30


Wie man Tor einrichtet habe ich in diesem Post beschrieben, zusammen mit dem Torbutton kann man (maybe mit noch weiteren Add-ons wie NoScript) durchs Netz cruisen ohne überall Spuren zu hinterlassen.

Nun haben manche Websites Länderbeschränkungen eingeführt, diese zu Umgehen ist ansich aber nicht schwierig.



Allerdings sollte man sich vorher erkundigen ob man damit nicht irgendwelchen Regelungen zuwiderhandelt, ich werde hier nur beschreiben wie es technisch möglich wäre und natürlich niemanden aufrufen, die von den Gesetzgebern in Ihrer unendlichen Weisheit beschlossenen Regeln zu umgehen.

Im Prinzip muß man sich mit Tor nur die Exit Node aussuchen können, denn diese wird ja dem Webserver als Aufruf-Ursprung übermittelt. Dazu sucht man sich potentielle Exitnodes aus dem gewünschen Land, in meinem Beispiel will ich amerikanische finden. Dazu öffnet man Vidalia und klickt den Button "Netzwerk betrachten".



Dort sucht man sich in der linken Spalte das richtige Land und mit einem Rechtsklick kriegt man den Fingerabdruck:

Dann fügt man diese Fingerprints im Configfile von Vidala ein, finden kann man es ebenfalls über das Vidalia Control Panel, zu zwar unter "Einstellungen/Fortgechritten/Edit current torrc":



Dort fügt man die Fingerprints an der richtigen Stelle ein, nämlich nach dem Tag ExitNodes, außerdem setzt man StrictExitNodes auf 1. Sollten die Parameter nicht vorhanden sein, legt man sie einfach an.





Im großen und Ganzen wars daß, Tor neu starten und man ist unter dem Land unterwegs, daß man sich ausgesucht hat. Was noch Probleme aufwarf, war daß der TorButton noch einige andere Infos auswechselt, unterdrückt, versteckt... was an sich eine tolle Sache ist, aber wenn man mit einem Linux 64 Bit System Flashvideos sehen will muß man da zu einem gewissen Teil die richtigen Infos über das System mitschicken, sonst läuft da nix.
Die Lösung dazu ist einfach, man schaltet den TorButton nicht ein und trägt den Torserver als normalen Proxy ein:



Links:
Tor Projekt Homepage
Vidalia

Sonntag, 10. April 2011

Heapsort in Java

Hier eine Implementierung von Heapsort in Java:

package at.ande.sorting.heapsort;

import java.util.ArrayList;

public class HeapSort {
 
 ArrayList list;
 int length;
 
 public ArrayList start(ArrayList arraylist){
  list = arraylist;
  length = list.size();
  createHeap();
  while(length > 1){
   length--;
   change(0, length);
   downheap(0);
  }
  return list;
 }
 
 public void createHeap(){
  for (int i = length / 2 - 1; i >= 0; i--){
   downheap(i);
  }
 }
 
 public void downheap(int i){
  int j = 2 * i + 1;
  while (j < length){
   if(j + 1 < length && list.get(j + 1) > list.get(j)){
    j++;
   }
   if(list.get(i) > list.get(j)){
    break;
   }
   change(i, j);
   i = j;
   j = 2 * i + 1;
  }
 }
 
 public void change(int i, int j){
  int temp = list.get(i);
  list.set(i, list.get(j));
  list.set(j, temp);
 }
}



Im Vergleich zu den auch in diesem Blog implementieren Sortieralgorithmen schneidet Heapsort ganz gut ab:

List Area: 0 - 999
List Numbers: 100000
Unsorted List:
- Iterative Quicksort: 123 ms
- Bubblesort: 45787 ms
- Gnomesort: 75418 ms
- Heapsort: 103 ms
Sorted List:
- Iterative Quicksort: 1518 ms
- Bubblesort: 5 ms
- Gnomesort: 8 ms
- Heapsort: 49 ms

Links:
Wikipediaeintrag über Heapsort
Ausführlicher Artikel der Uni Flensburg über Heapsort

Gnomesort in Java

Hier eine Implementierung von Gnomesort:

package at.ande.sorting.gnomesort;

import java.util.ArrayList;

public class GnomeSort {
 
 ArrayList list;

 public ArrayList start(ArrayList arraylist) {
  list = arraylist;
  sort();
  return list;
 }
 
 public void sort(){
  int right = 1;
  int left = 0;
  while (right != list.size()){
   if (list.get(left) <= list.get(right)){
    right = right + 1;
    left = left + 1;
   } else {
    int temp = list.get(left);
    list.set(left, list.get(right));
    list.set(right, temp);
    if(left != 0){
     left = left -1;
     right = right - 1;
    }
   }
  }
 }
}


Das Laufzeitverhalten ist nicht gerade überzeugend:

List Area: 0 - 999
List Numbers: 100000
Unsorted List:
-Iterative Quicksort: 135 ms
-Bubblesort: 43729 ms
-GnomeSort: 70638 ms
Sorted List:
-Iterative Quicksort: 1767 ms
-Bubblesort: 3 ms
-GnomeSort: 12 ms

Links:
Wikiartikel zu Gnomesort

Iteratives Quicksort in Java

Nachdem man bei der rekursiven Quicksort sehr schnell an Speichergrenzen stößt habe ich es mal iterativ implementiert.
Der Vergleich zu meiner Implementierung von Bobblesort zeigt bei einer Liste von 100000 Einträgen mit 1000 verschiedenen Werten einen beträchlichen Geschwindigkeitsvorsprung:
- Bubblesort ca. 40000 ms.
- Quicksort ca. 120 ms.
Übergibt man jedoch beiden eine schon sortierte Liste derselben Größe kehrt sich das um:
- Bubblesort ca. 12 ms.
- Quicksort ca. 2000 ms.

package at.ande.sorting.quicksort;

import java.util.ArrayList;
import java.util.Stack;

import at.ande.sorting.utils.SortingUtils;

public class QuickSort2 {

 ArrayList list;

 public ArrayList quickSort2(ArrayList arraylist) {
  list = arraylist;
  sort(0, arraylist.size() - 1);
  return list;
 }

 public void sort(int left, int right) {
  Stack stack = new Stack();
  while (true) {
   if (left < right) {
    int pivot = list.get(SortingUtils.randomOfTwo(left, right));
    int i = left - 1;
    int j = right + 1;

    while (true) {
     do {
      i = i + 1;
     } while (list.get(i) < pivot);

     do {
      j = j - 1;
     } while (list.get(j) > pivot);

     if (i >= j) {
      break;
     }
     int temp = list.get(i);
     list.set(i, list.get(j));
     list.set(j, temp);
    }
    stack.push(right);
    right = left > (i - 1) ? left : (i - 1);
   } else {
    if (stack.size() == 0) {
     break;
    }
    left = right + 1;
    right = stack.pop();
   }
  }
 }
}



Links:
Wikipediaeintrag Quicksort
Ausführliche Seite über Quicksort

Samstag, 9. April 2011

Quicksort in Java

Hier eine erste Implementierung von Quicksort, allerdings hat diese den Nachteil das ein StackOverflowError rasch erreicht wird:

package at.ande.sorting.quicksort;

import java.util.ArrayList;

public class QuickSort {
 
 ArrayList list;
 
 public ArrayList quickSort(ArrayList arraylist){
  list = arraylist;
  sort(0, arraylist.size() - 1);
  return list;
 }
 
 public void sort(int left, int right){
  if (left < right){
   int divisor = divide(left, right);
   sort (left, divisor - 1);
   sort (divisor + 1, right);
  }
  
 }
 
 public int divide(int left, int right){
  int i = left;
  int j = right -1;
  int pivot = list.get(right);
  
  do{
   while (list.get(i) <= pivot && i < right){
    i = i + 1;
   }
   while (list.get(j) >= pivot && j > left){
    j = j - 1;
   }
   if( i < j){
    int temp = list.get(i);
    list.set(i, list.get(j));
    list.set(j, temp);
   }
   
  } while (i < j );
  
  if(list.get(i) > pivot){
   int temp = list.get(i);
   list.set(i, list.get(right));
   list.set(right, temp);
  }
  return i;
 }
}


Ein Screenshot der Console des bei größeren Listen schnell auftretenden Fehlers:



Implementiert man Quicksort iterativ anstatt rekursiv funkt es auch mit großen Mengen: Iterative Implementierung von Quicksort
Quicksort von ungarischen Folkloretänzern getanzt

Links:
Ausführliche Seite über Quicksort

Bubblesort in Java

In nächster Zeit möchte ich als Fingerübung verschiedene Sortieralgorithmen in Java implementieren und dann verschiedene Messungen durchführen, begonnen habe ich mal mit Bubblesort, die ArrayList ist mit Integer befüllt, die Generics mußte ich rausnehmen da die Codedarstellung sonst nicht funzt.

package at.ande.sorting.bubblesort;

import java.util.ArrayList;

public class BubbleSort {

 public ArrayList sort(ArrayList list) {
  int listSize = list.size();
  boolean changed;
  do {
   changed = false;
   for (int i = 0; i < listSize - 1; i++) {
    Integer first = list.get(i);
    Integer second = list.get(i + 1);
    if (first > second) {
     list.set(i, second);
     list.set(i + 1, first);
     changed = true;
    }
   }
   listSize = listSize - 1;
  } while (changed && listSize > 1);
  
  return list;
 }
}


Links: Ausführliche Seite über Bubblesort
Bubblesort von ungarischen Folkloretänzern getanzt

Freitag, 8. April 2011

Facebook Plugin für Blogger

Auf dieser Seite kann man sich html generieren lassen, das dann einfach in den in die Vorlage einfügt:



Links:
Blogeintrag Facebook Plugin

Nachtrag 24.5.2011: Wie sich nun herausstellt spioniert Facebook mit dem Likebutton die User aus, ist also auf eine Seite ein "Like It" Button und man gleichzeitig in Facebook eingeloggt schneidet Facebook das mit, sprich Facebook weiß über deinen Account welche Seiten du besuchst. Dafür brauchst du den Button nicht benutzen, technisch kriegt es Facebook auch mit wenn der Button nur vorhanden ist. Aus diesem Grund hab ich den Button wieder aus dem Blog entfernt, man will ja seine Leser nicht an Facebook ausliefern.

Links:
Chipartikel zu diesem Thema

Sozialversicherungsnummer überprüfen

Eine österreichische Sozialversicherungsnummer auf Gültigkeit zu überprüfen ist einfach, man multipliziert jede der 10 Stellen mit einer Ziffer, nimmt das ganze Modulo 11 und vergleicht die vierte Zahl der Nummer damit, hier mal ein Javacodeschnipsel:

 public static boolean checkSozialversicherungsnummer(String nr) {
  int checksum = 0;

  if (nr.length() != 10)
   return false;

  try {
   checksum += Character.getNumericValue(nr.charAt(0)) * 3;
   checksum += Character.getNumericValue(nr.charAt(1)) * 7;
   checksum += Character.getNumericValue(nr.charAt(2)) * 9;
   checksum += Character.getNumericValue(nr.charAt(4)) * 5;
   checksum += Character.getNumericValue(nr.charAt(5)) * 8;
   checksum += Character.getNumericValue(nr.charAt(6)) * 4;
   checksum += Character.getNumericValue(nr.charAt(7)) * 2;
   checksum += Character.getNumericValue(nr.charAt(8)) * 1;
   checksum += Character.getNumericValue(nr.charAt(9)) * 6;

   checksum = checksum % 11;

   return (Character.getNumericValue(nr.charAt(3)) == checksum);

  } catch (NumberFormatException ex) {
   return false;
  }
 }



Montag, 21. März 2011

jQuery Datepicker: buttonImage ausrichten

JQuery-UI 1.8.2

In meinem letzten Beitrag wollte ich das Popup des Datepickers verschieben, nun will ich den Button, mit dem der Datepicker aufgerufen wird etwas anders positionieren.

Vorher noch die Methode, mit der man den Datepicker an ein Inputfeld hängt:

/**
 * Erzeugt einen Kalenderbutton in deutscher Sprache, wenn das Feld nicht disabled ist.
 *
 * @param fieldId: Id des Tags als String
 * @param addToTop: px value to add to the input field.top
 */
function addDatepicker(fieldId, addToTop){
    var $field = $( '#' + fieldId );
 if( $field.length > 0 && $field[0].disabled != true && $field[0].readonly != true && $field.hasClass("textoutput") != true){
     $field.datepicker({showOn: 'button',
       buttonImage: 'img/calendar_icon.gif',
       buttonImageOnly: true,
       buttonText: 'Kalender',
       changeMonth: true,
       yearRange: 'c-20:c+50',
       changeYear: true,
       beforeShow: function(fieldId) {
           var x = 100; //add offset 
           field = $(fieldId);
           left = field.position().left + x;
           /* top - 145 works for above the input */
           setTimeout(function(){
            if(addToTop != undefined || addToTop != null){
                var top = field.position().top + addToTop;
                $('#ui-datepicker-div').css({'top': top + 'px', 'left': left + 'px'});
            } else {
                $('#ui-datepicker-div').css({'left': left + 'px'});
            }
           },1);     
       }
     } );
    }
}


Dazu benutze ich CSS, in diesem ganz einfachen Fall will ich den Button einfach etwas runter setzen und hänge mich dazu an den ui-datepicker-trigger.

.ui-datepicker-trigger {
                               margin-bottom: -3px;
}


Links:
Blogbeitrag mit Lösung

Mittwoch, 9. März 2011

jQuery DatePicker: Popup ausrichten

JQuery-UI 1.8.2

Der Datepicker ist ein unkompliziertes Datumsauswahltool, positioniert man allerdings das aufrufende Element zu weit rechts kann es einem passieren das das Popup aus dem Fenster rutscht. Abhilfe schafft dieses Codeschnippsel:

function addDatepicker(fieldId ){
    var $field = $( '#' + fieldId );
 if( $field.length > 0 && $field[0].disabled != true && $field[0].readonly != true && $field.hasClass("textoutput") != true){
     $field.datepicker({showOn: 'button',
       buttonImage: 'img/calendar_icon.gif',
       buttonImageOnly: true,
       buttonText: 'Kalender',
       changeMonth: true,
       changeYear: true,
       beforeShow: function(fieldId) {
           var x = 100; //add offset 
           field = $(fieldId);
           left = field.position().left + x;
           setTimeout(function(){
               $('#ui-datepicker-div').css({'left': left + 'px'});      
           },1);                    
       }
     } );
    }
}

Der Event beforeShow setzt hier das Popup etwas nach links, damit es ganz sichtbar ist, die Methode setTimeout brauchen wir, da es anders irgendwie nicht so gut klappt.

Links:
Datepicker Dokumentation
Stackoverflow Eintrag mit der Lösung des Problems
Datepicker Demos

Sonntag, 6. März 2011

ListView in Android: TextView und EditText in einer Zeile

Android 2.3.1 Wenn mann aus einem xml-File eine längere Liste von Strings zu Controls auf der Oberfläche verarbeinen will, ist ListView ein geeignetes Mittel, soll nur ein Control pro Zeile vorhanden sein ist der Aufwand wie hier beschrieben minimal.

Sollen mehrere Controls pro Zeile vorhanden sein wird es etwas mehr Aufwand, aus verschiedenen Quellen im Netz hab ich mir soetwas zusammengebaut, ich stelle es nun hier vor:

Die Activity:
public class InputPropertiesActivity extends DefaultListActivity {
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.inputproperties);

  final List rowHolders = new ArrayList();
  String[] rowNames = getResources().getStringArray(R.array.properties);
  for (int i = 0; i < rowNames.length; i++) {
   RowHolder talentholder = new RowHolder(rowNames[i], "");
   rowHolders.add(talentholder);
  }
  setListAdapter(new MyListAdapter(this, R.layout.listrow, rowHolders));
 }
}


Bei der DefaultListActivity handelt es sich nur um eine Klasse die ListActivity extended und ein paar Methoden beinhalted, die ich in allen ListActivities zur Verfügung haben will. Im Prinzip lese ich hier nur mein xml aus und stopfe die Werte zusammen mit einem Leerstring in ein RowHolder Array, das ich meinen MyListAdapter übergebe, den ich dann als ListAdapter festlege.

Der RowHolder:
public class RowHolder {
 String rowName;
 String rowValue;

 public RowHolder(String talentName, String talentValue) {
  this.rowName = talentName;
  this.rowValue = talentValue;
 }

 public String getRowName() {
  return rowName;
 }

 public void setRowName(String rowName) {
  this.rowName = rowName;
 }

 public String getRowValue() {
  return rowValue;
 }

 public void setRowValue(String rowValue) {
  this.rowValue = rowValue;
 }
}


Der ListAdapter:
public class MyListAdapter extends BaseAdapter {

 private final List rowholders;
 private final int rowResID;
 private final LayoutInflater layoutInflater;

 public MyListAdapter(final Context context, final int rowResID, final List rowHolder) {
  this.rowResID = rowResID;
  this.rowholders = rowHolder;

  layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 }

 public int getCount() {
  return rowholders.size();
 }

 public Object getItem(int position) {
  return rowholders.get(position);
 }

 public long getItemId(int position) {
  return position;
 }

 public View getView(final int position, View convertView, ViewGroup parent) {

  final ViewHolder viewHolder;
  final RowHolder rowholder;

  if (convertView == null) {
   viewHolder = new ViewHolder();
   rowholder = rowholders.get(position);
   convertView = layoutInflater.inflate(rowResID, null);
   viewHolder.rowName = (TextView) convertView.findViewById(R.id.rowname);
   viewHolder.rowName.setText(rowholder.getRowValue());


   viewHolder.rowValue = (EditText) convertView.findViewById(R.id.rowvalue);
   viewHolder.rowValue.addTextChangedListener(new TextWatcher() {
    public void afterTextChanged(Editable edit) {
     rowholders.get(viewHolder.ref).setRowValue(edit.toString());
    }

    public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
    }

    public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
    }
   });
   convertView.setTag(viewHolder);
  } else {
   viewHolder = (ViewHolder) convertView.getTag();
  }

  viewHolder.ref = position;
  viewHolder.rowName.setText(rowholders.get(position).getRowName());
  viewHolder.rowValue.setText(rowholders.get(position).getRowValue());
  return convertView;
 }

 class ViewHolder {
  TextView rowName;
  EditText rowValue;
  int ref;
 }
}


Der Aufwand, der hier betrieben wird, ist schon etwas mehr als wenn nur ein Element pro Zeile vorhanden wäre. Allerdings läßt sich obiges wiederverwenden, sind also viele Ansichten ähnlich, müssen aber aus verschiedenen xml´s befüllt werden, nutzt man es einfach nochmal.

Dazu das vereinfachte inputproperties.xml aus dem layout Folder (Die Darstellung der Groß- und Kleinschreibung haut leider so gar nicht hin, muß beim kopieren entsprechend geändert werden):


 
  
  
 



Und das listrow.xml aus dem layout Folder:


 
  
  
 



Wie aber bekommt man die Werte nun wieder raus, wenn ich sie zB. persistieren will? Hierzu habe ich mich wieder des ListAdapters bedient:

Methode saveProperties() der Klasse InputPropertiesActivity:
public void saveProperiets() {

  for (int i = 0; i < this.getListAdapter().getCount(); i++) {
   String rowName = ((RowHolder) this.getListAdapter().getItem(i)).getRowName();
   String rowValue = ((RowHolder) this.getListAdapter().getItem(i)).getRowValue();

   Log.d("NAME - VALUE:", rowName + " " + rowValue);
   if (rowValue == null || rowValue.equalsIgnoreCase("")) {
    showDialog(DIALOG_PROPERTY_MISSING_ID);
   } else {
    inputTalents();
   }
  }
 }


Das Ergebnis (inklusive einiger Modifikationen, mit obigen Code wurde nur die Liste erzeugt) sieht dann so aus, wobei die Anzahl der Elemente beliebig ist:


Links:
Problemstellung zu dieser Konstellation

Freitag, 25. Februar 2011

Android Source für Eclipse

Eclipse 3.6.1
Android 2.3.1

In einem früheren Post habe ich schon erklärt wie man den Source für Android in Eclipse nutzbar macht, habe nun aber kein .zip für 2.3.1 gefunden. Über git wärs zwar möglich sich das selber zusammen zu basteln, aber bequem wie man ist hätte man es gerne einfacher.

Und tatsächlich gibt es ein Eclipse Plugin, das einem dem Source anhängt, mit dem Eclipse Update Manager lädt man mittels dieser Adresse:
http://adt-addons.googlecode.com/svn/trunk/source/com.android.ide.eclipse.source.update
das Plugin, nach einem Neustart kann man schon durch den Source cruisen... .

Links:
Blogeintrag zu diesem Thema

Montag, 21. Februar 2011

Absturz des Flashplugins im Firefox unter 64 Bit Ubuntu

Firefox 3.6.13
libflashplayer.so 10.0.2
Ubuntu 10.10 64 Bit

Wenn einem nach jeden Youtub Video der Firefox abkratzt kann das nervig werden. Gelegen ist es am libflashplayer Plugin im Firefox. Das wird ja für 64 Bit etwas stiefmütterlich behandelt, man darf es sich regelmäßig selbst ziehen um halbwegs auf den neuesten Stand zu bleiben.

Lösung war: Version 10.3d162 von hier ziehen, entpacken und mit dem vorhandenen im Verzeichnis ~/.mozilla/plugins austauschen, schon läuft das Teil wieder (ne zeitlang) rund.

Sonntag, 23. Januar 2011

Onlinekonvertierung pdf, xps usw.

Konvertierungstools gibts massenhaft, aber wenn man selten und dann schnell etwas umgewandelt haben will bieten sich Online Tools an.

Für xps in pdf habe ich gute Erfahrungen mit dieser Seite gemacht, außer dem zu konvertierendem Dokument werden keine Daten gefordert:

http://www.xps2pdf.org/


Ein weiteres nützliches Tool stellt die nächste Seite dar, hier lassen sich haufenweise Formate in andere umwandeln, die vollständige Liste würde aber den Rahmen sprengen, verlangt wird eine gültige Mailadresse, an die der Link gesendet wird, mit dem man sich das konvertierte File downloaden kann:

http://www5.zamzar.com/

Dienstag, 4. Januar 2011

In Fedora 14 Nautilus dem Panel hinzufügen

OS: Fedorea 14.x86_64

Um mit Fedora 14 Nautilus wieder in das Panel zu bekommen installiert man sich mit Rootrechten alacarte:
yum install alacarte

Danach findet man unter System -> Preferences den Eintrag "Main Menu". In diesem wählt man unter "Other" den "File Manager".
Nun findet man diesen im normalen Menü und kann ihn mit Rechtsklick "Add to Panel" zum Panel hinzufügen.

Links:
Foreneintrag zu diesem Thema