Reputation: 33
So I have the following code, and whenever I run the program it gives me an error. It all seems correct to me, but it isn't.
It is supposed to take the value of whatever is in the textfields and move the square to that position, and whenever the user enters a new value it is supposed to change the square to whatever the textfield says it should be. Can anybody fix this, or at least tell me whats wrong? Sorry about the code, it got even more screwed up when I started trying to debug it.
The error is
Exception in thread "main" java.lang.NullPointerException
at com.theDevCorner.Game$OptionPanel.<init>(Game.java:228)
at com.theDevCorner.Game$GridPane.<init>(Game.java:81)
at com.theDevCorner.Game.<init>(Game.java:35)
at com.theDevCorner.Game.main(Game.java:52)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Game extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
private GridPane gridPane;
private DragPanel drag;
public boolean isMouseClicked = false;
public static JMenuBar bar = new JMenuBar();
public int gridY = 1;
public int gridX = 1;
public Game() {
setLayout(new BorderLayout());
OptionPanel options = new OptionPanel();
options.addActionListener(this);
add(options, BorderLayout.NORTH);
gridPane = new GridPane();
gridPane.setBorder(BorderFactory.createLineBorder(Color.white));
add(gridPane);
drag = new DragPanel(options);
drag.setBorder(BorderFactory.createLineBorder(Color.white));
drag.setBackground(new Color(100, 100, 125));
add(drag, BorderLayout.WEST);
}
public static void main(String args[]) {
Game game = new Game();
JFrame frame = new JFrame();
frame.setTitle("Game");
frame.setVisible(true);
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(game);
frame.pack();
frame.setLocationRelativeTo(null);
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(e);
if (e.getActionCommand().equalsIgnoreCase("grid")) {
gridPane.setGridOn(!gridPane.isGridOn());
}
if (e.getActionCommand().equalsIgnoreCase("square")) {
gridPane.setSqaureOn(!gridPane.isSquareOn());
}
if (e.getActionCommand().equalsIgnoreCase("vgrid")) {
gridPane.setVertOn(!gridPane.isVertOn());
}
}
public class GridPane extends JPanel {
public OptionPanel op = new OptionPanel();
private static final long serialVersionUID = 1L;
private boolean gridOn = false;
private boolean squareOn = false;
private boolean vertOn = false;
public int x = 0,y = 0,w = 0,h = 0;
public GridPane() {
setBackground(Color.BLACK);
}
public boolean isGridOn() {
return gridOn;
}
public boolean isSquareOn() {
return squareOn;
}
public boolean isVertOn() {
return vertOn;
}
public void setGridOn(boolean value) {
if (value != gridOn) {
this.gridOn = value;
repaint();
}
}
public void setVertOn(boolean value) {
if (value != vertOn) {
this.vertOn = value;
repaint();
}
}
public void setSqaureOn(boolean value) {
if (value != squareOn) {
this.squareOn = value;
repaint();
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Toolkit tk = Toolkit.getDefaultToolkit();
if (gridOn) {
System.out.println("Grid works");
g.setColor(Color.white);
for (int i = 0; i < tk.getScreenSize().height; i += 64) {
gridY++;
g.drawLine(0, (64 * gridY), tk.getScreenSize().width, (64 * gridY));
}
}
gridY = -1;
gridX = -1;
if (vertOn) {
System.out.println("vert grid works");
g.setColor(Color.white);
for (int ig = 0; ig < tk.getScreenSize().width; ig += 64) {
gridX++;
g.drawLine((64 * gridX), 0, (64 * gridX), tk.getScreenSize().height);
}
}
if (squareOn) {
System.out.println("Square works");
g.setColor(Color.red);
x = Integer.parseInt(op.squareX.getText());
y = Integer.parseInt(op.squareY.getText());
w = Integer.parseInt(op.squareW.getText());
h = Integer.parseInt(op.squareH.getText());
g.fillRect(x,y,w,h);
}
x = 0;
y = 0;
w = 64;
h = 64;
}
}
public class DragPanel extends JPanel {
OptionPanel op;
public DragPanel(OptionPanel op) {
this.op = op;
this.add(this.op.squareButton);
this.op.squareButton.setActionCommand("square");
}
public void addActionListener(ActionListener listener) {
System.out.println(listener);
this.op.squareButton.addActionListener(listener);
}
}
private static class Square {
}
private class OptionPanel extends JPanel {
public JButton grid;
public JButton vgrid;
public JButton squareButton;
public JTextField squareX;
public JTextField squareY;
public JTextField squareW;
public JTextField squareH;
public int x,y,w,h;
public Square square = new Square();
public OptionPanel() {
//Sets the stuff for the panel
setBackground(new Color(155, 0, 255));
setLayout(new GridBagLayout());
//end
//The Show Grid Button Stuff
grid = new JButton("Show Horizontal Grid");
grid.setActionCommand("grid");
//end
//The vertical grid
vgrid = new JButton("Show Vertical Grid");
vgrid.setActionCommand("vgrid");
//end
//The Square tool button stuff
squareButton = new JButton("Sqaure Tool");
//end
squareX = new JTextField(gridPane.x); //<----- THIS IS WHERE THE PROBLEM IS!!!!!
squareY = new JTextField("1",3);
squareW = new JTextField("1",3);
squareH = new JTextField("1",3);
//The gridbagConstraints things
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTH;
//kind of like padding
gbc.weighty = 1;
//sets the positions
gbc.gridx = 0;
gbc.gridy = 0;
//add it
add(grid, gbc);
//changes position for the second button
gbc.gridx = -1;
gbc.gridy = 0;
// adds it
add(vgrid, gbc);
//end
add(squareX, gbc);
add(squareY, gbc);
add(squareW, gbc);
add(squareH, gbc);
}
public void addActionListener(ActionListener listener) {
//adds action listeners
grid.addActionListener(listener);
vgrid.addActionListener(listener);
squareButton.addActionListener(listener);
squareX.addActionListener(listener);
squareY.addActionListener(listener);
squareW.addActionListener(listener);
squareH.addActionListener(listener);
}
}
squareX = new JTextField("0" + gridPane.x,3); //<----- THIS IS WHERE THE PROBLEM IS!!!!!
squareY = new JTextField("0" + gridPane.y,3);
squareW = new JTextField("0" + gridPane.w,3);
squareH = new JTextField("0" + gridPane.h,3);
It seems that the main errors are coming from when I try to do something like this...
Upvotes: 0
Views: 169
Reputation: 347204
You're first NullPointerException
can be fixed by doing something like...
public Game() {
setLayout(new BorderLayout());
gridPane = new GridPane();
gridPane.setBorder(BorderFactory.createLineBorder(Color.white));
OptionPanel options = new OptionPanel();
options.addActionListener(this);
add(options, BorderLayout.NORTH);
add(gridPane);
drag = new DragPanel(options);
drag.setBorder(BorderFactory.createLineBorder(Color.white));
drag.setBackground(new Color(100, 100, 125));
add(drag, BorderLayout.WEST);
}
You're second NullPointerException
is more tricky...
You have a cyclic dependency problem...
Class A is trying to create Class B, which is trying to create class C when class C depends on an instance of B...
To clarify...GridPane
has an instance of OptionPane
, but OptionPane
is depended on the state of GridPane
, which is null
, because GridPane
can't initalise until OptionPane
has been initialised...confused yet...
You can solve this by using a lazy loading approach. That is, not try to insitate the OptionPane
till you need it...
public class GridPane extends JPanel {
public OptionPanel op;
// Other variables...
// Other methods...
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Other paint code...
if (squareOn) {
if (op == null) {
op = new OptionPanel();
}
System.out.println("Square works");
g.setColor(Color.red);
x = Integer.parseInt(op.squareX.getText());
y = Integer.parseInt(op.squareY.getText());
w = Integer.parseInt(op.squareW.getText());
h = Integer.parseInt(op.squareH.getText());
g.fillRect(x, y, w, h);
}
}
}
How ever. I don't think this is going to achieve what you want in the long run, as the state of the OptionPane
will be different between the classes...(GridPane
and OptionPane
won't share the same instance....)
A better solution would be to remove these direct dependencies, so that you can pass some the same reference of some kind of model between GridPane
and OptionPane
, which would allow it to act as the glue between them...
Upvotes: 1
Reputation: 3511
Create the gridPane
before you create the OptionPanel
Your code should be
gridPane = new GridPane();
OptionPanel options = new OptionPanel();
options.addActionListener(this);
add(options, BorderLayout.NORTH);
gridPane.setBorder(BorderFactory.createLineBorder(Color.white));
add(gridPane);
Upvotes: 1
Reputation: 324118
OptionPanel options = new OptionPanel();
options.addActionListener(this);
add(options, BorderLayout.NORTH);
gridPane = new GridPane();
You create the OptionPanel before your create the GridPane, so the gridPane variable is null when your optionPanel tries to access that variable.
Upvotes: 3