Jump to content

Comando para fechar janela de frame?


ms2222
 Share

Recommended Posts

Boas,

estou a fazer uma aplicação cliente servidor com sockets e threads. O sistema esta desenvolvido de forma a que quando eu pressione uma tecla esse evento seja enviado para o servidor e este responda com a informação que se deve fechar a aplicação cliente, neste caso um frame com um jogo. O que eu queria era um comando que fechasse a janela do frame sem encerrar também o servidor. Já tentei System.exit(0) mas esse encerra cliente e servidor, ja experimentei frame.dispose() mas isso apenas faz desaparecer o frame, o que eu pretendia era um comando que quando executado fechasse a janela do frame e encerrasse a comunicação com o servidor sem terminar também o servidor. Alguém me consegue ajudar?

Cumps

Link to comment
Share on other sites

Por o que tenho entendido, o System.exit(0) só fecha a aplicação. Alguns IDEs usam a mesma máquina virtual para correr varios programas, e por isso ao fechar um, a máquina virtual elimina-os todos. Tentaste executar desde a consola ou até criar um jar independente?

Link to comment
Share on other sites

Não faz sentido o System.exit() fechar os dois, a não ser que estejam a correr na mesma JVM, o que não deviam.

Tens duas opções, o método dispose(), que fecha a aplicação apenas se a janela que estás a fechar for a última que está a correr na JVM, ou o System.exit() que termina a execução da JVM, o que em parece é que tens duas coisas diferentes a correr na mesma JVM e isso não está correcto e está a causar esses problemas.

O IDE devia iniciar um processo por cada execução que fazes, se não o estiver a fazer, e estiveres a testar as aplicações, inicia as aplicações em processos separados sem recorreres ao IDE.

Link to comment
Share on other sites

Embora o ideal seja o System.exit(0), o dispose() não é má alternativa:

public void dispose()

Releases all of the native screen resources used by this Window, its subcomponents, and all of its owned children. That is, the resources for these Components will be destroyed, any memory they consume will be returned to the OS, and they will be marked as undisplayable.

Mais aquí...

Link to comment
Share on other sites

Quanto aos recursos serem destruídos, é quase isso 👍 , se fizerem dispose a uma janela e depois fizerem um setVisible(true) vão reparar que todos os componentes estão no mesmo estado em que estavam quando foram removidos, isto é, contém os mesmos dados, as mesmas selecções, etc. O dispose marca a janela para remoção, mas só será mesmo removida quando a JVM terminar.

Link to comment
Share on other sites

Executei agora novamente o servidor e o cliente em directorios diferentes na consola e efectivamente quando System.exit(0) é executado no lado do cliente encerra também o servidor.

Tentei fazer outro teste e coloquei o servidor a rodar no servidor que a universidade disponibiliza para os alunos, mas neste caso o cliente não se conseguiu conectar sequer. Poderá ser algum problema relacionado com politicas de segurança? Eu uso o Windows Vista.

Link to comment
Share on other sites

Estás a proteger o servidor e o cliente para o caso do socket terminar abruptamente? Isto é, se o cliente termina, o código de ligação está preparado aceitar novas ligações ou simplesmente executa até terminar?

Quanto a conseguir-se ligar, poderá ser muita coisa, portos fechados, firewalls, etc.

Link to comment
Share on other sites

Tenho seguido um modelo baseado num TicTacToe que encontrei, mas não sei muito bem se estou a fazer o que tu questionas. O código que estou a utilizar é o seguinte:

Servidor:

(...)
public ForcaServerProtocolo ()
        {
            try
            {
                server = new ServerSocket(5000);
            }
            catch (IOException e)
            {
                e.printStackTrace();
                System.exit( 1 );
            }

            System.out.println( "Server is started and is waiting for connections." );
        }
    
        public void execute()
        {
            while(true)
            {
                try
                {
                    player = new Player( server.accept(), this);
                    player.start();
                }
                catch ( IOException e)
                {
                    e.printStackTrace();
                    System.exit( 1 );
                }
            }
        }
(...)

Depois a partir daqui cria um player que extende de thread:

public class Player extends Thread 
{
(...)

public Player(Socket s, ForcaServerProtocolo t)
    {
        connection = s;
        control = t;

        System.out.println( "Connection established with: " + connection );
        try
        {
            input	= new ObjectInputStream( connection.getInputStream() );
            output	= new ObjectOutputStream( connection.getOutputStream() );
        }
        catch (IOException e) 
        {
            e.printStackTrace();
            System.exit(1);
        }
    }

    public void run() 
    {
        try 
        {
            while( true ) 
            {
                processaMsg(Protocolo.recebe(input));
            }

        }
        catch( Exception e ) 
        {
            e.printStackTrace();
            System.exit(1);
        }
    }
(...)
}

No cliente tenho o seguinte:

public class ClienteForcaClientProtocolo extends Applet implements Runnable {
(...)
public void start() {

        try {
            InetAddress serverAdd = InetAddress.getByName("localhost");
            connection = new Socket(serverAdd, 5000);
            output = new ObjectOutputStream(connection.getOutputStream());
            input = new ObjectInputStream(connection.getInputStream());

            inputThread = new Thread(this);
            inputThread.start();

            //Relativo ao protocolo de comunicação
            MsgIdt msg = new MsgIdt();
            msg.envia(output);
            System.out.println(msg);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

public void run() {
        try {
            while (true) {
                processaMsg(Protocolo.recebe(input));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Agora, se estou a fazer tudo o que é preciso isso são outros quinhentos  👍

Link to comment
Share on other sites

Ora pois lá está 👍

Esses tratamentos de excepções que têm um System.exit não estão muito correctos. Primeiro, não estão a tratar a excepção correcta mas sim uma excepção qualquer, não interessa qual é, desde que ocorra um excepção, ela vai ser tratada. Depois, quando no clientes invocas o fecho da aplicação, com o System.exit(), o socket vai ser fechado e do lado do servidor ocorre uma excepção, essa excepção do lado do servidor vai invocar, curiosamente, um outro System.exit().

Portanto, não é o cliente que está a desligar o servidor, nem o System.exit() do cliente. É o facto de terminares a aplicação quando ocorrem excepções. Estás a fazer o tratamento errado das excepções.

No caso do cliente, é a mesma história, fazes um printStackTrace, mas quando a excepção é executada o ciclo while é terminado e a aplicação executa a partir daí até ao fim.

Da forma como tens o código, se eu fechar o clientes vais provocar o fecho do servidor por tratares mal o fecho do socket, e vice-versa. Na wiki do P@P, na secção de Java, está um exemplo de um chat com sockets, http://wiki.portugal-a-programar.org/java:tutorial:131_chat

Link to comment
Share on other sites

Ora pois lá está 😞

Esses tratamentos de excepções que têm um System.exit não estão muito correctos. Primeiro, não estão a tratar a excepção correcta mas sim uma excepção qualquer, não interessa qual é, desde que ocorra um excepção, ela vai ser tratada. Depois, quando no clientes invocas o fecho da aplicação, com o System.exit(), o socket vai ser fechado e do lado do servidor ocorre uma excepção, essa excepção do lado do servidor vai invocar, curiosamente, um outro System.exit().

Portanto, não é o cliente que está a desligar o servidor, nem o System.exit() do cliente. É o facto de terminares a aplicação quando ocorrem excepções. Estás a fazer o tratamento errado das excepções.

No caso do cliente, é a mesma história, fazes um printStackTrace, mas quando a excepção é executada o ciclo while é terminado e a aplicação executa a partir daí até ao fim.

Da forma como tens o código, se eu fechar o clientes vais provocar o fecho do servidor por tratares mal o fecho do socket, e vice-versa. Na wiki do P@P, na secção de Java, está um exemplo de um chat com sockets, http://wiki.portugal-a-programar.org/java:tutorial:131_chat

Efectivamente aquele tratamento do catch no metodo run na classe player onde recebia os dados estragava o esquema todo. Assim, com o System.exit(0) já funciona correctamente.

Ainda assim, quem sabe é outra coisa.  👍

Cumps  👍

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.