Newsgroup: it.comp.java
Titolo: [Linux] Di chi e' il Focus?(lungo)

Salve NG, 
scusate se mi dilungo, ma sono giorni che combatto con questo coso e non so 
piu' dove sbattere la testa...
Ho un comportamento anomalo in ambiente Linux (con jre 1.4);
Allego un programma di esempio, per favore se usate Linux fatelo girare e 
seguite questi passi:
* Apri una finestra qualsiasi, ad esempio una shell
* lancia il browser e  richiama l'applet incriminata: avrai un text field e 
un bottone
*  click nel text e pesta un po' di tasti: si vedono i caratteri? si!
* Click nel bottone: si aprira' una window con dentro un bottone con 
scritto "Close ME" 
* Click sul bottone "Close ME"
** CHi ha il focus ora? lo dovrebbe avere il text field ma non lo ha!
* click sulla finestra della shell che avevamo lasciato da parte
*alt+tab in modo da ridare il focus al browser
** chi ha il focus ora? il text field! E allora perche' prima no???!!!
Non posso mica cliccare a destra e a manca per dare il focus a chi di 
competenza!!
Che ne dite?
Segue il programma di prova.
Grazie, 
RIc
/**** programma di test
nome programma: prova.java
applet per lanciarlo:
---p.html -
<HTML>
<HEAD>
<Title>
</Title>
</HEAD>
<BODY  bgcolor=red >
<applet code=prova.class width=600 height=600>
</applet>
</BODY>
</HTML>
-------
compilare con:
javac prova.java
*********/
import java.awt.*;
import java.awt.event.*;
import java.awt.event.MouseEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.*; 
import java.applet.*;
import java.util.*;
public class prova extends Applet       implements MouseListener {
        Button but = null;
        Button but1 = null;
        Dialog db=null;
        TextField tf1 = null;
        public void init() {
         setFont(new Font("Helvetica", Font.PLAIN, 14));
         tf1 = new TextField("MyField");
         but = new Button("Click Here!");
         add(tf1);
         add(but);
                 but.addMouseListener(this);
     }
         public void mouseClicked( MouseEvent evt ) 
         {
 
System.out.println(this.getClass().getName()+"mouseclick"+evt.toString());
                 if (evt.getSource()== but)
                         CreaFrame();
                         if (evt.getSource()== but1)
                 {
                         db.dispose();
                         boolean dum=tf1.requestFocusInWindow();
                         if( !dum) System.out.println("tf1 NON ha preso il 
focus");
                 }
        }
        public void mousePressed( MouseEvent evt ) { }
    public void mouseReleased( MouseEvent evt ) { }
    public void mouseEntered( MouseEvent evt ) { }
    public void mouseExited( MouseEvent evt ) { }
        void CreaFrame()
        {
                 Frame aFrame;
                 Component p = getParent();
                 while (p != null && !(p instanceof Frame) )
                                p = p.getParent();
                 if (p instanceof Frame)
                  {
                         aFrame = (Frame)p;
                 }
           else
                {
                  aFrame = new Frame();
                }
                db = new Dialog(aFrame);
                db.setSize(100,100);
                but1=new Button ("Close Me");
                but1.addMouseListener(this);
                db.add(but1);
                db.show();
        }
}

Ho già sentito parlare del problema dei Focus per gli oggetti AWT su Linux.
Onestamente esiste anche per Windows, ma non sempre.
Io ho risolto delegando il cambio del focus ad un timer.
Abbiamo notato che requestFocus() non riesce a fare il suo lavoro perchè c'è
qualche operazione che le da fastidio, ma basta rallentare la chiamata per
farla andare.
Con un piccolo metodo che lancia un timer che al suo scattare ti mette il
focus, dovrebbe aiutarti.
Prova.

 
Scusa,non mi e' chiarissimo, posso avere un esempio?
Grazie,
RIc

Prova con una cosa tipo : (lo so è una pacchinata degna del nome Patch)
public class Pippo
{
    Timer focusTimer;
    Component cGlobal;
    public void requestFocus(Component c)
    {
        cGlobal = c;
        focusTimer = new Timer(30, new ActionListener(){
                public void actionPerformed(ActionEvent e){
                    cGlobal.requestFocus();
                    focusTimer.stop();
                }
        });
    }
}
Te lo avevo deto che è una pacchianata.
Se ti funziona, puoi sicuramente migliorarlo.
Ti allego anche un codice di esempio che ho provato. Compilalo e guarda se
ti funziona. A me (su win 2K) va senza problemi.
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.Timer;
import java.util.Vector;
public class Pippo extends Frame implements ActionListener
{
    Timer focusTimer;
    Component cGlobal;
    Button cmdNext = new Button("Next");
    Button cmdPrev = new Button("Previous");
    Vector v = new Vector(10);
    int idx = 0;
    public static void main(String argv[])
    {
        (new Pippo()).setVisible(true);
    }
    public Pippo()
    {
        setTitle("Pippo, cammina dritto se no ti metto nel gabinetto");
        setLayout(null);
        setSize(400,400);
        cmdNext.setBounds(10, 50, 100, 20);
        cmdNext.addActionListener(this);
        cmdNext.setName("cmdNext");
        add(cmdNext);
        cmdPrev.setBounds(10, 80, 100, 20);
        cmdPrev.addActionListener(this);
        cmdPrev.setName("cmdPrev");
        add(cmdPrev);
        for(int i=0; i<10; i++)
        {
            TextField txt = new TextField();
            txt.setBounds(200, i*20+50, 150, 20);
            add(txt);
            v.addElement(txt);
        }
        requestFocus(getElement(idx));
    }
    public void actionPerformed(ActionEvent e)
    {
        if(e.getSource() instanceof Button)
        {
            Button b = (Button)e.getSource();
            if(b == cmdNext)
            {
                idx++;
                if(idx>9) idx=0;
                requestFocus(getElement(idx));
            }else if(b == cmdPrev)
            {
                idx--;
                if(idx<0) idx=9;
                requestFocus(getElement(idx));
            }
        }
    }
    private Component getElement(int idx)
    {
        return (Component)v.elementAt(idx);
    }
    public void requestFocus(Component c)
    {
        cGlobal = c;
        focusTimer = new Timer(30, new ActionListener(){
                public void actionPerformed(ActionEvent e){
                    cGlobal.requestFocus();
                    focusTimer.stop();
                }
        });
        focusTimer.start();
    }
}

TelespallaBob wrote.
EIla'
Il programma che hai allegato e' un programma, non una applet :)
I programmi funzionano benissimo,sono le applet che ca##eggiano
Comunque o riportato il sistema sulla mi aapplet e...
e' un disastro :) non va bene, si comporta in mobo molto piu' aleatorio di 
prima! Ho provato anche a sostituire requestFOcus con requestFOcusInWIndow 
(se usi 1.4 teloconsiglio, va comunque un pelino meglio)
Ora sto provando con un Thread.sleep al posto del timer... ma non cambia 
granche'
Comunque mi pare che la gestione del focus sia veramente disastrosa
Ad esempio, sotto Linux devi avere il puntatore del mouse dentro l'area 
dell'Applet per avere il focus e poer digitare caratterei, hai notato? :(
No? be prendi ad esempio 
http://www.visualroute.it/vr.asp
 poniti nel campo di testo e comincia a digitare, poi sposta il sorcio 
fuori, senza cliccare....
RIc

 fuori, senza cliccare....
apero' tu non usi Linux, quindi e' dura da provare !
RIc


mi pare sia un bug conosciuto di mozilla/netscape6
stavolta non e' colpa della sun!  :-)