简体   繁体   English

一个jframe中的多个jpanel

[英]Multiple jpanels in a jframe

I am currently trying to make a little app using a jframe that has multiple jpanels. 我目前正在尝试使用具有多个jpanel的jframe制作一个小应用程序。 I have a couple questions about this. 我对此有两个问题。

  1. There has to be a cleaner way of making an app with 16 different panels than having it all inside one class. 与拥有全部16个不同面板相比,必须有一种更清洁的方法来制作具有16个不同面板的应用程序。 What are some other options. 还有其他一些选择。

  2. Currently I only have 3 panels. 目前我只有3个面板。 I haven't gone any further because 2 of the panels aren't reflecting my changes. 我没有做进一步的事情,因为其中两个面板没有反映我的更改。 They are the two panels I call using 它们是我使用的两个面板

removeAll();
    add();
    revalidate();
    repaint();

What would be causing the other panels I am calling to be blank? 是什么导致我要呼叫的其他面板空白?

Here is a look at what I have, any advice would be great. 这是我所拥有的,任何建议都很好。 Thanks 谢谢

public class Jframetest extends JFrame {

    private JPanel Home;
    private JPanel masslog;
    private JPanel DEH;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Jframetest frame = new Jframetest();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public Jframetest() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setBounds(100, 100, 618, 373);
        Home = new JPanel();
        masslog = new JPanel();
        DEH = new JPanel();

        Home.setBackground(new Color(255, 250, 250));
        Home.setBorder(new LineBorder(Color.DARK_GRAY, 1, true));
        DEH.setBackground(new Color(255, 250, 250));
        DEH.setBorder(new LineBorder(Color.DARK_GRAY, 1, true));
        masslog.setBackground(new Color(255, 250, 250));
        masslog.setBorder(new LineBorder(Color.DARK_GRAY, 1, true));
        setContentPane(Home);
        Home.setLayout(null);

        JButton dehbutton = new JButton("Sign in");
        dehbutton.setFont(new Font("Tahoma", Font.PLAIN, 14));
        dehbutton.setForeground(new Color(0, 0, 0));
        dehbutton.setBackground(UIManager.getColor("Menu.selectionBackground"));
        DEH.add(dehbutton);

        JButton btnNewButton = new JButton("Data Entry login");
        btnNewButton.setFont(new Font("Tahoma", Font.PLAIN, 14));
        btnNewButton.setForeground(new Color(0, 0, 0));
        btnNewButton.setBackground(UIManager.getColor("Menu.selectionBackground"));

        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                Home.removeAll();
                Home.add(DEH);
                Home.revalidate();
                Home.repaint();

                // JOptionPane.showMessageDialog(null, "Username/Password incorrect");
            }
        });
        btnNewButton.setBounds(44, 214, 204, 61);
        Home.add(btnNewButton);

        final JButton button = new JButton("Manager and Associate login");
        button.setFont(new Font("Tahoma", Font.PLAIN, 14));
        button.setBackground(UIManager.getColor("EditorPane.selectionBackground"));
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Home.removeAll();
                Home.add(masslog);
                Home.revalidate();
                Home.repaint();

            }
        });
        button.setBounds(340, 214, 204, 61);
        Home.add(button);

        JTextPane txtpnEmployeeLogin = new JTextPane();
        txtpnEmployeeLogin.setForeground(Color.DARK_GRAY);
        txtpnEmployeeLogin.setBackground(Color.WHITE);
        txtpnEmployeeLogin.setFont(new Font("Tahoma", Font.PLAIN, 34));
        txtpnEmployeeLogin.setText("Employee Login");
        txtpnEmployeeLogin.setBounds(181, 123, 260, 52);
        Home.add(txtpnEmployeeLogin);

        JLabel lblNewLabel = new JLabel("New label");
        lblNewLabel.setIcon(new ImageIcon("C:\\Users\\Will and April\\Downloads\\your-logo-here.jpg"));
        lblNewLabel.setBounds(427, 11, 165, 67);
        Home.add(lblNewLabel);

    }

}

Your mistake is using a null layout, revalidate , invalidate and validate will no longer have any significant meaning, because they are related to supporting the layout management API. 您的错误是使用null布局, revalidateinvalidatevalidate将不再具有任何重要意义,因为它们与支持布局管理API有关。

Because you've removed the layout manager, you panels no longer have anything to tell them what size or location that they should appear at, meaning when you add a new component, it has a size of 0x0 and position of 0x0 因为您已经删除了布局管理器,所以面板不再有任何内容可以告诉他们应显示的大小或位置,这意味着添加新组件时,其大小为0x0,位置为0x0

Update with example 用示例更新

There are many reasons why you should take advantage of the layout manager API, including automatic handling of differences between how fonts are rendered on different systems, dynamic and resizable layouts, differences in screen resolution and DPI to name a few. 充分利用布局管理器API的原因很多,包括自动处理字体在不同系统上的呈现方式之间的差异,动态和可调整大小的布局,屏幕分辨率和DPI的差异等。

It will also encourage you to separate your UI into areas of responsibility instead of trying to dump your entire UI code into a single class (yes, I've seen this done, yes, I've spent most of my career cleaning up after people who do this...) 它还会鼓励您将UI划分为职责范围,而不是尝试将整个UI代码转储到一个类中(是的,我已经看过了,是的,我的大部分职业生涯都是在谁做的...)

在此处输入图片说明在此处输入图片说明在此处输入图片说明

This example makes use of CardLayout and GridBagLayout , but you should take the time to become farmiluar with the some of the others avaiable in the default JDK 此示例使用了CardLayoutGridBagLayout ,但是您应该花些时间来熟悉默认JDK中可用的其他一些方法

import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

public class FrameTest extends JFrame {
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    FrameTest frame = new FrameTest();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public FrameTest() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final CardLayout layout = new CardLayout();
        setLayout(layout);
        LoginPane loginPane = new LoginPane();
        add(loginPane, "login");
        add(new NewLoginPane(), "newLogin");
        add(new ManagerLoginPane(), "managerLogin");

        loginPane.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String command = e.getActionCommand();
                System.out.println(command);
                if ("new".equals(command)) {
                    layout.show(getContentPane(), "newLogin");
                } else if ("manager".equals(command)) {
                    layout.show(getContentPane(), "managerLogin");
                }
            }
        });

        layout.show(getContentPane(), "layout");

        pack();
        setLocationRelativeTo(null);
    }

    public class LoginPane extends JPanel {

        private JTextField userName;
        private JButton newButton;
        private JButton managerButton;

        public LoginPane() {
            setBorder(new EmptyBorder(20, 20, 20, 20));
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.gridwidth = 2;
            gbc.weightx = 1;
            gbc.insets = new Insets(10, 10, 10, 10);

            userName = new JTextField(10);
            userName.setFont(new Font("Tahoma", Font.PLAIN, 34));
            add(userName, gbc);

            gbc.gridx = 0;
            gbc.gridy = 1;
            gbc.gridwidth = 1;
            gbc.weightx = 0;
            gbc.fill = GridBagConstraints.HORIZONTAL;

            newButton = new JButton("Sign in");
            newButton.setActionCommand("new");
            managerButton = new JButton("Manager and Associate login");
            managerButton.setActionCommand("manager");

            add(newButton, gbc);
            gbc.gridx++;
            add(managerButton, gbc);                
        }

        public void addActionListener(ActionListener listener) {
            newButton.addActionListener(listener);
            managerButton.addActionListener(listener);
        }

        public void remveActionListener(ActionListener listener) {
            newButton.removeActionListener(listener);
            managerButton.removeActionListener(listener);
        }

        public String getUserName() {               
            return userName.getText();                
        }            
    }

    public class NewLoginPane extends JPanel {
        public NewLoginPane() {
            setLayout(new GridBagLayout());
            add(new JLabel("New Login"));
        }           
    }

    public class ManagerLoginPane extends JPanel {
        public ManagerLoginPane() {
            setLayout(new GridBagLayout());
            add(new JLabel("Welcome overlord"));
        }           
    }
}

There has to be a cleaner way of making an app with 16 different panels than having it all inside one class. 与拥有全部16个不同面板相比,必须有一种更清洁的方法来制作具有16个不同面板的应用程序。 What are some other options. 还有其他一些选择。

You are free to create and use as many classes as need be. 您可以自由创建和使用所需的多个类。 So if a JPanel holds a complex bit of GUI that you may wish to re-use elsewhere, or that has its own specific and separate functionality, by all means put the code in its own class. 因此,如果JPanel拥有一些复杂的GUI,您可能希望在其他地方重用它,或者具有自己的特定和单独的功能,则一定要将代码放在自己的类中。

Currently I only have 3 panels. 目前我只有3个面板。 I haven't gone any further because 2 of the panels aren't reflecting my changes. 我没有做进一步的事情,因为其中两个面板没有反映我的更改。 They are the two panels I call using 它们是我使用的两个面板

removeAll();
add();
revalidate();
repaint(); 

Smells like you're trying to re-invent the CardLayout. 闻起来就像您要重新发明CardLayout一样。 Why re-invent it when you can just use it? 为什么只要可以使用就重新发明它?

And yes, everything MadProgrammer says about null layout is true. 是的,MadProgrammer关于空布局的所有说法都是正确的。 You should avoid using it. 您应该避免使用它。

Oh, the CardLayout may work for you. 哦,CardLayout可能适合您。 I thought about using a JTabbedPane. 我考虑过使用JTabbedPane。 Here are my thoughts in a code example: 这是我在代码示例中的想法:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;


public class TabbedPaneDemo extends JFrame {

    public TabbedPaneDemo() {

        // set the layout of the frame to all the addition of all components
        setLayout(new FlowLayout());

        // create a tabbed pane
        JTabbedPane tabbedPane = new JTabbedPane();
        tabbedPane.setPreferredSize(new Dimension(500,500));
        add(tabbedPane);

        // create three panels to be added to this frame
        JPanel redPanel = new JPanel();
        JPanel greenPanel = new JPanel();
        JPanel bluePanel = new JPanel();

        // set the colors of the panels
        redPanel.setBackground(Color.RED);
        greenPanel.setBackground(Color.GREEN);
        bluePanel.setBackground(Color.BLUE);

        // set the preferred size of each panel
        redPanel.setPreferredSize(new Dimension(150,150));
        greenPanel.setPreferredSize(new Dimension(150,150));
        bluePanel.setPreferredSize(new Dimension(150,150));

        // add the panels to the tabbed pane
        tabbedPane.addTab("Red Panel", redPanel);
        tabbedPane.addTab("Green Panel", greenPanel);
        tabbedPane.addTab("Blue Panel", bluePanel);

        // finish initializing this window
        setSize(500,500); // size the window to fit its components (i.e. panels in this case)
        setLocationRelativeTo(null); // center this window
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // exit application when this window is closed
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TabbedPaneDemo().setVisible(true);
            }
        });
    }

}

选项卡式窗格演示

And for your other question about having 16 panels in one class: 还有一个班上有16个小组的其他问题:

  1. You can have panels within panel to organize things. 您可以在面板内有面板来组织事物。
  2. You can subclass JPanel and put the subclasses in their own .java files. 您可以将JPanel子类化,并将子类放入它们自己的.java文件中。

You can send me an email if I can be of further assistance. 如果我可以提供进一步的帮助,您可以给我发送电子邮件。 kaydell@yahoo.com (I like helping people with their programming and I learn from it too.) kaydell@yahoo.com(我喜欢帮助人们进行编程,我也从中学到东西。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM