0

I'm working on a task-planning AWT applet for my dev team, and I'm running into a problem.

I'm using a screen system, where the main class has a "current screen" variable that it uses to paint other screens. When the applet starts, it loads the "main screen" which has a "Chatroom" button. When you click the button, it should open the chatroom screen.

My problem is that it displays the main screen just fine, but when you click the button everything just goes blank and the chatroom does not show up at all. What am I doing wrong?

Each screen is a subclass of the Screen class, which is a subclass of Container.

Main Class:

public class TPApplet extends Applet
{
private static final long serialVersionUID = 7611084043153150559L;
private static final int WIDTH = 400;
private static final int HEIGHT = 350;
private static final String TITLE = "TaskPlanner v";
private static final double VERSION = 0.01;

private boolean setup = false;

public Screen currentScreen;

public void init()
{
    setLayout(null);

    setScreen(new MainScreen(this));
}

public void stop()
{
}

public void setScreen(Screen s)
{
    if (currentScreen != null)
    {
        currentScreen.destroy();
        remove(currentScreen);
    }

    currentScreen = s;

    if (currentScreen != null)
    {
        currentScreen.init();
        add(currentScreen);
    }
}

public void paint(Graphics g)
{
    if (!setup)
    {
        setSize(WIDTH, HEIGHT);
        setName(TITLE + VERSION);

        currentScreen.setLocation(0, 0);
        currentScreen.setSize(WIDTH, HEIGHT);

        setup = true;
    }

    if (currentScreen != null)
    {
        currentScreen.paint(g);
    }
}
}

Main Menu class:

public class MainScreen extends Screen
{
private static final long serialVersionUID = -993648854350389881L;

private TPApplet applet;

private Button todoButton;
private Button chatButton;

private boolean setup = false;

public MainScreen(TPApplet tpApplet)
{
    applet = tpApplet;
}

@Override
public void init()
{
    setLayout(null);

    todoButton = createButton("To-Do List");
    chatButton = createButton("Chatroom");
}

@Override
public void destroy()
{
    removeAll();
}

@Override
public void paint(Graphics g)
{
    if (!setup)
    {
        todoButton.setLocation(25, 50);
        todoButton.setSize(100, 40);

        chatButton.setLocation(135, 50);
        chatButton.setSize(100, 40);

        setup = true;
    }
}

@Override
public void actionPerformed(ActionEvent e)
{
    if (e.getSource() instanceof Button)
    {
        Button button = (Button) e.getSource();

        if (button.getLabel() == chatButton.getLabel())
        {
            applet.setScreen(new ChatScreen(applet));
        }
    }
}
}

Chatroom Class:

public class ChatScreen extends Screen
{
private static final long serialVersionUID = -8774060448361093669L;

private TPApplet applet;

private ScrollPane chatWindow;
private TextField textField;
private Button sendButton;

private boolean setup = false;

public ChatScreen(TPApplet tpApplet)
{
    applet = tpApplet;
}

@Override
public void init()
{
    setLayout(null);

    sendButton = createButton("Send");

    chatWindow = new ScrollPane();
    textField = new TextField();

    add(chatWindow);
    add(textField);
}

@Override
public void destroy()
{
    removeAll();
}

@Override
public void paint(Graphics g)
{
    if (!setup)
    {
        chatWindow.setLocation(20, 20);
        chatWindow.setSize(100, 100);

        textField.setLocation(150, 150);
        textField.setSize(60, 20);

        sendButton.setLocation(220, 150);
        sendButton.setSize(40, 20);

        setup = true;
    }
}

@Override
public void actionPerformed(ActionEvent e)
{
    if (e.getSource() instanceof Button)
    {
        Button button = (Button) e.getSource();

        if (button.getLabel() == sendButton.getLabel())
        {
            String text = textField.getText();
        }
    }
}
}

Thank you in advance for your help!

Michael Auderer
  • 159
  • 1
  • 6
  • 1) Why code an applet? If it is due due to spec. by teacher, please refer them to [Why CS teachers should stop teaching Java applets](http://programmers.blogoverflow.com/2013/05/why-cs-teachers-should-stop-teaching-java-applets/). 2) For deploying Java desktop apps., the best option is usually to install the app. using [Java Web Start](http://stackoverflow.com/tags/java-web-start/info). JWS works on Windows, OS X & *nix. – Andrew Thompson Jun 07 '13 at 17:48
  • @AndrewThompson I looked in to it before and realized exactly that. I'm not making it an applet anymore, i changed it to a desktop application with webstart using swing instead of awt. – Michael Auderer Jun 07 '13 at 18:59
  • Great idea. :) Show us the new code when you have it (unless the problem is already resolved). – Andrew Thompson Jun 07 '13 at 19:01
  • @AndrewThompson Problem resolved, I just had to set the size of it! However i have a new problem now.. listed here: http://stackoverflow.com/questions/16992764/socketexception-resource-temporarily-unavailable-recv-failed – Michael Auderer Jun 07 '13 at 20:54

2 Answers2

2

I suspect that seen as you've chosen to discard the use of layout managers, when you add a new screen, the screen is being added with a 0x0 size

public void setScreen(Screen s)
{

    //...//

    if (currentScreen != null)
    {
        currentScreen.init();
        // Look ma, I have no size...
        add(currentScreen);
    }
}

One of the jobs of a layout manger is to decide how any new components should be laid out.

Try setting the applet's layout manager to something like BorderLayout.

The next problem is that the child screens suffer from the same problem, so even though the screen will be sized (based on the needs of the layout manager), the screens themselves also have no layout manager, so the components you add to them have no size and it will appear that the screen hasn't been updated.

I'd also recommend that you take a look at Andrew's example of CardLayout

You could also check out A Visual Guide to Layout Managers and Using Layout Managers for more details...

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
1

You will need to invalidate() the applet in your setScreen method. The new screen component needs to be laid out again to compute the sizes of its children.

It's a shame this isn't done automatically when adding!

Also, consider doing this using a LayoutManager if possible. Would a CardLayout work for you?

Sanjay Manohar
  • 6,920
  • 3
  • 35
  • 58
  • 1
    For many components in one space, use a [`CardLayout`](http://docs.oracle.com/javase/7/docs/api/java/awt/CardLayout.html) as see in this [short example](http://stackoverflow.com/a/5786005/418556). – Andrew Thompson Jun 06 '13 at 23:50
  • What am I calling invalidate() on? The applet, or the currentScreen? And where in the method do i invalidate it? Please be a bit more clear :) – Michael Auderer Jun 07 '13 at 00:26
  • 1
    invalidate may not work seen as you seen fit to discard the use of the layout managers – MadProgrammer Jun 07 '13 at 00:30
  • I haven't discarded it, I just haven't looked at it yet. I literally just started learning about AWT. I'm gonna look into using layout managers and see if that'll get it to work. – Michael Auderer Jun 07 '13 at 00:32
  • 1
    @MichaelAuderer `setLayout(null)` is what I interrupt as discarding ;) – MadProgrammer Jun 07 '13 at 00:33