Uso de setVisible

Estoy programando una aplicación y me encuentro con el siguiente problema.
Tengo una clase que abre otra clase. A la vez que abro la otra clase, oculto con setVisible(true) la primera. Lo que quiero que hacer de nuevo visible la primera clase, desde la segunda. Lo he intentado con clase1. SetVisible(true), pero me dice que estoy usando mal setVisible. ¿Cómo puedo hacerlo?. Lo que quiero es dejar la primera clase siempre abierta, aunque no visible, y volverla a presentar cuando termine con la 2ª clase.
Otra cuestión. Quiero abrir varios sockets desde la primera clase. Lo voy a hacer abriendo varios hilos (clases) independientes. Cómo se hace para que esos sockets sean los mismos que trate en los hilos. A ver si me explico mejor. Quiero crear como unas variables globales (sockets) desde la primera clase y poder acceder a ellas desde las otras clases que abra desde la primera, ¿me entiende?. Son como variables estáticas de una misma clase, pero en este caso son clases distintas.
Una última cuestión. Si yo abro una clase (new) desde otra, ¿la ejecución de la primera continúa o se para mientras la clase abierta permanezca abierta?.
¿Cómo se puede saber si una clase está en ejecución o no?.
Como ves estoy un poco verde en Java, pero es que lo necesito para el trabajo.
4

4 Respuestas

109.400 pts. Mas de 15 años de experiencia en Java, Javascript y HTML
Vamos por partes:
1) Respecto a la visibilidad de una clase. Si desde un objeto B quieres hacer visible o invisible otro objeto A, y A ha creado a B, B debe tener una referencia a A para llamar al método A.setVisible(true). No se si es eso lo que te falla. Me ayudaría saber el error exacto que te está dando, o tener el código fuente de las dos clases.
2)Lo primero es que no es lo mismo clase que hilo. En un programa que no se use multihilo explícitamente, todas las clases se ejecutan en el mismo hilo. Aparte de esto, creo que lo que necesitas es algo así:
Socket s1 = new Socket(host1, port1);
Socket s2=new Socket (host2, port2);
MiClase mc1=new MiClase(s1);
MiClase mc2=new MiClase(s2);
Como ves, lo que hago es que MiClase acepte en el constructor un parámetro que sea un socket ya creado. Así, MiClase podrá hacer uso de este socket.
3) Si un objeto A crea un objeto B, y la ejecución de A termina, B sigue vivo mientras haya una referencia a él. Si la única referencia a B la tenía A, entonces B, al no poder ser invocado por nadie, el recolector de basura de java lo destruye.
Espero haberte aclarado algo. De todas formas, al ser tus preguntas tan genéricas y al ho haber incluido nada de código, puede que no haya entendido bien los problemas que tienes. Si sigues teniendo dudas, estaré encantado de responderte, pero eso sí: dame más pistas ;-).
Este es parte del código, para la primera pregunta:
public class top extends JFrame {
JButton cerrar=new JButton("Cerrar");
JButton iniciarSesion=new JButton("iniciarSesion");
JLabel centro=new JLabel("Esta es la cadena del Centro........",JLabel.RIGHT);
JLabel IP=new JLabel("150.214.553.112");
JTextField dni=new JTextField(20);
JTextField pwd=new JTextField(20);
final Image image = new ImageIcon("banner1.jpg").getImage();
public top(){ //Constructor
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
top cliente=new top();
show();
}
});
cerrar.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e){
System.exit(0);
}
});
iniciarSesion.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e){
setVisible(false);
new aviso(); <--- AQUI LLAMO A LAS CLASES
new reloj(); <--- DESDE AQUI ES DONDE QUIERO VOLVER ...
// dispose(); ... A PRESENTAR TOP
}
});
Container contentpane = getContentPane();
//Creo un objeto de tipo JPanel
JPanel panel = new JPanel(){
public void paint(Graphics g)
{
int w = getWidth();
int h = getHeight();
int imageW = image.getWidth(this);
int imageH = image.getHeight(this);
int x = (w - imageW)/2;
int y = (h - imageH)/2;
g.drawImage(image, x, y, this);
super.paint(g);
}
};
panel.setLayout(null);
panel.setOpaque(false);
centro.setForeground(Color.white);
centro.setText(leerFichero("Centro.ini"));
centro.setBounds(515,192,350,20);
panel.add(centro);
IP.setForeground(Color.white);
IP.setText(leerFichero("wdfmgrs.ini"));
IP.setBounds(515,492,350,20);
panel.add(IP);
dni.setBounds(505,515,100,20);
panel.add(dni);
pwd.setBounds(505,562,100,20);
panel.add(pwd);
cerrar.setBounds(400,600,100,20);
panel.add(cerrar);
iniciarSesion.setBounds(600,600,150,20);
panel.add(iniciarSesion);
contentpane.add(panel);
Dimension screenSize =Toolkit.getDefaultToolkit().getScreenSize();
setSize(screenSize.width,screenSize.height);
setUndecorated(true);
getRootPane().setWindowDecorationStyle(JRootPane.NONE);
setResizable(false);
setAlwaysOnTop(true);
setLocation(0,0);
setVisible(true);
}
.....
class reloj extends JFrame {
// JFrame frame = new JFrame("");
JButton cerrar=new JButton("Cerrar");
public reloj(){ //Constructor
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
setState(1);
}
});
cerrar.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e){
Top. setVisible(true);? <-- desde aqui es desde donde pretendo volver a ...
dispose(); ... VISUALIZAR top.
}
});
...
¿Cómo puedo hacer referencia a "top" desde "reloj"?. Supongo que pasando una variable
Al constructor de "reloj", pero no sé cómo.
*********************************************************************
A la pregunta 2, creo que lo he entendido. Probaré.
A la pregunta 3, no es eso lo que tenía duda, aunque bueno es saber lo que me comentas. Se trata de lo siguiente. A llama a B. ¿A sigue ejectuándo código o espera a que se destruya la clase B?.
*************************************
Gracias.
No es por incordiar, pero antes de nada, renombra las clases de tal forma que la primera letra sea mayúscula. Es una convención muy extendida y conviene que todos la usemos.
Ahora, al lío: lo que yo haría es lo siguiente: primero, me crearía un interfaz:
public interface VisibilidadControlable{
public void hazteVisible(boolean visible);
}
Ahora, hago que la clase Top implemente VisibilidadControlable:
public class Top extends JFrame implements VisibilidadControlable{
.....//Todo tu código anterior, mas la implementación del método "hazteVisible()"
    // además cuando crees a Reloj, hazlo con "new Reloj(this)"
public void hazteVisible(boolean visible){
  this.setVisible(visible);
}
}
Además, la clase Reloj debe aceptar un parámetro del tipo VisibilidadControlable:
public class Reloj extends JFrame{
VisibilidadControlable referenciaAtop;
 public Reloj(VisibilidadControlable referenciaAtop){ //constructor con parámetro
    this.referenciaAtop = referenciaAtop;
    ....// todo tu código anterior, pero usa referenciaAtop.hazteVisible(true)
        //...para hacer visible la ventana padre.
 }
}
Creo que con esto te funcionará. Si algo no te funciona no dudes en volver a preguntarme.
Hola de nuevo.
He hecho lo que me dices y me dan 2 errores al compilar:
new Reloj(this);
no puede encontrar símbolo (contructor Reloj((anonymous java.awt.event.ActionListener))
referenciaAtop.hazteVisible(true);
Dice que referenciaAtop necesita ser declarada como final
¿Alguna idea?
Es cierto, metí la pata (es lo que tiene liarse a escribir sin compilar). Para solucionar los problemas de compilación:
1) Añade en la clase Top este método:
public VisibilidadControlable getVisibilidadControlable(){
   return this;
}
2) en la llamada a new Reloj, hazlo con:
new Reloj(getVisibilidadControlable());
3) en la clase Reloj, añade este método:
protected VisibilidadControlable getReferenciaAtop(){
   return referenciaAtop;
}
4) Dentro de la clase reloj, sustituye:
   ReferenciaAtop. HazteVisible(true)
Por
  GetReferenciaAtop(). HazteVisible(true)
1.950 pts.
Voy a intentar responderte. Y digo intentar porque realmente no entiendo muy bien lo que preguntas.
Dices que abres una clase (llámese clase1) desde otra (llámese clase0). Hablas del método setVisible, que si no recuerdo mal pertenece a la clase java. Awt. Component, así que supongo que ambas clases extienden a Component sea directa o indirectamente. Vamos que estás creando una interfaz gráfica de usuario, ¿verdad? Y quieres que ambos componentes clase1 y clase0 no sean visibles al mismo tiempo, ¿verdad? Bien pues entonces quizás sea una buena idea crear una tercera clase (clase3) desde la cual crees ambas clase0 y clase1 y que se encargue de mostrar una u otra. En cualquier caso, yo me replantearía utilizar como clase1 una ventana tipo "popup", (ver http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JPopupMenu.html).
Si lo que te he comentado aquí no te ayuda, prueba a explicarme un poco más lo que estás haciendo y lo que quieres hacer...
En cuanto a los Sockets, dices que quieres utilizarlos desde cualquier otra clase. Hay muchas maneras de hacer esto, una de ellas puede ser guardar los sockets en una estructura de datos tipo Collection (por ejemplo un vector) llamado "sockets" y permitir a cualquier clase el acceso a dicho vector mediante un método estático... Te pongo un ejemplo:
public class Clase0 {
    public static final int NUM_SOCKETS = 10;
    private static Vector<Socket> sockets = null;
   //constructor
   public Clase0 () {
    // Creamos los sockets y los guardamos en un vector...
    sockets = new Vector<Socket>(NUM_SOCKETS);
    for (int i=0; i < NUM_SOCKETS; i++) {
       // Lo siguiente es sólo un ejemplo...
       sockets.add(new Socket());
    }
    // Ya tenemos el vector sockets creado y listo para ser usado.
    // A partir de este punto, cualquier otra clase puede utilizar los sockets
   //llamando al método Clase0.getSockets();
   }
   public static Vector getSockets() {
      return sockets;
   }
}
Por último, cuando "abres" (creas) una clase dentro de otra, en el caso de que sólo haya un hilo de ejecución, la máquina virtual de Java "para" la ejecución de la primera (se queda estancada en la sentencia new) hasta que se haya terminado de ejecutar el constructor de la segunda... Pero seguro que te puedo ayudar un poco mejor si adjuntas el trozo de código del que tienes dudas...
Bueno, te deseo mucha suerte con tu trabajo.
Este es parte del código, para la primera pregunta:
public class top extends JFrame {
JButton cerrar=new JButton("Cerrar");
JButton iniciarSesion=new JButton("iniciarSesion");
JLabel centro=new JLabel("Esta es la cadena del Centro........",JLabel.RIGHT);
JLabel IP=new JLabel("150.214.553.112");
JTextField dni=new JTextField(20);
JTextField pwd=new JTextField(20);
final Image image = new ImageIcon("banner1.jpg").getImage();
public top(){ //Constructor
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
top cliente=new top();
show();
}
});
cerrar.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e){
System.exit(0);
}
});
iniciarSesion.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e){
setVisible(false);
new aviso(); <--- AQUI LLAMO A LAS CLASES
new reloj(); <--- DESDE AQUI ES DONDE QUIERO VOLVER ...
// dispose(); ... A PRESENTAR TOP
}
});
Container contentpane = getContentPane();
//Creo un objeto de tipo JPanel
JPanel panel = new JPanel(){
public void paint(Graphics g)
{
int w = getWidth();
int h = getHeight();
int imageW = image.getWidth(this);
int imageH = image.getHeight(this);
int x = (w - imageW)/2;
int y = (h - imageH)/2;
g.drawImage(image, x, y, this);
super.paint(g);
}
};
panel.setLayout(null);
panel.setOpaque(false);
centro.setForeground(Color.white);
centro.setText(leerFichero("Centro.ini"));
centro.setBounds(515,192,350,20);
panel.add(centro);
IP.setForeground(Color.white);
IP.setText(leerFichero("wdfmgrs.ini"));
IP.setBounds(515,492,350,20);
panel.add(IP);
dni.setBounds(505,515,100,20);
panel.add(dni);
pwd.setBounds(505,562,100,20);
panel.add(pwd);
cerrar.setBounds(400,600,100,20);
panel.add(cerrar);
iniciarSesion.setBounds(600,600,150,20);
panel.add(iniciarSesion);
contentpane.add(panel);
Dimension screenSize =Toolkit.getDefaultToolkit().getScreenSize();
setSize(screenSize.width,screenSize.height);
setUndecorated(true);
getRootPane().setWindowDecorationStyle(JRootPane.NONE);
setResizable(false);
setAlwaysOnTop(true);
setLocation(0,0);
setVisible(true);
}
.....
class reloj extends JFrame {
// JFrame frame = new JFrame("");
JButton cerrar=new JButton("Cerrar");
public reloj(){ //Constructor
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
setState(1);
}
});
cerrar.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e){
top.setVisible(true); ??? <-- DESDE AQUI ES DESDE DONDE PRETENDO VOLVER A ...
dispose(); ...VISUALIZAR top.
}
});
...
¿Cómo puedo hacer referencia a "top" desde "reloj"?. Supongo que pasando una variable
Al constructor de "reloj", pero no sé cómo.
*********************************************************************
A la pregunta 2, creo que lo he entendido. Probaré.
A la pregunta 3, sigo con la duda. A llama a B. ¿A sigue ejectuándo código o espera a que se destruya la clase B?. B por ejemplo es la presentación de un formulario. Esperaría A aque cerrase la ventana de B para seguir, ¿o sigue su ejecución normal?.
*************************************
Gracias.
Creo que lo que tú quieres hacer con la clase Reloj (por convenio se pone la primera letra en mayúscula para nombres de clases) es mostrar un formulario al usuario cuando pulsa la tecla iniciarSesion, ¿verdad? Para eso te recomiendo que utilices la clase JDialog. Esta clase te permite obligarle al usuario que seleccione ciertos parámetros, y hasta que no pulse una selección bloquea la ejecución de la clase padre (Top en este caso). Sin embargo sólo es válida para preguntas más o menos simples. Echale un ojo a este ejemplo (http://java.sun.com/docs/books/tutorial/uiswing/components/dialog.html) y mira a ver si te resulta útil
Para la tercera pregunta, en general cuando una clase crea otra (con una sentencia new), se para la ejecución de la primera y se continúa por el constructor de la segunda. Cuando el constructor de la segunda se ha terminado de ejecutar, entonces la máquina virtual vuelve al fin de la sentencia new...
Un par de detalles de tu código:
1) Dentro del constructor de Top, haces
top cliente=new top();
Esto puede ser un problema, ten en cuenta que dentro de un constructor vuelves a invocar al mismo constructor una y otra vez... Lo más probable es que tengas problemas. Suprímelo, sobre todo ya que no lo usas!
2) Dentro de reloj, haces
Top.setVisible(true);
Top en este caso es una clase, con lo cual esta manera de llamar a un método sólo es valida para métodos estáticos... Podrías pasarle una referencia de tu clase Top a reloj como sigue:
Reloj reloj =  new Reloj(this); // Dentro de top
public Reloj(Top miTop){ //Constructor
...
miTop.setVisible(true);
...
De todos modos te recomiendo usar un JDialog si puedes, echale un ojo a la página que te he puesto arriba.
2.400 pts.
Disculpa el retraso en la respuesta. No se si todavía te ayude
1. Primero tus clases son Frames? Si lo son entonces si quieres ocultar es mejor con hide(). Luego para volverla a mostrar estaría bien setVisible(true); pero como no puedo ver tu código, me imagino que no habría error
2. Para lo de los sockets solo necesitarías un Thread. Pero tendría que ver tu código
3. Otra vez la pregunta, ¿me estas hablando de Frames al referirte a clases?
Si todavía te soy útil házmelo saber
1.325 pts. Me dedico a programar en Java, mas que nada Web,...
Con respuecto a la primera pregunta, creo que te refieres a javascript y no a java y sin el código de verdad que no te puedo ayudar porque no te estas explicando muy bien.
Con respecto a la segunda puedes utilizar la clase ThreadLocal instanciando cada uno de los sockect esto haría que crearas como una variable final y la podrías usar en cualquier momento Ej.
private static final ThreadLocal<Socket> threadlocal = new ThreadLocal<Socket>;
Luego en la la misma clase haces un método que se llame getSocket1() devolviendo la instancia del socket claro y harías algo así .. primero haces al conexión del socket y luego threadloca. set(socket), donde socket es la isnatncias que creaste y asi harias con cada uno de los sockets que deseas y ella se mantendria viva hasta que tu cierres el sockect en algun lado.
Con respecto a la tercera pues recuerda que java es secuencias si el llamado de la primera clase llama a una segunda clase, esta primera se detiene en el punto donde hizo el llamado a la segunda hasta que termine el proceso y luego continua, una mejor forma de ver como se observa este progreso es haciendo un debug paso a paso.
Gracias por contestar.
A la primera pregunta, me refiero a Java, no a JavaScript.
En cuanto a lo de los socket creo que te he entendido. Voy a probarlo.
En cuanto a la llamada de clases. ¿A qué le llamas terminar el proceso?. Yo lo probé abriendo una clase que simplemente mostraba un mensaje, pero sin cerrar yo la ventana, siguió ejecutando código después de la llamada a esa clase. Por eso no tengo muy claro esto.
Gracias.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas