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
|