gpt4 book ai didi

java - Swing:隐藏的 JPanel 添加的尺寸等于 0 时,在变为可见时不会重新计算

转载 作者:太空宇宙 更新时间:2023-11-04 14:35:06 26 4
gpt4 key购买 nike

我的程序有两个面板,一个左侧有 2 个切换按钮,一个右侧显示标签。
选择后,每个按钮都会在右侧区域添加其面板(并将其他按钮设置为不可见)。
取消选择后,他们会将其删除。
在最后一种情况下,我希望其他面板(如果添加到容器中)变得可见。

该代码基本上可以工作,但如果在开始面板上取消选择第二个按钮,则不会出现 1。
我发现面板 1 的尺寸设置为 0,如果我手动设置此尺寸,面板就会出现。不幸的是,这样做布局管理器会停止处理面板尺寸(当我调整窗口或 JSplitPanel 的大小时,这很糟糕!)。

public static void main(final String[] args) {
SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
final JFrame frame = new JFrame();
frame.setSize(800, 800);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

final JPanel buttonsPanel = new JPanel(new FlowLayout());
final JToggleButton btn1 = new JToggleButton("Button 1");
final JToggleButton btn2 = new JToggleButton("Button 2");

buttonsPanel.add(btn1);
buttonsPanel.add(btn2);

final JPanel containerPanel = new JPanel(new BorderLayout());
final JPanel pan1;
final JPanel pan2;
pan1 = new JPanel(new BorderLayout());
pan2 = new JPanel(new BorderLayout());

pan1.add(new JLabel("panel 1"));
pan2.add(new JLabel("panel 2"));

pan1.setBackground(Color.WHITE);
pan2.setBackground(Color.RED);

btn1.addItemListener(new ItemListener() {

@Override
public void itemStateChanged(final ItemEvent e) {
final int state = e.getStateChange();
for (final Component component : containerPanel.getComponents()) {
component.setVisible(false);
}

if (state == ItemEvent.SELECTED) {
containerPanel.add(pan1, BorderLayout.CENTER);
pan1.setVisible(true);
}
else {
containerPanel.remove(pan1);
for (final Component component : containerPanel.getComponents()) {
component.setVisible(true);
break;
}
}
containerPanel.invalidate();
containerPanel.repaint();
}
});

btn2.addItemListener(new ItemListener() {

@Override
public void itemStateChanged(final ItemEvent e) {
final int state = e.getStateChange();
for (final Component component : containerPanel.getComponents()) {
component.setVisible(false);
}

if (state == ItemEvent.SELECTED) {
pan2.setVisible(true);
containerPanel.add(pan2, BorderLayout.CENTER);
}
else {
containerPanel.remove(pan2);
for (final Component component : containerPanel.getComponents()) {
component.setVisible(true);
// component.setSize(containerPanel.getSize());
break;
}
}
containerPanel.revalidate();
containerPanel.repaint();
}
});

btn1.setSelected(true);
btn2.setSelected(true);

final JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
true,
buttonsPanel,
containerPanel);
splitPane.setResizeWeight(0.5);
frame.add(splitPane);
frame.setVisible(true);

}
});

}

如何在不手动设置其他面板尺寸的情况下解决此问题?我知道 CardLayout 是此类需求的解决方案,但不幸的是它不适用于我的问题。

谢谢

编辑:正如评论中所要求的,这里有一个简单的操作序列来解释问题:

我的期望:

  1. 启动应用程序 -> 两个按钮都被选中,两个面板都添加到右侧容器中,只有面板 2 可见(因为按钮 2 是代码最后选择的)。
  2. 取消选择按钮 2 -> 面板 2 从右侧容器中删除,面板 1 切换为可见并显示在右侧容器中。

到底发生了什么:

  1. 与预期相同
  2. 面板 1 未显示,因为其尺寸均为 0,无效和重绘不起作用

最佳答案

"both panels are added to the right container, only panel 2 is visible"

这是不正确的。您正在使用 BorderLayout。问题是每个位置只能有一个组件。第一个被踢出(容器中不再存在),仅保留最后一个添加的,并且您正在尝试将两者添加到 CENTER

因此,您认为通过删除第二个面板,当您调用 setVisible 时第一个面板将自动出现,这是不正确的。该组件实际上需要再次添加。

根据这些新信息,尝试调试您的问题。还可以使用 revalidate() 而不是 invalidate()

"panel 1 is not shown because its dimensions are both 0"

与此无关。 BorderLayout 不关心大小。它将拉伸(stretch)面板以适应。

<小时/>

旁白:这是 CardLayout 的完美情况。不太确定为什么你不能使用它,但也许你应该更深入地研究实现它的可能性

<小时/>

更新

我想这可能就是您正在寻找的。只需切换另一个按钮的状态即可。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test {

public static void main(final String[] args) {
SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
final JFrame frame = new JFrame();
frame.setSize(800, 800);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

final JPanel buttonsPanel = new JPanel(new FlowLayout());
final JToggleButton btn1 = new JToggleButton("Button 1");
final JToggleButton btn2 = new JToggleButton("Button 2");

buttonsPanel.add(btn1);
buttonsPanel.add(btn2);

final JPanel containerPanel = new JPanel(new BorderLayout());
final JPanel pan1;
final JPanel pan2;
pan1 = new JPanel(new BorderLayout());
pan2 = new JPanel(new BorderLayout());

pan1.add(new JLabel("panel 1"));
pan2.add(new JLabel("panel 2"));

pan1.setBackground(Color.WHITE);
pan2.setBackground(Color.RED);

btn1.addItemListener(new ItemListener() {

@Override
public void itemStateChanged(final ItemEvent e) {
final int state = e.getStateChange();

if (state == ItemEvent.SELECTED) {
containerPanel.add(pan1, BorderLayout.CENTER);
containerPanel.remove(pan2);
btn2.getModel().setSelected(false);
} else {
containerPanel.add(pan2, BorderLayout.CENTER);
containerPanel.remove(pan1);
btn2.getModel().setSelected(true);
}
containerPanel.revalidate();
containerPanel.repaint();
}
});

btn2.addItemListener(new ItemListener() {

@Override
public void itemStateChanged(final ItemEvent e) {
final int state = e.getStateChange();
if (state == ItemEvent.SELECTED) {
containerPanel.add(pan2, BorderLayout.CENTER);
containerPanel.remove(pan1);
btn1.getModel().setSelected(false);
} else {
containerPanel.add(pan1, BorderLayout.CENTER);
containerPanel.remove(pan2);
btn1.getModel().setSelected(true);
}

containerPanel.revalidate();
containerPanel.repaint();
}
});

btn1.setSelected(true);
btn2.setSelected(true);

final JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
true,
buttonsPanel,
containerPanel);
splitPane.setResizeWeight(0.5);
frame.add(splitPane);
frame.setVisible(true);

}
});
}
}

关于java - Swing:隐藏的 JPanel 添加的尺寸等于 0 时,在变为可见时不会重新计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25684969/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com