0

所以我有以下代码,每当我运行程序时,它都会给我一个错误。这一切对我来说似乎都是正确的,但事实并非如此。

它应该采用文本字段中的任何值并将正方形移动到该位置,并且每当用户输入新值时,它应该将正方形更改为文本字段所说的任何值。任何人都可以解决这个问题,或者至少告诉我有什么问题吗?对不起代码,当我开始尝试调试它时,它变得更加糟糕。

错误是

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);

当我尝试做这样的事情时,主要错误似乎来自......

4

3 回答 3

3
OptionPanel options = new OptionPanel();
options.addActionListener(this);
add(options, BorderLayout.NORTH);
gridPane = new GridPane();

您在创建 GridPane 之前创建了 OptionPanel,因此当您的 optionPanel 尝试访问该变量时,gridPane 变量为空。

于 2013-05-12T05:27:36.570 回答
1

你首先NullPointerException可以通过做类似的事情来解决......

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);
}

你是第二个NullPointerException更棘手...

你有一个循环依赖问题......

A类正在尝试创建B类,当C类依赖于B的实例时,B类正在尝试创建C类...

澄清一下...GridPane有一个实例OptionPane,但OptionPane取决于 的状态GridPane,即null,因为在初始化GridPane之前无法OptionPane初始化...混淆了...

您可以通过使用延迟加载方法来解决此问题。也就是说,不要试图启动OptionPane直到你需要它......

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);
        }
    }
}

然而。从长远来看,我认为这不会达到你想要的效果,因为OptionPane类之间的状态会有所不同......(GridPane并且OptionPane不会共享相同的实例......)

GridPane更好的解决方案是删除这些直接依赖关系,以便您可以在和之间传递某种模型的相同引用OptionPane,这将允许它充当它们之间的粘合剂......

于 2013-05-12T07:23:43.373 回答
1

在创建gridPane之前创建OptionPanel 你的代码应该是

gridPane = new GridPane();
OptionPanel options = new OptionPanel();
options.addActionListener(this);
add(options, BorderLayout.NORTH);
gridPane.setBorder(BorderFactory.createLineBorder(Color.white));
add(gridPane);
于 2013-05-12T06:33:56.933 回答