简体   繁体   中英

Java Object values not consistent

I couldn't find any other solutions to my problem because I'm unsure of how to describe it in few enough words.

When I assign activeList , which is a field of currentActiveList a randomly generated Rectangle in the ActiveList class it receives the value just fine.

public class ActiveList {
    Rectangle[] activeList = new Rectangle[10];

    public ActiveList() {
        for(int i = 0; i < activeList.length; i++)
            activeList[i] = null;
    }

    public void addToList(Rectangle x) {
        for(int i = 0; i < this.activeList.length; i++) {
            if(this.activeList[i] == null) {
                this.activeList[i] = x;
                i = this.activeList.length+1;
            }

            else
                this.activeList[activeList.length-1] = x;
        }
    }

    public Rectangle[] getActiveList() {
        return this.activeList;
    }

    public int getLength() {
        //System.out.print(this.activeList.length);
        return this.activeList.length;
    }

    public void deleteFromList(int x) {
        this.activeList[x] = null;
    }

    public Rectangle getFromList(int x) {
        Rectangle retVal = this.activeList[x];
        //System.out.println("Returning getFromList(int x): " +retVal);
        return retVal;
    }

    public void genRandomRectangle() {
        Random randomNumberGenerator = new Random();
        double[] pointVal = new double[4];
        double randomInt = randomNumberGenerator.nextInt(400-10);
        pointVal[0] = randomInt;
        randomInt = randomNumberGenerator.nextInt(400-10);
        pointVal[1] = randomInt;
        randomInt = randomNumberGenerator.nextInt((int) (400-pointVal[0]));
        if(randomInt < 5) {
            randomInt = randomInt+pointVal[0]+5;
        }

        else
            pointVal[2] = randomInt+pointVal[0];

        randomInt = randomNumberGenerator.nextInt((int) (400-pointVal[1]));
        if(randomInt < 5) {
            randomInt = randomInt+pointVal[1]+5;
        }

        else
            pointVal[3] = randomInt+pointVal[1];

        Rectangle newRandom = new Rectangle(pointVal[0], pointVal[1], pointVal[2], pointVal[3]);
        //System.out.println(pointVal[0]);
        //System.out.println(pointVal[1]);
        //System.out.println(pointVal[2]);
        //System.out.println(pointVal[3]);
        System.out.println("New Random: " +newRandom);

        addToList(newRandom);
    }
}

However, when I try to use those values in my main class GraphicGen , the currentActiveList returns null values for all of its indexes.

public class GraphicGen extends JPanel {
    ActiveList currentActiveList = new ActiveList();
    public static int gridSpaceX = 400;
    public static int gridSpaceY = 400;
    static JFrame mainFrame = new JFrame();

    protected void paintComponent(Graphics g) {
        //super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        //int w = getWidth();
        //int h = getHeight();
        // Draw ordinate.
        //g2.draw(new Line2D.Double(PAD, PAD, PAD, h-PAD));
        // Draw abcissa.
        //g2.draw(new Line2D.Double(PAD, h-PAD, w-PAD, h-PAD));
        //double xInc = (double)(w - 2*PAD)/(data.length-1);
        //double scale = (double)(h - 2*PAD)/maxValue();
        // Mark data points.
        //g2.setPaint(Color.red);

        double[] coords = new double[4];
        //g2.fill(new Ellipse2D.Double(coords[0], coords[1], 4, 4));
        //g2.fill(new Ellipse2D.Double(coords[2], coords[3], 4, 4));
        //g2.fill(new Ellipse2D.Double(100, 100, 4, 4));
        System.out.println("Graphic Gen Active List Obj: " +currentActiveList);
        System.out.println("Ya drew a new Main GUI!");
        System.out.println("currentActiveList.getActiveList(): " +currentActiveList.getActiveList());
        for(int i = 0; i < currentActiveList.getLength(); i++) {
            //System.out.println("currentActiveList.getFromList(i): "+currentActiveList.getFromList(i));
            //System.out.println("Graphic Gen Active List Obj: " +currentActiveList);
            //System.out.println(activeList.getFromList(i).getTopLeftX());
            if(currentActiveList.getFromList(i) != null) {
                coords[0] = currentActiveList.getFromList(i).getTopLeftX();
                System.out.println(coords[0]);
                coords[1] = currentActiveList.getFromList(i).getTopLeftY();
                System.out.println(coords[1]);
                coords[2] = currentActiveList.getFromList(i).getBottomRightX();
                System.out.println(coords[2]);
                coords[3] = currentActiveList.getFromList(i).getBottomRightY();
                System.out.println(coords[3]);
                g2.draw(new Line2D.Double(coords[0], coords[1], coords[2], coords[1]));
                g2.draw(new Line2D.Double(coords[0], coords[1], coords[0], coords[3]));
                g2.draw(new Line2D.Double(coords[2], coords[1], coords[2], coords[3]));
                g2.draw(new Line2D.Double(coords[0], coords[3], coords[2], coords[3]));
            }
        }

        /*double x = 50;
        double y = 50;
        g2.fill(new Ellipse2D.Double(x, y, 4, 4));*/
        /*for(int i = 0; i < data.length; i++) {
            double x = PAD + i*xInc;
            double y = h - PAD - scale*data[i];
            g2.fill(new Ellipse2D.Double(x-2, y-2, 4, 4));
        }*/
    }

    /*private int maxValue() {
        int max = data[0];
        for(int i = 0; i < data.length; i++) {
            if(data[i] > max)
                max = data[i];
        }
        return max;
    }*/

    public void callRepaintOnMain() {
        mainFrame.repaint();
    }

    public void callGenRandom() {
        currentActiveList.genRandomRectangle();
    }

    public static void main(String[] args) {
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.add(new GraphicGen());
        mainFrame.setSize(gridSpaceX, gridSpaceY);
        ButtonPrompt buttonPrompter = new ButtonPrompt();
        mainFrame.setLocation(200,200);
        mainFrame.setVisible(true);
    }
}

The random generator method is called by the action listener.

public class ButtonPrompt extends GraphicGen {

    ActionListener actionListenerRandom = new ActionListener() {
        public void actionPerformed(ActionEvent actionEvent) {
          //currentActiveList.genRandomRectangle();
            callGenRandom();
            callRepaintOnMain();
        }
    };

    JButton randomBtn = new JButton("Add Random Rectangle");        
    JButton inputCoordinates = new JButton("Input Rectangle Coordinates");

    public ButtonPrompt() {
        JFrame f = new JFrame("Add Rectangles");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        BoxLayout boxLayout = new BoxLayout(f.getContentPane(), BoxLayout.Y_AXIS);
        f.setLayout(boxLayout);

        randomBtn.addActionListener(actionListenerRandom);

        f.setSize(200, 200);
        f.setLocation(600, 200);
        f.setVisible(true);
        f.add(randomBtn);
        f.add(inputCoordinates);
        f.pack();
    }
}

Is this a scoping or referencing problem? I'm really at a loss here.

Your actual problem is quite unclear, but just reading the first two methods is enough to find what, I suppose, is a bug:

public ActiveList() {
    for(int i = 0; i < activeList.length; i++)
        activeList[i] = null;
}

the above code is completely useless. The default value of an element of an array of objects is null. So the loop assigns null to a variable wich is already null.

public void addToList(Rectangle x) {
    for(int i = 0; i < this.activeList.length; i++) {
        if(this.activeList[i] == null) {
            this.activeList[i] = x;
            i = this.activeList.length+1;
        }

        else
            this.activeList[activeList.length-1] = x;
    }
}

If your list only contains null, the rectangle will be stored at index 0, and the loop will stop. For all the susequent calls to this method, the loop will find that the element at index 0 is not null, and will thus store x at the last index of the array, and then at the first non-null index.

I don't know exactly what you're trying to achieve, and what the actual problem is, but you should probably forget about implementing your own list based on an array, and use an ArrayList instead.

Here:

public static void main(String[] args) {
    ...
    mainFrame.add(new GraphicGen());
    ...
    ButtonPrompt buttonPrompter = new ButtonPrompt();
}

ButtonPrompt extends GraphicGen , which is a JPanel . In ButtonPrompt 's constructor, you created a JFrame and added two JButton s to it.

So when your app starts, there will be two JFrames on the screen, one is mainFrame which contains a GraphicGen , the other is buttonPrompter which contains two buttons.

When you click on the button, the actionPerformed() is called and it's actually calling the callGenRandom() of the buttonPrompter -- if the random generation logic is correct, the generated Rectangles are added to buttonPrompter . But you didn't add this buttonPrompter to any one of the JFrame s, you won't see it.


What you may want:

ButtonPrompt doesn't extend GraphicGen , instead, give ButtonPrompt a reference of the GraphicGen you added to the mainFrame .

public class ButtonPrompt extends GraphicGen {
    JButton randomBtn = new JButton("Add Random Rectangle");        
    JButton inputCoordinates = new JButton("Input Rectangle Coordinates");
    final GraphicGen gg;

    public ButtonPrompt(GraphicGen gg) {
        this.gg = gg;
        ......

        ActionListener actionListenerRandom = new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                gg.callGenRandom();
                gg.callRepaintOnMain();
            }
        };

        randomBtn.addActionListener(actionListenerRandom);

        ......
    }
}

and in your main() :

public static void main(String[] args) {
    ...
    GraphicGen gg = new GraphicGen();
    mainFrame.add(gg);
    ...
    ButtonPrompt buttonPrompter = new ButtonPrompt(gg);
}

What's more, the code has other problems.

For example, GraphicGen is a JPanel , main class and it has a field of a JFrame which actually contains the GraphicGen instance when app runs -- this looks bad. I don't know much of Swing... Is it a must to call the containing JFrame 's repaint() instead of just calling the JPanel 's repaint() , if it has?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM