Bloc-note 'Java'
Le 23 mars 2007, à 1:32 par Ulhume...

Bloc-Note Java

Gestion vidéo bas-niveau

Activation du mode "Full-screen"

Window window = new Window(frame);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getScreenDevices()[1];
GraphicsConfiguration gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
gd.setFullScreenWindow(window);
window.requestFocus();

Résumé des configurations écran disponibles

public void dumpConfiguration()
{
  GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
  for (int i = 0; i < ge.getScreenDevices().length; i++)
  {
    GraphicsDevice gd = ge.getScreenDevices()[i];
    logger.info("Screen " + i);
    logger.info("   - id: " + gd.getIDstring());
    logger.info("   - type: " + gd.getType());
    logger.info("   - accelerated Memory: " + gd.getAvailableAcceleratedMemory());
    logger.info("   - class: " + gd.getClass());
    logger.info("   - isDisplayChangeSupported: " + gd.isDisplayChangeSupported());
    logger.info("   - isFullScreenSupported: " + gd.isFullScreenSupported());
    for (int j = 0; j < gd.getDisplayModes().length; j++)
    {
      DisplayMode displayMode = gd.getDisplayModes()[j];
      logger.info("   - " + displayMode.getWidth() + "x" + displayMode.getHeight() + "x" + displayMode.getBitDepth() + " " + displayMode.getRefreshRate() + " Hz");
    }
    System.out.println(gd.getIDstring());
    for (int j = 0; j < gd.getConfigurations().length; j++)
    {
      GraphicsConfiguration configuration = gd.getConfigurations()[j];
    }
  }
}

Utilisation de java3D

public static class CustomCanvas3D extends Canvas3D
{
  public CustomCanvas3D(GraphicsConfiguration gcIn)
  {
    super(gcIn);
  }

  public void postRender()
  {
    J3DGraphics2D g = getGraphics2D();

  }

  public static void render(J3DGraphics2D g)
  {
    try
    {
      FileInputStream in = new FileInputStream("/storage/donnees/archives/photos/2005/Ladakh/pict2026.jpg");
      JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(in);
      BufferedImage photo = decoder.decodeAsBufferedImage();
      in.close();
      g.drawImage(photo, 0, 0, null);
    }
    catch (Exception e)
    {
      // TODO: handle exception
    }
    g.flush(true);
  }
}

public Test3D() throws ImageFormatException, IOException
{
  setLayout(new BorderLayout());

  GraphicsConfiguration config =

  SimpleUniverse.getPreferredConfiguration();

  Canvas3D canvas = new CustomCanvas3D(config);

  add("Center", canvas);


  SimpleUniverse universe = new SimpleUniverse(canvas);

  universe.getViewingPlatform().setNominalViewingTransform();

  setUndecorated(true);
  setResizable(false);
  setAlwaysOnTop(true);
  setVisible(true);
  setSize(640,480);
  setVisible(true);
  CustomCanvas3D.render(universe.getCanvas().getGraphics2D());
}

public static void main(String[] args) throws ImageFormatException, IOException
{

  new Test3D();

}

Un redimensionnement propre d'icônes

J'ai essayé des tonnes de méthode pour redimensionner une image type "png" d'un classique 128x128 à 16x16, et quelle que soit la méthode utilisé (draw direct, transformation, etc...), c'est l'enfer. J'ai toujours obtenu une sorte de "nearest" vilain.

La seule méthode que j'ai trouvé est la suivante :

public static BufferedImage scaledImage(BufferedImage image, int width, int height) {
    Image scaledImage = image.getScaledInstance(width, height, Image.SCALE_SMOOTH);
    BufferedImage scaledBuffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    Graphics2D graphics = scaledBuffer.createGraphics();
    graphics.drawImage(scaledImage, 0, 0, width, height, null);
    graphics.dispose();
    return scaledBuffer;
}

Envoi d'un post http avec cookied

PostMethod post = null;
    try
    {
      String nutName = xmlInvokation.getAttribut("nut");
      String methodName = xmlInvokation.getAttribut("method");
      String channel = xmlInvokation.getAttribut("channel", "nuts");
      String host = xmlInvokation.getAttribut("host", "localhost");
      int port = xmlInvokation.getAttributAsInteger("port", 8080);
      String url = "http://" + host + ":" + port + "/" + channel;

      NutContainer.logger.info("Running invokation : " + url +  "/"+nutName + "." + methodName);
      post = new PostMethod(url);

      String toString = xmlInvokation.toString().replace("&", "&amp;");

      if (LoggerUtilities.isDebug(NutContainer.logger))
        NutContainer.logger.debug(url + " : " + toString);

      RequestEntity entity = new StringRequestEntity(toString, "text/xml", "UTF-8");
      post.setRequestEntity(entity);
      HttpClient httpclient = new HttpClient();
      HttpState state = httpclient.getState();
      state.clearCookies();
      if (NutContainer.getInstance().getCookies() != null)
        state.addCookies(NutContainer.getInstance().getCookies());
      int result = httpclient.executeMethod(post);
      state = httpclient.getState();
      Cookie[] cookies = state.getCookies();
      if (cookies != null)
        NutContainer.getInstance().setCookies(cookies);
      // Display status code
      if (LoggerUtilities.isDebug(NutContainer.logger))
      {
        NutContainer.logger.debug("Response status code: " + result);
        NutContainer.logger.debug("Response body: ");
        NutContainer.logger.debug(post.getResponseBodyAsString());
      }
    }
    catch(Exception e)
    {
      LoggerUtilities.severe(NutContainer.logger, e);
    }
    finally
    {
      if (post != null)
        post.releaseConnection();
    }

Ping en java

try
{
  InetAddress address = InetAddress.getByName(getUrlMatcher(getUrl()).getHost());
  startSensoring();
  if (!address.isReachable((int) getTimeOut()))
    setAlert(new SensorAlert("Host not reachable"));
}
catch (UnknownHostException e)
{
  setAlert(new SensorAlert("Unknown host " + getUrl()));
}
catch (IOException e)
{
  throw new SensorException(e);
}

Création d'un buffer d'image volatile

protected void createBuffer(int width, int height)
  {
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsConfiguration gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
    if (volatileImage)
    {
      buffer = gc.createCompatibleVolatileImage(2, height);
      int valid = ((VolatileImage) buffer).validate(gc);
      if (valid == VolatileImage.IMAGE_INCOMPATIBLE)
      {
        buffer = null;
        LoggerUtilities.severe(logger, "Unable to create volatile image, switching to bufferedImage");
      }
      ((VolatileImage) buffer).setAccelerationPriority(1);
    }
    if (buffer == null)
      buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  }

Activation du pipe OpenGL

System.setProperty("sun.java2d.opengl", StringUtilities.firstUp(String.valueOf(configuration().isOpenGl())));

Spécification du dossier des JNI

-Djava.library.path=./native/

Vérifications d'usage : NPTL

NPTL est une fonction ajoutée au kernel récent pour optimiser la gestion des threads. Avant, un thread était un processus, comme une application lancée séparement ou plus exactement s'était un fork. l'arrivée de NPTL a permis de gérer les threads de manière plus efficace. Pour se donner une idée, l'ouverture de 100 000 threads prenait quelques 15 minutes sur un i86 contre, avec NPTL, 2 secondes sur la même machine. Dans la mesure où java utilise massivement les threads, l'arrivée de NPTL a booster les performances de près de 30% sous Linux. Il est donc important de vérifier s'ils sont activés sur la machine qui va héberger une application Java.

Avant de se casser la tête, vérifions que les NPTL sont présent tout court sur cette distribution :

getconf GNU_LIBPTHREAD_VERSION
# qui me répond :
#    NPTL 2.4

Parfait. La gestion des threads est conférée à la librairie libc. Hors il y a 3 libc différentes sur une distribution moderne. Une dans /lib, une dans /lib/tls et une encore dans /lib/i686.. Pour connaître ce que supporte une de ses librairies, l'astuce consiste à les rendre exécutables et de les lancer.. En tant que root évidement :

chmod +x /lib/libc-2.3.5.so
/lib/libc-2.3.5.so

Ici, j'obtiens (entre autre) la ligne suivante :

linuxthreads-0.10 by Xavier Leroy

Pas de NPTL donc.. On continue sur les autres, même manipulation donc pour /lib/tls/libc-2.3.5.so j'obtiens :

Native POSIX Threads Library by Ulrich Drepper et al

Parfait, la librairie à utiliser est donc celle de /lib/tls. Maintenant pour savoir dans quel ordre sont lynkées ses librairies :

ldconfig -p | grep "libc"
# Ce qui me donne :
#  libc.so.6 (libc6, hwcap: 0x8000000000000000, OS ABI: Linux 2.6.9) => /lib/tls/libc.so.6
#  libc.so.6 (libc6, hwcap: 0x8000000000000, OS ABI: Linux 2.4.1) => /lib/i686/libc.so.6
#  libc.so.6 (libc6, OS ABI: Linux 2.2.5) => /lib/libc.so.6

C'est positif, maintenant cherchons à savoir à quelle librairie fait appel java :

ldd /usr/java/jdk/jre/bin/java | grep libc
# cela donne :
#   libc.so.6 => /lib/tls/libc.so.6 (0xb7de5000)

Parfait, java utilise bien la bonne librairie. On peut passer à la suite Smiling

Librairies utiles

  • Conversion de dates en multi-threads

    L'objet SimpleDateFormat n'est pas threadsafe... Et le résulat est très étrange, cela peut donner une erreur du type java.lang.NumberFormatException: multiple points, et ce depuis le JDK1.4 jusqu'au 1.6. La solution, chynchroniser sur l'objet :

    synchronized (dateFormat) {
       return dateFormat.parse(value);
     }

    IllegalMonitorStateException

    Un grand classique... Imaginons que nous voulions attendre dans notre thread qu'un événement se produise ailleurs. Cela donne quelque chose du genre :

       class bidule {
       private String valeur = null;
       String ecrireValeur(String valeur) {
         this.valeur = valeur;
         this.notify();
       }
       String lireValeur() {
          this.wait();
          return valeur;
       }
    }

    Dans un thread on va donc avoir un maValeur = bidule.lireValeur() qui va bloquer jusqu'à ce qu'un autre thread fasse un bidule.ecrireValeur(...). Et au lancement, padaboum, on se prend un bon vieux IllegalMonitorStateException sur le wait. La solution est aussi simple à mettre en oeuvre qu'à comprendre. En effet, que se passerait-il avec ce code si plusieurs threads appelaient la méthode lireValeur ? Benoîtement on se dit "il sont tous en attente". Manque de pot, Java ne sait pas faire cela car le "Wait" est lié à un et un seul thread. Donc si le but recherché est est d'avoir plusieurs thread appelant, il faut passer par une autre solution. Maintenant si lireValeur est appelé par un seul thread, il faut que cette méthode soit déclarée dans ce sens. Il suffit donc d'ajouter un synchronized dans la déclaration de la méthode pour régler notre problème. En rajouter un dans écrireValeur ne ferait pas de mal non plus ceci dit.

    En somme, la régle, c'est que wait ne peut avoir lieu que dans un block synchronizé.

    Crash entre Swing et Xinerama

    Si au lancement de Swing vous obtenez une horreur du genre

    Locking assertion failure.  Backtrace:
    #0 /usr/lib/libxcb-xlib.so.0 [0xb7cca767]
    #1 /usr/lib/libxcb-xlib.so.0(xcb_xlib_unlock+0x31) [0xb7cca8b1]
    #2 /usr/lib/libX11.so.6(_XReply+0xfd) [0xab708a8d]
    #3 /opt/java/jre/lib/i386/xawt/libmawt.so [0xab81864e]
    #4 /opt/java/jre/lib/i386/xawt/libmawt.so [0xab7f6f97]
    #5 /opt/java/jre/lib/i386/xawt/libmawt.so [0xab7f7248]
    #6 /opt/java/jre/lib/i386/xawt/libmawt.so(Java_sun_awt_X11GraphicsEnvironment_initDisplay+0x2f) [0xab7f754f]
    #7 [0xb5c9366e]
    #8 [0xb5c8bedd]
    #9 [0xb5c8bedd]
    #10 [0xb5c89243]
    #11 /opt/java/jre/lib/i386/client/libjvm.so [0x620bc6d]
    #12 /opt/java/jre/lib/i386/client/libjvm.so [0x630a828]
    #13 /opt/java/jre/lib/i386/client/libjvm.so [0x620bb00]
    #14 /opt/java/jre/lib/i386/client/libjvm.so(JVM_DoPrivileged+0x34b) [0x62619bb]
    #15 /opt/java/jre/lib/i386/libjava.so(Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2+0x3d) [0xb7ca496d]
    #16 [0xb5c9366e]
    #17 [0xb5c8bd77]
    #18 [0xb5c89243]
    #19 /opt/java/jre/lib/i386/client/libjvm.so [0x620bc6d]
    Locking assertion failure.  Backtrace:
    #0 /usr/lib/libxcb-xlib.so.0 [0xb7cca767]
    #1 /usr/lib/libxcb-xlib.so.0(xcb_xlib_lock+0x2e) [0xb7cca81e]
    #2 /usr/lib/libX11.so.6 [0xab707e08]
    #3 /usr/lib/libX11.so.6(XGetVisualInfo+0x26) [0xab6feb76]
    #4 /opt/java/jre/lib/i386/xawt/libmawt.so [0xab7f6249]
    #5 /opt/java/jre/lib/i386/xawt/libmawt.so [0xab7f6495]
    #6 /opt/java/jre/lib/i386/xawt/libmawt.so [0xab7f72f9]
    #7 /opt/java/jre/lib/i386/xawt/libmawt.so(Java_sun_awt_X11GraphicsEnvironment_initDisplay+0x2f) [0xab7f754f]
    #8 [0xb5c9366e]
    #9 [0xb5c8bedd]
    #10 [0xb5c8bedd]
    #11 [0xb5c89243]
    #12 /opt/java/jre/lib/i386/client/libjvm.so [0x620bc6d]
    #13 /opt/java/jre/lib/i386/client/libjvm.so [0x630a828]
    #14 /opt/java/jre/lib/i386/client/libjvm.so [0x620bb00]
    #15 /opt/java/jre/lib/i386/client/libjvm.so(JVM_DoPrivileged+0x34b) [0x62619bb]
    #16 /opt/java/jre/lib/i386/libjava.so(Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2+0x3d) [0xb7ca496d]
    #17 [0xb5c9366e]
    #18 [0xb5c8bd77]
    #19 [0xb5c89243]

    Cela viendrait du fait qu'AWT ait été compilé en statique avec X11. La solution est un patch sauvage de Java :

    sed -i 's/XINERAMA/FAKEEXTN/g'  /usr/local/java/jdk1.6.0_04/jre/lib/i386/xawt/libmawt.so

    Look and feel Swing natif

    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception e) {
      Traces.severe(logger, e);
    }

    Commentaires

  • Répondre

    Le contenu de ce champ est gardé secret et ne sera pas montré publiquement.
    • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
    • To highlight piece of code, just surround them with <code type="language"> Your code &tl;/code>>. Language can be java,c++,bash,etc... Everything Geshi support.
    • Les lignes et les paragraphes vont à la ligne automatiquement.
    • Textual smileys will be replaced with graphical ones.
    • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.

    Plus d'informations sur les options de formatage

    Connexion utilisateur
    Les derniers bavardages...