JPanel 删除组件并添加一个新组件抵消新组件
JPanel removing component and adding a new one offsets the new component
我正在开发一个求解器,通过生成地形图来说明 Nelder Mead 算法。地图由 JPanel 组件直观地表示(我知道地图生成的效果不如我希望的那样干净,但这是另一个问题)。我拥有的其中一个按钮应该通过从容器 JPanel 中删除旧组件并添加新组件来生成新地图;然而,虽然它确实绘制了一个新地图,但它显示它偏移了组件高度的一半。以下是重生被击中前后的图像。
初始地图图片
点击重新生成按钮后,新地图显示在 y 偏移处
这是我的主要代码(canvas 对象扩展了 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();
});
}
如果有人能为我指出正确的方向,我将不胜感激,谢谢。
我能够将 camickr 关于 reset()
方法的提示应用到我的代码中,这解决了我的问题。建议是让所有组件编辑发生在组件 class 中,而不是尝试修改组件在 JPanel 中的存在方式。我还更改了 canvas 对象以扩展 JComponent。对于以后遇到此问题的任何人,这里是解决方案:
regenerateButton.addActionListener(event -> {
running = false;
canvas.regenerate(CANVAS_WIDTH, CANVAS_HEIGHT, TILE_WIDTH, TILE_HEIGHT, ELEVATION_MAX, ELEVATION_MIN);
});
[编辑] regenerate()
修改 canvas 的 HeightMap
对象并调用 this.repaint()
我正在开发一个求解器,通过生成地形图来说明 Nelder Mead 算法。地图由 JPanel 组件直观地表示(我知道地图生成的效果不如我希望的那样干净,但这是另一个问题)。我拥有的其中一个按钮应该通过从容器 JPanel 中删除旧组件并添加新组件来生成新地图;然而,虽然它确实绘制了一个新地图,但它显示它偏移了组件高度的一半。以下是重生被击中前后的图像。
初始地图图片
点击重新生成按钮后,新地图显示在 y 偏移处
这是我的主要代码(canvas 对象扩展了 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();
});
}
如果有人能为我指出正确的方向,我将不胜感激,谢谢。
我能够将 camickr 关于 reset()
方法的提示应用到我的代码中,这解决了我的问题。建议是让所有组件编辑发生在组件 class 中,而不是尝试修改组件在 JPanel 中的存在方式。我还更改了 canvas 对象以扩展 JComponent。对于以后遇到此问题的任何人,这里是解决方案:
regenerateButton.addActionListener(event -> {
running = false;
canvas.regenerate(CANVAS_WIDTH, CANVAS_HEIGHT, TILE_WIDTH, TILE_HEIGHT, ELEVATION_MAX, ELEVATION_MIN);
});
[编辑] regenerate()
修改 canvas 的 HeightMap
对象并调用 this.repaint()