Duda con interfaces gráficas en Java.

Iniciado por niano, 6 Septiembre 2019, 16:58 PM

0 Miembros y 1 Visitante están viendo este tema.

niano

Hola.

He tenido una pequeña sorpresa programando interfaces gráficas con Java. He simplificado el código manteniendo el problema para que se haga más sencilla su comprensión. Tenemos una clase Prueba2 que extiende un JFrame:

Código (java) [Seleccionar]

package prueba2;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import javax.swing.JFrame;
public class Prueba2 extends JFrame   {
    private PanelPrueba Juego;
    public Prueba2() throws IOException{
        Juego=new PanelPrueba();
        getContentPane().add(Juego);
        addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent e){
                System.exit(0);
            }
        });
       Juego.setVisible(true);
}
    public static void main(String[] args) throws IOException {
        Prueba2 J=new Prueba2();
        J.setBounds(0, 0, 400, 400);
        J.setVisible(true);
    }
}


Y otra clase PanelPrueba, que extiende un JPanel e implementa un KeyListener:

Código (java) [Seleccionar]

package prueba2;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import static javax.swing.JOptionPane.PLAIN_MESSAGE;
import static javax.swing.JOptionPane.YES_NO_OPTION;
import static javax.swing.JOptionPane.YES_OPTION;
import static javax.swing.JOptionPane.showConfirmDialog;
import javax.swing.JPanel;

public class PanelPrueba extends JPanel implements KeyListener {
    public PanelPrueba(){
        setBounds(0,0,200,500);
        addKeyListener(this);
        setFocusable(true);
        requestFocus();
}
    public void paint(Graphics g){
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, 200, 500);
    }
    public void reiniciar() {
        repaint();
    }
    @Override
    public void keyTyped(KeyEvent que) {}
   
    @Override
    public void keyPressed(KeyEvent que)  {
        if(showConfirmDialog(this,"Has ganado,deseas empezar otra partida?","Fin de Partida",YES_NO_OPTION,PLAIN_MESSAGE)==YES_OPTION){
            reiniciar();
        } 
        else{
           System.exit(0);
        }
    }
   
    @Override
    public void keyReleased(KeyEvent que) {}
}


Básicamente lo que pasa cuando aprietas una tecla es que te sale un cuadro de diálogo con dos botones. Si se pulsa "No" la aplicación finaliza y si se pulsa "Sí" vuelve a la situación inicial. La sorpresa está en que si se pulsa "Sí" aparece un molesto texto detrás del JPanel. ¿Alguien sabría explicarme por qué pasa eso, y cómo se puede solucionar el problema?

He estado probando cosas, y si el cuadro de diálogo haces que aparezca con un showMessageDialog en lugar de con un showConfirmDialog el problema desaparece.

Por otro lado, si hago que la clase PanelPrueba extienda un Canvas en lugar de un JPanel el problema desaparece. No obstante, quisiera solucionar el problema con un JPanel, ya que éste es el "peso pesado" de los contenedores, y aporta muchas ventajas, ¿verdad?  ;)

También me gustaría comentar que me han pasado cosas parecidas cuando he añadido objetos de clases JPanel y JButton a un mismo JFrame, y que estos problemas han desaparecido igualmente utilizando Canvas.

Agradezco de antemano cualquier tipo de ayuda o comentario y el tiempo que os haya tomado atenderme.

Un saludo a todos.

niano

Hola.

Hace unos días solucioné el problema. Se trataba de incluir la línea setLayout(null); en el constructor del JFrame.

No entiendo muy bien por qué esa línea soluciona el problema. ¿A alguien se le ocurre por qué?

Me llama la atención especialmente que el error sólo ocurría en máquinas con Windows, lo he comprobado en dos diferentes. Sin embargo en máquinas con Mac el problema, según parece, no tenía lugar. Pero, ¿no se suponía que con el JPanel y el JFrame no dependían del sistema y que eso era una ventaja sobre el Canvas y el Frame?

Si alguien sabe algo sobre lo que pasa aquí me encantaría que me iluminase un poco. Supongo que ya se ve que estoy un poco verde en el tema y quizás no sea fácil explicármelo, pero estaría muy interesado en aprender algo al respecto.

Gracias de antemano. Un saludo.

rub'n

#2
Cita de: niano en 16 Mayo 2020, 20:36 PM
Hola.

Hace unos días solucioné el problema. Se trataba de incluir la línea setLayout(null); en el constructor del JFrame.

No entiendo muy bien por qué esa línea soluciona el problema. ¿A alguien se le ocurre por qué?

Me llama la atención especialmente que el error sólo ocurría en máquinas con Windows, lo he comprobado en dos diferentes. Sin embargo en máquinas con Mac el problema, según parece, no tenía lugar. Pero, ¿no se suponía que con el JPanel y el JFrame no dependían del sistema y que eso era una ventaja sobre el Canvas y el Frame?

Si alguien sabe algo sobre lo que pasa aquí me encantaría que me iluminase un poco. Supongo que ya se ve que estoy un poco verde en el tema y quizás no sea fácil explicármelo, pero estaría muy interesado en aprender algo al respecto.

Gracias de antemano. Un saludo.


Bueno mira, respondiendo una parte de tu pregunta, seguro es incompatibilidad del Layout, porque el único Layout multiplataforma es el,

GroupLayout

Entonces como lo seteas a null, pues quizá este la cosa por ahi.

saludos.


rubn0x52.com KNOWLEDGE  SHOULD BE FREE!!!
If you don't have time to read, you don't have the time (or the tools) to write, Simple as that. Stephen

niano

Hola.

Antes de nada muchas gracias por responder, rub'n.

Cita de: rub'n en 17 Mayo 2020, 17:44 PM

Bueno mira, respondiendo una parte de tu pregunta, seguro es incompatibilidad del Layout, porque el único Layout multiplataforma es el,

GroupLayout

Entonces como lo seteas a null, pues quizá este la cosa por ahi.


Mmmm... No sé si te he entendido bien. Resulta que el problema desapareció precisamente cuando metí la línea setLayout(null) al principio del constructor de la clase que extiende el JFrame, ¿dices que mejor haber hecho algo con un GroupLayout?

Un saludo y gracias.