使用JPanel CardLayout切换面板时出现视觉故障求助
CardLayout切换面板时视觉重叠故障求助
系统配置:
- MacBook Air(13英寸,2015年初)
- 2.2 GHz 双核Intel Core i7
- 8 GB 1600 MHz DDR3
- Intel HD Graphics 6000 1536 MB
- MacOS Monterey 12.6.7
尝试创建使用CardLayout的JPanel,点击按钮在菜单和论坛面板间切换,功能上能成功切换,但存在视觉故障:切换到新面板后,上一个面板的元素仍会显示并覆盖新面板元素。被覆盖的新面板元素仍可选中,选中后会切换到前景显示。
注:此代码为大型项目的简化示例,实际UI可能与代码不完全匹配,但整个项目中使用CardLayout时均出现类似故障。
Main类
import javax.swing.*; public class Main { public static void main(String[] args) { JFrame frame = new JFrame(); frame.setContentPane(new MainPanel()); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } }
MainPanel类
import javax.swing.*; import java.awt.*; public class MainPanel extends JPanel { private final CardLayout layout = new CardLayout(); private final Menu menuScreen; private final Forum forumScreen; public static final String MENU = "1"; public static final String FORUM = "2"; public MainPanel() { setLayout(layout); menuScreen = new Menu(this); add(menuScreen, MENU); forumScreen = new Forum(this); add(forumScreen, FORUM); layout.show(this, MENU); } public void navigate (String destination) { layout.show(this, destination); switch (destination) { case MENU -> menuScreen.updateUI(); case FORUM -> forumScreen.updateUI(); } this.revalidate(); this.updateUI(); } }
Menu类
import java.awt.*; import java.awt.event.ActionEvent; public class Menu extends Screen { private final MainPanel panel; public Menu(MainPanel panel) { this.panel = panel; Button deleteButton = new Button("Delete"); deleteButton.addActionListener(this::delete); add(deleteButton); Button loadButton = new Button("Load"); loadButton.addActionListener(this::load); add(loadButton); Button forumButton = new Button("Forum"); forumButton.addActionListener(this::toForum); add(forumButton); } private void toForum(ActionEvent actionEvent) { panel.navigate(MainPanel.FORUM); } private void load(ActionEvent actionEvent) { } private void delete(ActionEvent actionEvent) { } }
Forum类
import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; public class Forum extends Screen { private final MainPanel panel; private final JSpinner heightField = new JSpinner(new SpinnerNumberModel(1,1,Integer.MAX_VALUE,1)); private final JSpinner widthField = new JSpinner(new SpinnerNumberModel(1, 1, Integer.MAX_VALUE, 1)); public Forum(MainPanel panel) { this.panel = panel; add(new Label("Forum", Label.CENTER)); add(new Label("Height")); add(heightField); add(new Label("Width")); add(widthField); Button exitButton = new Button("Exit"); exitButton.addActionListener(this::exit); add(exitButton); } private void exit(ActionEvent actionEvent) { panel.navigate(MainPanel.MENU); } }
Screen类
import javax.swing.*; public class Screen extends JPanel { public Screen() { setBorder(BorderFactory.createEmptyBorder(30,30,30,30)); setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); } }
已尝试的修复措施:
- 回退到Java 11版本,问题依旧存在
- 添加加载面板强制UI更新,无论面板是否有元素均无效
- 在代码中调用
revalidate()、updateUI()、repaint()等方法尝试刷新面板,无效果
内容的提问来源于stack exchange,提问作者FMrts
相关产品推荐
相关产品推荐

