Wednesday 2 March 2016

Spot The Bug: The Java Sentry

Good day, ladies and gentlemen. Spot The Bug is in town.

Time for some
bug-hunting!


This one is in Java. Not only that, it's a Java noob bug. Got a techie to look at it, and he couldn't figure it out either. Took an hour and boy, by the time I found it, it's so simple I could've died. I was trying to get a simple graphical interface for an Sign-in module up.

Here's what I was trying to accomplish. Simple enough? Well, apparently not!



What went wrong 

This happened.



The label and textbox simply did not show up. However, the window with title and all, opened just fine. Morever, there were no compiler errors. Here's the code for the classes.

Sentryguard.java
package tt_Sentryguard;
public class Sentryguard
{
    public static void main(String[] args)
    {
        SentryguardFrame frame=new SentryguardFrame();
        frame.setTitle("Guard on Duty");
        frame.setSize(800, 200);
        frame.setVisible(true);
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
     }
}

SentryguardFrame.java
package tt_Sentryguard;

import java.awt.Dimension;
import javax.swing.*;

public class SentryguardFrame extends JFrame
{
    private JPanel pnlSentryguard;
    private JTextField txtSentryguard;
  
    public void SentryguardFrame()
    {
        pnlSentryguard=new JPanel();
        txtSentryguard=new JTextField();
        txtSentryguard.setPreferredSize(new Dimension(300, 20));
       
        pnlSentryguard.add(new JLabel("HALT! Who goes there?"));
        pnlSentryguard.add(txtSentryguard);
       
        this.add(pnlSentryguard);
    }
}

I tried doing this instead - adding all the graphical interface elements from the main method instead of from the class. It worked! But that wasn't what I wanted. For a simple interface, it wouldn't matter. But if I had nested frames and an entire form of buttons, controls and what-have-you, this would get messy real quick. So no, I had to solve this problem rather than get around it.

Sentryguard.java
package tt_Sentryguard;

import java.awt.Dimension;
import javax.swing.*;

public class Sentryguard
{
    public static void main(String[] args)
    {
        SentryguardFrame frame=new SentryguardFrame();
        frame.setTitle("Guard on Duty");
        frame.setSize(800, 200);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(
        JFrame.EXIT_ON_CLOSE);
              
        JPanel pnlSentryguard=new JPanel();
        JTextField txtSentryguard=new JTextField();
        txtSentryguard.setPreferredSize(new Dimension(300, 20));
       
        pnlSentryguard.add(new JLabel("HALT! Who goes there?"));
        pnlSentryguard.add(txtSentryguard);
       
        frame.add(pnlSentryguard);
    }
}

So, back to square one. But that's OK, because it gave me a clue as to what was going on there. Obviously the code in Sentryguard.java was working fine, so the problem had to be in SentryguardFrame.java.

Why it went wrong 

The "void" in the SentryguardFrame() method was the problem. Because SentryguardFrame() is supposed to be a constructor. While public void SentryguardFrame() is technically legal, this meant that the program would treat SentryguardFrame() like any other method. The compiler would create its own default constructor in the absence of an programmer-specified one. But that default constructor would be blank, without any of the custom code I put in there. And SentryguardFrame frame=new SentryguardFrame(); would use that blank constructor instead.

How I fixed it 

Remove the "void" like so, and voila!
SentryguardFrame.java
package tt_Sentryguard;

public class SentryguardFrame extends JFrame
{
    private JPanel pnlSentryguard;
    private JTextField txtSentryguard;
  
    public SentryguardFrame()
    {
        pnlSentryguard=new JPanel();
        txtSentryguard=new JTextField();
        txtSentryguard.setPreferredSize(new Dimension(300, 20));
       
        pnlSentryguard.add(new JLabel("HALT! Who goes there?"));
        pnlSentryguard.add(txtSentryguard);
       
        this.add(pnlSentryguard);
    }
}

Moral of the story

It's often the innocuous little keywords that catch us off guard. (heh heh) But this helped hammer home the difference between a constructor and any other method in Object-oriented Programming.

Silly bug. Avoid at all costs!
T___T

No comments:

Post a Comment