Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Disappearing object  RSS feed

 
Layne Lund
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Okay, my question isn't exactly about how to use Swing or AWT, but this IS a GUI app. Somehow, one of my member variables becomes null when it should actual refer to an object. So...here are some details. I have a plethora of classes in this program:
LifeFrame - extends JFrame and initializes the GUI
LifePanel - extends JPanel and contains all other graphic objects
WorldPanel - I do my custom drawing here. This is where the member reference lives that mysteriously becomes null.
World - Parent class for my Game of Life simulation. This has two subclasses: one for text-only and another for use in a GUI app
GraphicWorld - extends World; Most importantly, this has a paint() and other methods for graphical manipulation
OptionsDialog - so far this dialog allows the user to set the width and height of the "world" grid. I might add other customization features in the future.
When I run the program, the grid paints fine. I can click on it to create "life" and click on the various buttons to run the simulation. This means that the reference to a GraphicWorld in the WorldPanel class actually has an object (i.e. isn't null). When I open the OptionsDialog to change the size of the world, I get a NullPointerException, though.
The biggest mystery is that it used to work perfectly. I'm not sure what I changed recently to cause this problem.
I guess I should also post some of my code so you can get a better idea how I have this put together. I'll try to just post the relevant parts. If anyone wants to see other sections, pleast let me know.
<pre>
// LifeFrame.java
public class LifeFrame
extends CloseableFrame
{
static public void main(String[] args)
{
new LifeFrame().show();
}

public LifeFrame()
{
setTitle("The Game of Life");
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
setBounds(d.width / 4, d.height / 4, d.width / 2, d.height / 2);

p = new LifePanel();
getContentPane().add(new LifePanel());
createMenu();
}
private void createMenu()
{
// snip...
a = new AbstractAction[1];
a[0] = new AbstractAction("Options...")
{
public void actionPerformed(ActionEvent e)
{
options.show();

if(options.getResult() == OptionsDialog.OK)
{
System.out.println("Setting size");
p.setWorldSize(options.getWorldSize());
}
}
};

mb.addMenu("Edit", a);
}

LifePanel p;
OptionsDialog options;
JFileChooser fileDialog;
}
// LifePanel.java
public class LifePanel
extends JPanel
{
// snip several methods
public void setWorldSize(Dimension d)
{
w.setWorldSize(d);
}
private WorldPanel w;
}
// WorldPanel.java
public class WorldPanel
extends JPanel
{
// some methods are omitted
public WorldPanel()
{
genCount = 0;
genLabel = new JLabel("Generation " + genCount);
add(genLabel);

addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
try
{
world.setCell(e.getX(), e.getY());
repaint();
}
catch(IndexOutOfBoundsException ex)
{
}
}
});
}

public void paintComponent(Graphics g)
{
super.paintComponent(g);
if(world == null) newWorld();
world.paint(g, getWidth(), getHeight());
}
public void newWorld(File file)
{
System.out.println("WorldPanel.newWorld()");
world = new GraphicWorld(file);
genCount = 0;
updateLabel();
repaint();
}

public void setWorldSize(Dimension d)
{
System.out.println("Making a new world");
if(world == null) System.out.println("World is null");
world.setSize(d);
System.out.println("world:" + world);
}

private void newWorld()
{
newWorld(10, 10);
}

private void newWorld(int w, int h)
{
world = new GraphicWorld(w, h);
genCount = 0;
updateLabel();
repaint();
}

private void updateLabel()
{
genLabel.setText("Generation " + genCount);
genLabel.repaint();
}
private GraphicWorld world;
}
// GraphicWorld.java
public class GraphicWorld
extends World
{
public void paint(Graphics g, int w, int h)
{
x = (w - width * CELL_SIZE) / 2;
y = (h - height * CELL_SIZE) / 2;
paint(g);
}

public void paint(Graphics g)
{
System.out.println("in paint:" + this);
for(int i = 0; i < width + 1; ++i)
{
int xPos = x + i * CELL_SIZE;
g.drawLine(xPos, y, xPos, y + height * CELL_SIZE);
}

for(int i = 0; i < height + 1; ++i)
{
int yPos = y + i * CELL_SIZE;
g.drawLine(x, yPos, x + width * CELL_SIZE, yPos);
}

for(int i = 0; i < width; ++i)
for(int j = 0; j < height; ++j)
if(board[i][j])
{
int left = x + i * CELL_SIZE;
int top = y + j * CELL_SIZE;
g.fillRect(left, top, CELL_SIZE, CELL_SIZE);
}
}

public void setCell(int x, int y)
throws IndexOutOfBoundsException
{
Point p = new Point(x, y);
Rectangle r = new Rectangle(this.x, this.y,
width * CELL_SIZE,
height * CELL_SIZE);

if(!r.contains(p))
throw new IndexOutOfBoundsException("Coordinates are out of bounds");

int newX = (x - this.x) / CELL_SIZE;
int newY = (y - this.y) / CELL_SIZE;
board[newX][newY] = !board[newX][newY];
}
final private int CELL_SIZE = 10;
private int x, y;
}
</pre>
I apologize for posting so much code. I tried to eliminate any that isn't important to my question. Note that any apparent compiler errors in the code above are a result of editing. My program DOES compile.
I will really appreciate any input about fixing my problem.
Thank you,
Layne
[This message has been edited by Layne Lund (edited December 07, 2001).]
 
Nathan Pruett
Bartender
Posts: 4121
IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can you post the actual output of the NullPointerException you are getting and the line numbers around where it says the exception happens? Does it happen when the OptionsDialog first appears, or after you click 'OK' to apply the changes?

-Nate
 
Layne Lund
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for the response. I'm on a different computer right now, so I can't run my program. I'll try to describe it the best I can, though:
The NullPointerException occurs just after I click on the OK button for the OptionsDialog. In particular it happens during this function:
<pre>
public void setWorldSize(Dimension d)
{
System.out.println("Making a new world");
if(world == null) System.out.println("World is null");
world.setSize(d);
System.out.println("world:" + world);
}
</pre>
The System.out calls are just there for debugging purposes. The if statement prints out its message and world.setSize() throws the exception.
I hope this answers your question.
Layne
 
Manfred Leonhardt
Ranch Hand
Posts: 1492
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Layne,
Since you didn't show us anything about the OptionsDialog class. My first approach would be to get rid of its use and see if the problem still occurs. I would replace the following:

with:

If it still happens I would look at your paintComponent method since it seems to be the only place where you are giving world a value.
Regards,
Manfred.
 
Layne Lund
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for the suggestion. I will try that later today when I get a chance to work on this program.
Layne
 
Layne Lund
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Okay, I changed the code to just pass a hard-coded Dimension object. It still throws the NullPointerException when I call world.setSize() from the WorldPanel.setWorldSize() function:
Exception occurred during event dispatching:
java.lang.NullPointerException
at life.WorldPanel.setWorldSize(WorldPanel.java:84)
at life.LifePanel.setWorldSize(LifePanel.java:113)
at life.LifeFrame$5.actionPerformed(LifeFrame.java:104)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1450)
at javax.swing.AbstractButton$ForwardActionEvents.actionPerformed(AbstractButton.java:1504)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:378)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:250)
at javax.swing.AbstractButton.doClick(AbstractButton.java:279)
at javax.swing.plaf.basic.BasicMenuItemUI$MouseInputHandler.mouseReleased(BasicMenuItemUI.java:886)
at java.awt.Component.processMouseEvent(Component.java:3717)
at java.awt.Component.processEvent(Component.java:3546)
at java.awt.Container.processEvent(Container.java:1164)
at java.awt.Component.dispatchEventImpl(Component.java:2595)
at java.awt.Container.dispatchEventImpl(Container.java:1213)
at java.awt.Component.dispatchEvent(Component.java:2499)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:2451)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:2216)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:2125)
at java.awt.Container.dispatchEventImpl(Container.java:1200)
at java.awt.Window.dispatchEventImpl(Window.java:912)
at java.awt.Component.dispatchEvent(Component.java:2499)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:319)
at java.awt.EventDispatchThread.pumpOneEvent(EventDispatchThread.java:103)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:84)
The strange thing is that when I click on the grid, it draws the "world" just fine. I've even printed it out, so there IS an object there. It's not null. Somehow the reference is set to null, though. I searched my code to make sure I didn't have an = instead of an == for comparisons, but all of those were fine. I'm stumped why the object all of a sudden disappears. I'd be grateful if anyone else can point out where the problem might be.
Thank you
Layne
 
Nathan Pruett
Bartender
Posts: 4121
IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This should fix your problems... in WorldPanel, replace this :


with this :



-Nate
 
Layne Lund
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, that WOULD fix the problem. However, the world reference SHOULDN'T be null at the moment this function gets called. In fact it paints just fine, which means that it isn't null just prior to the call to setSize(). I'm frustrated with this, but I haven't had a chance to work on it since last weekend. I'm trying to figure out why world all of a sudden becomes null? It could mean that other bugs will appear that I haven't discovered yet.
Thank you for your input. If I can't find the real problem, I will definitely use your suggestion.
Layne
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!