Affichage des articles dont le libellé est Java. Afficher tous les articles
Affichage des articles dont le libellé est Java. Afficher tous les articles

vendredi 9 août 2013

java.lang.IndexOutOfBoundsException: "Invalid index" lors de l'appel à la méthode JFileChooser.setCurrentDirectory( dir )

Une exception assez inattendue peut survenir lors de l'appel à la méthode setCurrentDirectory() sur une objet de type JFileChooser.

Exception in thread "xxx" java.lang.IndexOutOfBoundsException: Invalid index
 at javax.swing.DefaultRowSorter.convertRowIndexToModel(DefaultRowSorter.java:514)
 at sun.swing.FilePane$SortableListModel.getElementAt(FilePane.java:658)
 at javax.swing.plaf.basic.BasicListUI.updateLayoutState(BasicListUI.java:1360)
 at javax.swing.plaf.basic.BasicListUI.maybeUpdateLayoutState(BasicListUI.java:1311)
 at javax.swing.plaf.basic.BasicListUI.getCellBounds(BasicListUI.java:952)
 at javax.swing.JList.getCellBounds(JList.java:1633)
 at javax.swing.JList.ensureIndexIsVisible(JList.java:1149)
 at sun.swing.FilePane.ensureIndexIsVisible(FilePane.java:1694)
 at sun.swing.FilePane.doDirectoryChanged(FilePane.java:1617)
 at sun.swing.FilePane.propertyChange(FilePane.java:1667)
 at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335)
 at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:327)
 at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:263)
 at java.awt.Component.firePropertyChange(Component.java:8382)
 at javax.swing.JFileChooser.setCurrentDirectory(JFileChooser.java:581)
 at ...

A priori cela ressemble à un bug Swing, or il n'en est rien. Un article présent dans la base de bug de Sun, explique qu'il ne s'agit pas d'un bug, mais d'un problème de Thread.

Il est a noter que dans mon cas, qu'aucune erreur n'était visible tant que le code ne faisait pas appel à la méthode setCurrentDirectory().

Pour ceux qui sont pressés, je vous donne directement la recette de cuisine :
Il suffit de transformer le code qui initialise votre objet JFileChooser comme suit

Code initial :
JFileChooser jfc = ...
jfc.setFileSelectionMode( ... );
jfc.setCurrentDirectory( ... );
if( jfc.showOpenDialog( parent ) == JFileChooser.APPROVE_OPTION ){
 ...
 }

Code corrigé :
SwingUtilities.invokeLater( new Runnable() { @Override public void run() { JFileChooser jfc = ... jfc.setFileSelectionMode( ... ); jfc.setCurrentDirectory( ... ); if( jfc.showOpenDialog( parent ) == JFileChooser.APPROVE_OPTION ){ ... } } });

Comme l'explique, fort mal, l'article de Sun, l’initialisation doit se faire depuis l'"event dispatch thread", en français, depuis le thread de gestion des événements Swing.

Dans les programmes Swing, le thread d'initialisations n'ont pas pas grand chose à faire. Sa tâche principal étant de créer un objet Runnable qui initialise l'interface graphique. Cette tâche est mise dans la pile des tâche awt/swing, c'est depuis cet environnement que doit être exécuté les traitements lié à l'interface graphique.

Une fois l'interface graphique est créé, le programme est principalement contrôlé par les événements GUI, chacun qui provoque l'exécution d'une tâche courte sur l'"event dispatch thread". Le code d'application peut planifier des tâches de suppléments sur l'"event dispatch thread" a condition qu'ils se terminent rapidement, afin de ne pas interférer avec le traitement des événements ou un thread de travail (pour les tâches longue à traiter).

lundi 19 novembre 2012

Spécification JavaBean des trucs étranges

JavaBeans est une notion familière à tout développeur Java. A priori, il s'agit d'une classe, avec certaines propriétés et pour chacune de ces propriétés les méthodes getter et setter associées. Rien de bien compliqué donc.
Cependant, il arrive que nous ayant des surprise, et bien que les getter et setter aient été générés on découvre une erreur. Pourquoi lors l'exécution de l'application, celle-ci ne trouve pas un getter ou un setter d'une des propriété du bean ?

Et là on se rend compte que les spécifications JavaBean sont expliquées dans un petit document PDF de plus de 100 pages. Inévitablement, certaines des règles sont un peu bizarres et autant dire que rare sont les personnes qui ont regardée cette documentation.

Concrètement
Le nom des propriétés commence par une lettre minuscule au début du nom de la propriété, les méthodes JavaBean correspondantes (getter / setter) commences par get et set puis vient ensuite la première lettre en majuscule nom de la propriété.

Dans la plupart des cas cette règle est correcte.

Mais il arrive que l'on à traiter des noms des attributs non standard que certain problèmes se présentent. C'est typiquement le cas si votre code provient d'une génération automatisée de votre code.
Prenons un exemple, une chaîne provenant du C risque de vous produire l'attribut sName. Là, vous générez les méthodes getSName() et setSName(String nom).

Avec cet exemple, les framework tels que Struts, Hibernate, iBatis ou JSF ne seront pas résoudre l'accès à l'attribut sName.
En effet, dans un tel cas le getter et setter doivent avoir la forme suivante: getsName() et setsName(String nom).

Les propriétés et les règles d'accès

Type de la
propriété
Nom de la
propriété
getter setter
Doublexcoordinate public Double getXcoordinate() public void setXcoordinate(Double value)
DoublexCoordinate public Double getxCoordinate() public void setxCoordinate(Double value)
DoubleXCoordinate public Double getXCoordinate() public void setXCoordinate(Double value)
DoubleXcoordinateNon autoriséNon autorisé
Booleanstudent public Boolean getStudent() public void setStudent(Boolean value)
booleanstudent public boolean getStudent()
public boolean isStudent()
public void setStudent(boolean value)
Toto[]toto public Toto[] getToto()
public Toto getToto(int index)
public void setToto(Toto[] newArray)
public void setToto(int index, Toto item)

La Javadoc.

On peut s'inspirer de java.beans.Introspector, une classe permettant de récupérer la liste des propriétés présente sur une classe.

Method getter = new PropertyDescriptor(propertyName, beanClass).getReadMethod();

Voir également:

mardi 13 novembre 2012

Astuce JAVA, XML et expressions régulières

L'analyse de petits flux XML inséré dans une base de donnée par exemple n'est pas rare, la mise en place d'un parseur XML classique pour ce genre de traitement peut s'avérer inadapté.

Prenons le cas où l'on chercher à retrouver un texte entre 2 balises.

Attention, ce code n'est pas censé remplacé un parseur XML, il ne supporte pas en particulier le fait qu'un élément contienne un élément ayant le même nom.

jeudi 14 juin 2012

Portage C/Java: isalnum()vs isLetterOrDigit()

Le Code JAVA équivalent au code C

/* code C */
 
if( isalnum( c ) ) {
  // ... true ...
  }
else {
  // ... false ...
  }

est

// Eg. C / isalnum() Unix in JAVA
 
if( Character.isLetterOrDigit( c ) && (c < 128) ) {
  // ... true ...
  }
else {
  // ... false ...
  }

la seconde clause est souvent omise dans les documentations et les applications.

vendredi 10 février 2012

Lint4j une extension sympa pour Eclipse

Lint4j une extension sympa pour Eclipse

Lint4j ("Lint for Java") est un analyseur statique de code Java, il prend également en charge le byte code, d'après la documentation, mais je n'ai pas encore essayé cette fonctionnalité.

Lint4j est un bon outil que tout développeur Java devrait utiliser au minimum une fois. Il met en effet des problèmes potentiel d'interblocage, des problèmes de threads (synchronisation) ou d'évolutivité. Lint4j prend également en charge la recherche de problèmes potentiels autour de la sérialisation.

Cette extension aide à la découverte et à leurs résolutions de problèmes potentiel durant la phase de développent, mais c'est également un bon outil pour améliorer son code et prendre quelques bons réflexes.

URL pour installer le plugin depuis Eclipse :

http://www.jutils.com/eclipse-update