在我的程序中,我有一个基于向导的布局。由CardLayout实施。所以有一组扩展JPanel的类。我希望每个面板中都有按钮导航到其他面板。例如,当程序显示第一个面板时,我想要一个按钮来显示面板2.
我厌倦了在主cardlayout面板支架中创建一个方法,所以任何其他类都可以通过这种方法更改显示面板,但是它不起作用并且出现了stackoverflow错误。
这是我的课程
基本框架:
public class Base {
JFrame frame = new JFrame("Panel");
BorderLayout bl = new BorderLayout();
public Base(){
frame.setLayout(bl);
frame.setSize(800, 600);
frame.add(new LeftBar(), BorderLayout.WEST);
frame.add(new MainPanel(), BorderLayout.CENTER);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
new Base();
}
}
保存子面板的主类:
public class MainPanel extends JPanel {
private CardLayout cl = new CardLayout();
private JPanel panelHolder = new JPanel(cl);
public MainPanel() {
NewSession session = new NewSession();
ChooseSource chooseSource = new ChooseSource();
panelHolder.add(session, "Session");
panelHolder.add(chooseSource, "ChooseSource");
cl.show(panelHolder, "Session");
add(panelHolder);
}
public void showPanel(String panelIdentifier){
cl.show(panelHolder, panelIdentifier);
}
}
子面板1
public class NewSession extends JPanel {
MainPanel ob2 = new MainPanel();
public NewSession(){
JButton newSessionBTN = new JButton("Create A New Session");
newSessionBTN.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
System.out.println("HI");
ob2.showPanel("ChooseSource");
}
});
add(newSessionBTN);
}
}
子面板2
public class ChooseSource extends JPanel {
public ChooseSource(){
JLabel showMe = new JLabel("Show Me");
JButton back = new JButton("Back");
//MainPanel ob = new MainPanel();
back.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
//ob.showPanel("start");
}
});
add(back);
add(showMe);
}
}
如您所见,我在每个子面板中都有按钮,这些按钮必须在单击后显示另一个面板。稍后他们也会将数据从一个传输到另一个。
ERROR:
Exception in thread "main" java.lang.StackOverflowError
at java.awt.Component.setFont(Component.java:1899)
at java.awt.Container.setFont(Container.java:1748)
at javax.swing.JComponent.setFont(JComponent.java:2751)
at javax.swing.LookAndFeel.installColorsAndFont(LookAndFeel.java:208)
at javax.swing.plaf.basic.BasicPanelUI.installDefaults(BasicPanelUI.java:66)
at javax.swing.plaf.basic.BasicPanelUI.installUI(BasicPanelUI.java:56)
at javax.swing.JComponent.setUI(JComponent.java:663)
at javax.swing.JPanel.setUI(JPanel.java:153)
at javax.swing.JPanel.updateUI(JPanel.java:126)
at javax.swing.JPanel.<init>(JPanel.java:86)
at javax.swing.JPanel.<init>(JPanel.java:109)
at javax.swing.JPanel.<init>(JPanel.java:117)
at InnerPanels.NewSession.<init>(NewSession.java:21)
at StrongBaseLayout.MainPanel.<init>(MainPanel.java:22)
错误比此更长,重复最后两行。
我怎样才能让它发挥作用?
此外,我还有另一个想法,在页面底部有一个下一个和上一个按钮来切换面板。但我不确定哪一个是最佳的。有什么想法吗?
答案 0 :(得分:4)
每当你看到一个意外的StackOverflowError
总是寻找无意递归的存在,事实上,这正是你在这里所发生的事情,因为MainPanel创建了一个NewSession对象,然后创建一个新的MainPanel对象然后创建一个新的NewSession对象,然后创建一个新的MainPanel对象....无限重复ad或直到堆栈内存(因此堆栈溢出)耗尽。
这里:
public class NewSession extends JPanel {
MainPanel ob2 = new MainPanel(); // *****
在这里:
public class MainPanel extends JPanel {
private CardLayout cl = new CardLayout();
private JPanel panelHolder = new JPanel(cl);
public MainPanel() {
NewSession session = new NewSession(); // *****
不要那样做。而是注意创建每个对象中的一个且仅一个。使用setter方法或构造函数参数来帮助您完成此任务。
例如,更改为:
public class NewSession extends JPanel {
MainPanel ob2;
NewSession(MainPanel mainPanel) {
this.ob2 = mainPanel;
和此:
public class MainPanel extends JPanel {
private CardLayout cl = new CardLayout();
private JPanel panelHolder = new JPanel(cl);
public MainPanel() {
NewSession session = new NewSession(this);
关于:
此外,我还有另一个想法,在页面底部有一个下一个和上一个按钮来切换面板。但我不确定哪一个是最佳的。有什么想法吗?
我不确定你的意思。定义“最佳”。