java 在一个框架中使用多个面板

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16214808/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 22:15:27  来源:igfitidea点击:

Working with multiple panels in one frame

javaswinglayoutframesmultiple-instances

提问by user2319690

I have a problem where i want a program to switch between multiple panels in a same frame. The problems I am encountering are that i can't set the layout when the panels switch and after the switch content is lowering pixel by pixel. Here is my code.

我有一个问题,我想要一个程序在同一帧中的多个面板之间切换。我遇到的问题是,当面板切换时以及切换内容逐像素降低后,我无法设置布局。这是我的代码。

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import javax.swing.JFrame;

public class Main {

    public static boolean logged_in = false;

    public static int width = 200, height = 400;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Dimension d = new Dimension(width, height);
                    First frame = new First();
                         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setSize(d);
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                    frame.setResizable(true);
                    frame.setLayout(new FlowLayout());  
                } catch (Exception e) { 
                    e.printStackTrace();    
                }
            }
        });
    }
}

and here are the two classes that hold frames.

这是保存帧的两个类。

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;


public class First extends JFrame {

    JPanel contentPane;
    private JButton button_1;
    private JTextField text;

    public First(){

        contentPane = new JPanel();
        setContentPane(contentPane);

        button_1 = new JButton("Second frame");
        button_1.setVisible(true);
        text = new JTextField(20);
        text.setVisible(true);

        contentPane.add(button_1);
        contentPane.add(text);

        thehandler handler = new thehandler();

        button_1.addActionListener(handler);
    }

    private class thehandler implements ActionListener {

        public void actionPerformed(ActionEvent event) {

            if (event.getSource() == button_1) {
                contentPane.removeAll();
                contentPane.invalidate();
                Second frame = new Second();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLocationRelativeTo(null);
                frame.setResizable(true);
                frame.setLayout(new FlowLayout());
                frame.contentPane.setVisible(true);
                contentPane.add(frame.contentPane);
                ((JPanel) contentPane).revalidate();
                contentPane.setSize(200, 400);
                contentPane.repaint();
            }
        }
    }
}

and the second one

第二个

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;


public class Second extends JFrame {

    JPanel contentPane;
    private JButton button_1;
    private JTextField text;

    public Second(){

        contentPane = new JPanel();
        setContentPane(contentPane);

        button_1 = new JButton("First frame");
        button_1.setVisible(true);
        text = new JTextField(20);
        text.setVisible(true);

        contentPane.add(button_1);
        contentPane.add(text);

        thehandler handler = new thehandler();

        button_1.addActionListener(handler);
    }

    private class thehandler implements ActionListener {

        public void actionPerformed(ActionEvent event) {

            if (event.getSource() == button_1) {
                contentPane.removeAll();
                contentPane.invalidate();
                First frame = new First();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLocationRelativeTo(null);
                frame.setResizable(true);
                frame.setLayout(new FlowLayout());
                frame.contentPane.setVisible(true);
                contentPane.add(frame.contentPane);
                ((JPanel) contentPane).revalidate();
                contentPane.setSize(200, 400);
                contentPane.repaint();
            }
        }
    }
}

Any help is appreciated. Please keep in mind I am not so good with java GUI. Ty.

任何帮助表示赞赏。请记住,我对 Java GUI 不太擅长。泰。

EDITAfter a lot of time searching for an answer i got one. It probably isn't perfect but i will post it for future reference or if anyone else needs this solution. Here is the code.

编辑经过大量时间寻找答案后,我得到了一个答案。它可能并不完美,但我会将其发布以供将来参考,或者如果其他人需要此解决方案。这是代码。

Main frame that holds panels:

固定面板的主框架:

import javax.swing.JFrame;
import javax.swing.JPanel;

public class MainFrame extends JFrame {

    public static JPanel main_panel;
    private static FirstFrame first;

    public MainFrame(){

        setLayout(null);    
        setSize(400, 400);
        setLocationRelativeTo(null);
        setResizable(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        main_panel = new JPanel();
        main_panel.setBounds(0, 0, 400, 400);
        add(main_panel);

        main_panel.invalidate();
        main_panel.removeAll();

        first = new FirstFrame();
        main_panel.add(first);
        main_panel.revalidate();
        main_panel.repaint();
    }

    public static void main(String[] args) {
        MainFrame frame = new MainFrame();
        frame.setVisible(true);
    }
}

First panel:

第一个面板:

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;

public class FirstFrame extends JPanel {

    private JButton button;

    public FirstFrame() {

        JPanel panel = new JPanel();

        panel.setPreferredSize(new Dimension(400, 400));
        panel.setLayout(null);

        button = new JButton("First");
        button.setBounds(20, 20, 200, 40);
        button.setVisible(true);

        thehandler handler = new thehandler();

        button.addActionListener(handler);

        panel.add(button);

        add(panel);
        revalidate();
        repaint();
    }
    private class thehandler implements ActionListener {

        public void actionPerformed(ActionEvent event) {
            if (event.getSource() == button) {
                MainFrame.main_panel.invalidate();
                MainFrame.main_panel.removeAll();
                SecondFrame frame = new SecondFrame();
                MainFrame.main_panel.add(frame);
                MainFrame.main_panel.revalidate();
                MainFrame.main_panel.repaint();
            }
        }
    }
}

Second:

第二:

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;

public class SecondFrame extends JPanel {

    private JButton button;

    public SecondFrame() {
        JPanel panel = new JPanel();

        panel.setPreferredSize(new Dimension(400, 400));
        panel.setLayout(null);

        button = new JButton("Second");
        button.setBounds(20, 20, 200, 40);
        button.setVisible(true);

        thehandler handler = new thehandler();

        button.addActionListener(handler);

        panel.add(button);

        add(panel);
        revalidate();
        repaint();
    }
    private class thehandler implements ActionListener {

        public void actionPerformed(ActionEvent event) {
            if (event.getSource() == button) {
                MainFrame.main_panel.invalidate();
                MainFrame.main_panel.removeAll();
                ThirdFrame frame = new ThirdFrame();
                MainFrame.main_panel.add(frame);
                MainFrame.main_panel.revalidate();
                MainFrame.main_panel.repaint();
            }
        }
    }
}

And third:

第三:

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;

public class ThirdFrame extends JPanel {

    private JButton button;

    public ThirdFrame() {
        JPanel panel = new JPanel();

        panel.setPreferredSize(new Dimension(400, 400));
        panel.setLayout(null);

        button = new JButton("Third");
        button.setBounds(20, 20, 200, 40);
        button.setVisible(true);

        thehandler handler = new thehandler();

        button.addActionListener(handler);

        panel.add(button);

        add(panel);
        revalidate();
        repaint();
    }
    private class thehandler implements ActionListener {

        public void actionPerformed(ActionEvent event) {
            if (event.getSource() == button) {
                MainFrame.main_panel.invalidate();
                MainFrame.main_panel.removeAll();
                FirstFrame frame = new FirstFrame();
                MainFrame.main_panel.add(frame);
                MainFrame.main_panel.revalidate();
                MainFrame.main_panel.repaint();
            }
        }
    }
}

As you can see you can switch from panel 1 ->2 ->3 and back to 1 but not the second one. Ty all for your answers they were helpful. Any further suggestions are welcome.

如您所见,您可以从面板 1 ->2 ->3 切换回 1,但不能切换到第二个面板。Ty all 对于您的回答,他们很有帮助。欢迎任何进一步的建议。

回答by Sridhar

The solution is to use card layout. It is very simple,

解决方案是使用卡片布局。这很简单,

  1. create a panel with card layout in which other children panels added with unique string reference.
  2. invoke showmethod of CardLayout to pick a panel to take in front (docs)
  1. 创建一个带有卡片布局的面板,其中其他子面板添加了唯一的字符串引用。
  2. 调用showCardLayout 的方法来选择要放在前面的面板 ( docs)

Check the following code.

检查以下代码。

  final JPanel mainPanel=new JPanel();
    JPanel panelOne=new JPanel();
    JPanel panelTwo=new JPanel();
    final CardLayout card=new CardLayout();
    mainPanel.setLayout(card);
    mainPanel.add(panelOne, "one"); // id one refers panelOne
    mainPanel.add(panelTwo, "two"); // id two refers panelTwo

    panelOne.add(new JLabel("first panel"));
    JButton btn1=new JButton("Show second");
    panelOne.add(btn1);
    btn1.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent ae){
    card.show(mainPanel, "two"); // shows panelTwo
    }});

  panelTwo.add(new JLabel("second panel"));
    JButton btn2=new JButton("Show First");
    panelTwo.add(btn2);
    btn2.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent ae){
    card.show(mainPanel, "one"); // shows panelOne
    }});