MokaByte Numero  42  - Giugno 2000
  
Realizzare di applicazioni
Java indipendenti dalla
risoluzione del video
di 
Stefano Rossini
In questo articolo si spiegherà come è possibile ottenere programmi Java (applicazioni e Applet) indipendenti dalla risoluzione grafica del video della macchina sulla quale vengono interpretati

Può succedere che a parità di codice java compilato, cioè di bytecode (file di estensione .class), a secondo della macchina dove viene interpretato si ottiene visualizzazione diversa a parità di sisitema operativo e di JDK. Queste diversità possono dipendere semplicemente da una diversa configurazione della scheda video. Lo scopo di questo articolo è di ottenere una semplice programma  in grado di ottenere la medesima visualizzazione su due PC aventi risoluzione della scheda grafica diversa.

I problemi derivanti dalla risoluzione grafica del video
Quando si ottiene una diversa visualizzazione del medesimo programma Java su macchine diverse, si può essere indotti a pensare che il problema sia dovuti ai componenti peer del sistema, da una diversa versione della JVM o dal programma stesso.
A volte non è nessuno di questi motivi, semplicemente le due macchine hanno una risoluzione della scheda video diversa.
Sviluppiamo una semplicissima applicazione con lo scopo di visualizzare a tutto schermo un pannello BorderLayout con 5 bottoni.

Il codice è il seguente :

import java.awt.*;
import javax.swing.*;

public class myBadFrame extends JFrame {
  Container frameContainer;
  public static void main(String args[])
  {
   myBadFrame myFrame = new myBadFrame();
  }

  public myBadFrame()
  {
    super("myBadFrame");
    frameContainer = getContentPane();
    frameContainer.setLayout(new BorderLayout());
    frameContainer.add("North",new Button("North"));
    frameContainer.add("East",new Button("East"));
    frameContainer.add("Center",new Button("Center"));
    frameContainer.add("West",new Button("West"));
    frameContainer.add("South",new Button("South"));
    this.setSize(640,480);
      this.setVisible(true);
  }
}
 
 
 
 
 
 

Ottenuto il file .class, lo mandiamo in esecuzione su due PC Wndows NT4.0 con la stessa medesina versione del JDK 1.2 ottenendo il risultato rappresentato in figura 1.


Figura1

L’effetto non è quello voluto, ogni PC  visualizza in modo diverso a parità di S.O e di JDK.
Il problema è dovuto semplicemente ad una diversa risoluzione del video delle 2 macchine.
Ogni PC ha una propria scheda video e quindi differenti possibilità di risoluzione. Anche a parità di schede video, ogni utente ha le sue preferenze.
Per vedere come è settata la propria risoluzione in Windows basta andare in Pannello di Controllo, selezionare l'icona Display e portarsi in Settings, oppure schiacciando il tasto destro del mouse sul top panel.
Nel nostro caso, i 2 PC su cui veniva interpretato il bytecode del nostro programma avevamo le seguenti configurazioni di scheda video :
 



Figura 2

Il codice del nostro esempio sbaglia perchè pone il vincolo che sulla macchina dove viene interpretato la risoluzione sia obbligatoriamente 640X480 a causa della linea di codice :

setSize(640,480);

Una macchina avente una risoluzione grafica 1280 X 1024 vedrebbe comparire sul video una finestra ancora piu' piccola costringendo l'utente ad un resize manuale tramite mouse.
Per risolvere questo problema Java mette a disposizone la classe Toolkit [1].
La classe Toolkit fornisce un collegamento tra l'implementazione indipendente dalla piattaforma e le  caratteristiche specifiche della piattaforma.
Tra i molti metodi implementati da questa classe vi sono beep() che emette il fatidico "bip" sonoro, getFontList() che restituisce l'elenco dei caratteri supportati, getScreenSize() che identifica le dimensioni dello schermo in punti orizzontali e verticali.
Questi metodi sono utili per interagire con lo specifico S.O su cui il programma Java sta venendo interpretato.
In effetti si puo' dire che la classe astratta Toolkit fa da "colla" tra le classi Java e lo specifico sistema operativo delle macchine sulle quali viene interpretato il codice Java.
Per ricavere le dimensioni del video basta invocare il metodo getScreenSize nel seguente modo :
Dimension screenSize=java.awt.Toolkit.getDefaultToolkit().getScreenSize();

Cambiando il costruttore della classe Frame  nel seguente modo :

public myGoodFrame()
  {
    super("myGoodFrame");
   Dimension screenSize =Toolkit.getDefaultToolkit().getScreenSize();
    frameContainer = getContentPane();
    frameContainer.setLayout(new BorderLayout());
    frameContainer.add("North",new Button("North"));
    frameContainer.add("East",new Button("East"));
    frameContainer.add("Center",new Button("Your screen size is : "+ screenSize.toString()));
    frameContainer.add("West",new Button("West"));
    frameContainer.add("South",new Button("South"));
   this.setSize(screenSize);
    this.setVisible(true);
  }

Otteniamo il  risultato di figura 3.


Figura 3

Indipendentemente dalla risoluzione video, il risultato è il medesimo su entrambi i PC.
Quindi se per caso volessimo che il frame occupasse il 75% dello schermo basterebbe fare :

this.setSize(screenSize.width * 3 / 4,screenSize.height * 3 /4);

Mentre per disporre il frame (avente dimensione pari alla metà di quelle del video) al centro dello schermo sono sufficienti le seguenti istruzioni :

this.setSize(screenSize.width * 1/2,screenSize.height * 1/2); 
Dimension frameSize = this.getSize();
this.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
 
 


Figura 4





Capito il trucco, lo applichiamo immediatamente agli Applet.
Vogliamo conseguire lo stesso risultato ottenuto con la precedente applicazione.
Il codice dell’Applet risulta essere anch’esso semplice e viene sotto riportato :

import java.awt.*;
import java.applet.*;

public class myApplet extends Applet 
{
 public void init()
  { 
    layoutComponents();
  }

 public void layoutComponents()
  {
   Dimension screenSize =Toolkit.getDefaultToolkit().getScreenSize();
   setLayout(new BorderLayout());
   add("North",new Button("North"));
   add("East",new Button("East"));
   add("Center",new Button("Your screen size is : " + screenSize.toString()));
   add("West",new Button("West"));
   add("South",new Button("South"));
   this.setSize(screenSize);
  }
}

Creiamo un semplice file HTML che richiami l’Applet.
Utilizziamo a tale poposito il tag <APPLET> specificando i parametri strettamenti necessari, cioè CODE, WIDTH e HEIGHT.
Tali parametri sono obbligatori e non possono essere omessi.
WIDTH e HEIGHT delineano le dimensioni dell’area in cui comparirà l’Applet all’interno della pagina HTML.

<HTML>
<HEAD>
<TITLE>* 800 X 600*</TITLE>
</HEAD>
<BODY>
<CENTER>
<applet
 code=myApplet.class
 width = 800
 height = 600>
</applet>
</CENTER>
</BODY>
</HTML>

Come WIDTH e HEIGHT ho messo800 e 600  visto che non si possono omettere, tanto poi sarà il metodo setSize(screenSize) ad aggiustare le cose.
Apriamo la nostra pagina HTML sui due famigerati PC di test.
In figura 5 viene riportato il risultato ottenuto.
 
 


Figura 5

Il metodo setSize che funzionava bene con la classe Frame, non sembra sortire nessun effetto con gli Applet.
Come mai ?
Questo perchè le tag WIDTH e HEIGHT sono espresse in modo assoluto, e l’Applet non può modificare il Panel delineato da tali due proprietà in fase di inizializzazione.
Il tutto si risolve con un tocco di malizia.
Andiamo ad espriemre in senso relativo i paramtri WIDTH e HEIGHT, specificando la percentuale di riempimento e non un dato numerico fisso.
Cambiamo il codice della nostra pagina HTML nel seguente modo :

<CENTER>
<applet
  code=myApplet.class
  width = "100%"
  height = "100%">
 </applet>
</CENTER>

Ecco che in questo modo su entrambi i PC, nonostante la risoluzione video diversa, si ha lo stesso effetto, l’Applet occupa l’intera area possibile.
 
 


Figura 6

Supponiamo ora di volere che l’Applet occupi metà dell’area massima disponibile e sia dispota al centro dello schermo.
A parità di bytecode (myApplet.class) ci basterà cambiare i parametri HTML WIDTH e HEIGHT nel seguente modo :

<CENTER>
<applet
  code=myApplet.class
  width = "50%"
  height = "50%">
 </applet>
</CENTER>

In figura 6 si mostra che si ottine il risultato voluto su entrambi i PC.


Figura 7

Si è verificato che il medesimo risultato lo si ottenga per file Jar, su Internet Explorere versione 5.0 e con Netscape 4.0 su piattaforma Sun Solaris.
I risultati di queste ulteriori verifiche sono riportati in fig.8.
 
 


Figura 8

C'è da tenere conto che l'utilizzo di WIDTH e HEIGHT in modo percentuale crea problemi di startup con l'appletviewer.Si può pensare di utilizzare una pagina HTML di prova con i TAG specificati in modo assoluto per provarla con l'appletviewer, e specificarli in termini di percentuale per l'utilizzo con i browser.
 
 

Conclusioni
In questo articolo abbiamo visto come rendere applicazioni ed Applet Java anche indipendenti dalla risoluzione grafica della scheda video tramite l’utilizzo della classe Toolkit e con un pò di malizia nel gestire i parametri HTML WIDTH e HEIGHT.
Per quanto riguarda il ridimensionamento degli Applet in seguito al ridimensionamento della finestra del browser si può utilizzare una tecnica di scripting  riportata nel Tip80 su JavaWorld.[2].
 

Bibliografia
 [1] http://java.sun.com/products/jdk/1.3/docs/api/java/awt/Toolkit.html
 [2] http://www.javaworld.com/javaworld/javatips/f_jw-javatips80.html

 

Chi volesse mettersi in contatto con la redazione può farlo scrivendo a mokainfo@mokabyte.it