0

the situation is the following.

I have this class:

package it.polimi.client.view.gui.phases;

import it.polimi.client.controller.ControllerClient;
import it.polimi.client.exceptions.BadInputException;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class ChoiceGameTypePhase extends GuiPhase {

    ControllerClient controllerClient;

    public static JFrame frame;
    private String typeGame;

    public ChoiceGameTypePhase(ControllerClient controllerClient) {

        super();
        this.controllerClient = controllerClient;

    }

    @Override
    public void exec() {

        initialize();

    }

    private void initialize() {


        frame = new JFrame("ciao");

        frame.setBounds(100, 100, 345, 260);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);

        JLabel lblChoiceRules = new JLabel("choose which rules to use");
        lblChoiceRules.setBounds(38, 44, 152, 14);
        frame.getContentPane().add(lblChoiceRules);

        /*JRadioButton rdbtnSimple = new JRadioButton("simple");
        rdbtnSimple.setBounds(203, 40, 88, 23);
        rdbtnSimple.addActionListener(/new RdbtnBase());
        frame.getContentPane().add(rdbtnSimple);

        JRadioButton rdbtnComplete = new JRadioButton("complete");
        rdbtnComplete.setBounds(203, 66, 88, 23);
        rdbtnComplete.addActionListener(new RdbtnAdvanced());
        frame.getContentPane().add(rdbtnComplete);

        JRadioButton rdbtnOldSchool = new JRadioButton("old school");
        rdbtnOldSchool.setBounds(203, 92, 88, 23);
        rdbtnOldSchool.addActionListener(new RdbtnOldSchool());
        frame.getContentPane().add(rdbtnOldSchool);

        JRadioButton rdbtnInfection = new JRadioButton("infection");
        rdbtnInfection.setBounds(203, 118, 88, 23);
        rdbtnInfection.addActionListener(new RdbtnInfection());
        frame.getContentPane().add(rdbtnInfection);

        JRadioButton rdbtnArena = new JRadioButton("arena");
        rdbtnArena.setBounds(203, 144, 88, 23);
        rdbtnArena.addActionListener(new RdbtnArena());
        frame.getContentPane().add(rdbtnArena);

        ButtonGroup bg = new ButtonGroup();
        bg.add(rdbtnSimple);
        bg.add(rdbtnComplete);
        bg.add(rdbtnOldSchool);
        bg.add(rdbtnInfection);
        bg.add(rdbtnArena);

        JButton btnBack = new JButton("BACK");
        btnBack.setBounds(10, 196, 89, 25);
        btnBack.addActionListener(new Back());
        frame.getContentPane().add(btnBack);

        JButton btnNext = new JButton("NEXT");
        btnNext.setBounds(240, 196, 89, 25);
        btnNext.addActionListener(new Next());
        frame.getContentPane().add(btnNext);*/

        Dimension screenSize = Toolkit.getDefaultToolkit ().getScreenSize ();
        Dimension frameSize = frame.getSize ();

        frame.setLocation ((screenSize.width - frameSize.width) / 2 , (screenSize.height - frameSize.height) / 2);

        frame.setVisible(true);

    }

    private class RdbtnBase implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {

            typeGame = e.getActionCommand();

        }

    }

    private class RdbtnAdvanced implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {

            typeGame = e.getActionCommand();

        }

    }

    private class RdbtnOldSchool implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {

            typeGame = e.getActionCommand();

        }

    }

    private class RdbtnInfection implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {

            typeGame = e.getActionCommand();

        }

    }

    private class RdbtnArena implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {

            typeGame = e.getActionCommand();

        }

    }

    private class Back implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent arg0) {

            ChoiceGameTypePhase.closeFrame();
            ChoiceConnectionPhase choiceConnectionPhase = new ChoiceConnectionPhase(); 
            choiceConnectionPhase.exec();

        }

    }

    private class Next implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent arg0) {

            if (typeGame != null ) {

                try {
                    System.out.println(typeGame);
                    controllerClient.controlGameType(typeGame);

                } catch (BadInputException e) {

                    JOptionPane.showMessageDialog(null, "<html><p align='center' width='150'>" + e.getMessage() + "</p></html>", "messagge", JOptionPane.ERROR_MESSAGE);

                }

            }
            else {

                JOptionPane.showMessageDialog(null, "<html><p align='center' width='150'>No field selected</p></html>", "messagge", JOptionPane.ERROR_MESSAGE);

            }

        }

    }

    public static void closeFrame() {

        ChoiceGameTypePhase.frame.dispose();

    }

}

which creates a JFrame and shows a window. The class is called in this other class at "phase.exec()":

package it.polimi.client.view;

import it.polimi.client.Session;
import it.polimi.client.controller.ControllerClient;
import it.polimi.client.phases.Phase;
import it.polimi.server.observer.Event;
import it.polimi.server.observer.Observable;
import it.polimi.server.observer.Observer;

import java.net.Socket;

public abstract class HandleNotifiesFromServer implements Observer {

    protected Session session;
    protected Phase phase;
    String eventMessage;

    public HandleNotifiesFromServer(Socket socketServer, ControllerClient controllerClient) {

        this.session = new Session(socketServer, controllerClient);
        getstartedToHandle();

    }

    public void writeServerMessageAndlaunchPhaseCorrespondentBehaviour() {

        System.out.println(eventMessage);
        phase.exec();

    }

    public void parseServerString(String serverString) {

        //Divido la stringa serverString in sottostringhe -> Phase:EventMessage

        String[] serverStringSubstrings = serverString.split(":");

        assert serverStringSubstrings.length == 2 : "[ASSERTION ERROR] Creato un array di sottostringhe dalla stringa ricevuta dal server con dimensione diversa 2."
                + "Dimensione =" + serverStringSubstrings.length ;

        buildPhaseObjectDependingOnServerPhase(serverStringSubstrings[0]);

        eventMessage = serverStringSubstrings[1];

        writeServerMessageAndlaunchPhaseCorrespondentBehaviour();

    }

    public String getEventMessage() {

        return eventMessage;

    }

    @Override
    public void notify(Observable source, Event event) {

        parseServerString(event.getMsg());

    }

    private void registerToEventReceiveGateway(){

        session.getEventReceiveGateway().register(this);    

    }

    private void getstartedToHandle() {

        registerToEventReceiveGateway();
        session.getEventReceiveGateway().startReadingFromSocket();

    }

    public Session getSession() {

        return session;

    }

    public void setSession(Session session) {

        this.session = session;

    }

    public abstract void buildPhaseObjectDependingOnServerPhase(String phase);

}

While the "phase" variable of the previous class is setted in another class depending on what the server sends.

An "HandleNotifiesFromServer" instance (or better an istance of his subclass: "GuiHandleNotifiesFromServer") is created, instead, in this class:

package it.polimi.client.controller;

import it.polimi.client.exceptions.BadInputException;
//import it.polimi.client.phases.Phase;
import it.polimi.client.view.gui.GuiHandleNotifiesFromServer;
import it.polimi.client.view.gui.phases.ChoiceConnectionPhase;
import it.polimi.client.view.gui.phases.ChoiceGameTypePhase;
import it.polimi.client.view.gui.phases.ChoiceNicknamePhase;
import it.polimi.client.view.gui.phases.SimpleGamePhase;
import it.polimi.client.view.util.SocketWriter;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JOptionPane;


public class ControllerClientGui extends ControllerClient {

    public ControllerClientGui() {

        super();

    }

    @Override
    public void controlConnection(String userInput) throws BadInputException {

        switch (userInput) {

        case "SOCKET":

            try {

                Socket socketServer = createSocket();
                this.socketWriter = new SocketWriter(socketServer);

                ChoiceConnectionPhase.closeFrame();

                new GuiHandleNotifiesFromServer(socketServer, this);

            } catch (UnknownHostException e) { 

                JOptionPane.showMessageDialog(null, "<html><p align='center' width='150'>Error creating socket</p></html>", "messagge", JOptionPane.ERROR_MESSAGE);
                e.printStackTrace();

            } catch (IOException e) {

                JOptionPane.showMessageDialog(null, "<html><p align='center' width='150'>Error creating socket</p></html>", "messagge", JOptionPane.ERROR_MESSAGE);
                e.printStackTrace();

            }

            break;

        case "RMI":

            ChoiceConnectionPhase.closeFrame();

            ChoiceGameTypePhase choiceGameTypePhaseRmi = new ChoiceGameTypePhase(this);
            choiceGameTypePhaseRmi.exec();
            break;

        }

    }       


    @Override
    public void controlGameType(String userInput) throws BadInputException {

        System.out.println(userInput);
        //socketWriter.printLineStringOnSocket("GameType:" + userInput);
        ChoiceGameTypePhase.closeFrame();
        ChoiceNicknamePhase choiceNicknamePhase = new ChoiceNicknamePhase(this); 
        choiceNicknamePhase.exec();

    }

    @Override
    public void controlNickname(String userInput) {

        if (userInput.matches("[a-zA-Z]+")) {

            //socketWriter.printLineStringOnSocket("Nickname:" + userInput);
            ChoiceNicknamePhase.closeFrame();
            SimpleGamePhase simpleGamePhase = new SimpleGamePhase(this); 
            simpleGamePhase.exec();
        }

        else {

        JOptionPane.showMessageDialog(null, "<html><p align='center' width='150'>enter username [only character]</p></html>", "messagge", JOptionPane.ERROR_MESSAGE);

        }



    }

    @Override
    public void controlSimpleGame(String userInput) {


    }

    @Override
    public void controlCompleteGame(String userInput) {
        // TODO Auto-generated method stub

    }

    @Override
    public void controlMove(String userInput) {
        // TODO Auto-generated method stub

    }

    @Override
    public void controlNoise(String userInput) {
        // TODO Auto-generated method stub

    }

    @Override
    public void controlUseItem(String userInput) {
        // TODO Auto-generated method stub

    }

    @Override
    public void controlListRounds(String userInput) {
        // TODO Auto-generated method stub

    }

    @Override
    public void controlPossibleMovementsOpponents(String userInput) {
        // TODO Auto-generated method stub

    }

    @Override
    public void controlEndTurn(String userInput) {
        // TODO Auto-generated method stub

    }

    @Override
    public void controlTimer(String userInput) {
        // TODO Auto-generated method stub

    }

    @Override
    public void controlExit(String userInput) {
        // TODO Auto-generated method stub

    }

    @Override
    public void controlAttack(String userInput) {
        // TODO Auto-generated method stub

    }

}

When I run I can see only a blank JFrame window, I can't see any of the element added to pane.

Very strange thing is that if I edit "ControllerClientGui" class this way:

//...

switch (userInput) {

                case "SOCKET":

                    try {

                        Socket socketServer = createSocket();
                        this.socketWriter = new SocketWriter(socketServer);

                        ChoiceGameTypePhase choiceGameTypePhaseSocket = new ChoiceGameTypePhase(this);`
            choiceGameTypePhaseSocket.exec();

                    } catch (UnknownHostException e) {

//...

creating the phase directly in the GuiController end executing it the very next line, I can correctly see the window with all elements inside...

... I really don't know what to think, debugged all day and got nothing, can you help?


I closed the frame 'cause my idea was of opening a window for every "phase", where the correct phase is sended by the server through the socket. As asked, this is the content of GuiHandleNotifiesFromServer:

package it.polimi.client.view.gui;

import java.net.Socket;

import it.polimi.client.controller.ControllerClient;
import it.polimi.client.view.HandleNotifiesFromServer;
import it.polimi.client.view.gui.phases.ChoiceGameTypePhase;
import it.polimi.client.view.gui.phases.ChoiceNicknamePhase;
import it.polimi.client.view.gui.phases.SimpleGamePhase;

public class GuiHandleNotifiesFromServer extends HandleNotifiesFromServer { 

    public GuiHandleNotifiesFromServer(Socket socketServer, ControllerClient controllerClient) {

        super(socketServer, controllerClient);

    }

    @Override
    public void buildPhaseObjectDependingOnServerPhase(String phase) {

        switch(phase) {

        case "InsertGameTypePhase":

            System.out.println(session.getControllerClient() + " " + phase + " DEBUG buildPhaseObjectDependingOnServerPhase");

            this.phase = new ChoiceGameTypePhase(session.getControllerClient());

            break;

        case "InsertNicknamePhase":

            this.phase = new ChoiceNicknamePhase(session.getControllerClient());
            break;

        case "InsertSimpleGamePhase ":

            this.phase = new SimpleGamePhase(session.getControllerClient());
            break;

        }

    }

}
ela
  • 325
  • 2
  • 10
  • 2
    For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example) or [SSCCE](http://www.sscce.org/) (Short, Self Contained, Correct Example). From the little I understood of that, it could be the the socket I/O is blocking the EDT. Don't block the EDT (Event Dispatch Thread). The GUI will 'freeze' when that happens. See [Concurrency in Swing](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/) for details and the fix. – Andrew Thompson Jun 25 '15 at 19:19
  • `lblChoiceRules.setBounds(38, 44, 152, 14);` Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). – Andrew Thompson Jun 25 '15 at 19:21
  • `Dimension screenSize = Toolkit.getDefaultToolkit ().getScreenSize (); Dimension frameSize = frame.getSize (); frame.setLocation ((screenSize.width - frameSize.width) / 2 , (screenSize.height - frameSize.height) / 2); frame.setVisible(true);` easier to `frame.pack(); frame.setLocationRelativeTo(null); frame.setVisibe(true);` – Andrew Thompson Jun 25 '15 at 19:22
  • Why are you disposing a frame `ChoiceConnectionPhase.closeFrame();` and what's in the `new GuiHandleNotifiesFromServer(socketServer, this);` constructor – Madhan Jun 25 '15 at 19:23
  • @Madhan Edited to answer your question. – ela Jun 25 '15 at 19:36
  • @AndrewThompson Thanks for the answer, I'm reading the lesson; I'll make you know – ela Jun 25 '15 at 19:36
  • In `buildPhaseObjectDependingOnServerPhase` in `GuiHandleNotifiesFromServer` inside switch case you are assigning the phase but where are you calling the `phase.exec()`.I guess you forget to call. – Madhan Jun 25 '15 at 19:51

0 Answers0