Home > Back-end >  JPanel removing component and adding a new one offsets the new component
JPanel removing component and adding a new one offsets the new component

Time:01-27

I am working on a solver to illustrate the Nelder Mead algorithm by generating a topographical map. The map is represented visually by a JPanel component (I know the map is not generating as cleanly as I'd like, but that's another issue). One of the buttons I have is supposed to generate a new map by removing the old component from the container JPanel and adding a new component; however, while it does draw a new map, it displays it offset by half of the component's height. Following are before and after images of what happens when Regenerate is hit.

Original map

The initial map image

After Regenerate button is hit

After the Regenerate button is hit, the new map is displayed at a y offset

Here is my main code (The canvas object extends JPanel):

public void init() {
        frame = new JFrame("Nelder Mead");
        container = new JPanel();

        solveButton = new JButton("Solve");
        solveButton.setToolTipText("Solves the given Height Map using the Nelder Mead algorithm.");
        resetButton = new JButton("Reset");
        resetButton.setToolTipText("Resets the simplex to its initial position.");
        reconfigureButton = new JButton("Reconfigure");
        reconfigureButton.setToolTipText("Reconfigures the simplex's initial position.");
        regenerateButton = new JButton("Regenerate");
        regenerateButton.setToolTipText("Generates a new Height Map and a new simplex.");

        buttonPanel = new JPanel();
        buttonPanel.setBackground(Color.WHITE);
        buttonPanel.setPreferredSize(BUTTON_SIZE);
        buttonPanel.add(solveButton);
        buttonPanel.add(resetButton);
        buttonPanel.add(reconfigureButton);
        buttonPanel.add(regenerateButton);

        canvas = new Canvas(new HeightMap(CANVAS_WIDTH, CANVAS_HEIGHT, TILE_WIDTH, TILE_HEIGHT, ELEVATION_MAX, ELEVATION_MIN));
        canvas.setPreferredSize(CANVAS_SIZE);

        container.setLayout(new BoxLayout(container, BoxLayout.PAGE_AXIS));
        container.add(buttonPanel);
        container.add(canvas);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.add(container);
        frame.pack();
        frame.setVisible(true);
    }

    public void run() {
        init();

        regenerateButton.addActionListener(event -> {
            running = false;
            container.remove(canvas);
            canvas = new Canvas(new HeightMap(CANVAS_WIDTH, CANVAS_HEIGHT, TILE_WIDTH, TILE_HEIGHT, ELEVATION_MAX, ELEVATION_MIN));
            container.add(canvas);
            frame.revalidate();
        });
    }

If anyone is able to point me in the right direction, that is appreciated, thanks.

CodePudding user response:

I was able to apply camickr's hint about a reset() method to my code, which solved my issue. The suggestion was to have all the component editing occur within the component class instead of trying to modify how the component exists in the JPanel. I also changed the canvas object to extend JComponent. For anyone that encounters this problem in the future, here is the solution:

regenerateButton.addActionListener(event -> {
            running = false;
            canvas.regenerate(CANVAS_WIDTH, CANVAS_HEIGHT, TILE_WIDTH, TILE_HEIGHT, ELEVATION_MAX, ELEVATION_MIN);
        });

[Edit] regenerate() modifies the canvas's HeightMap object and calls this.repaint()

  •  Tags:  
  • Related