如何在 jFrame 上布局多个面板?(爪哇)

2022-01-24 00:00:00 layout java swing jpanel jframe

我正在制作自己的 java socket 游戏.我的游戏在全屏上画得很好(它说在这里画图",但我现在画到整个jframe).我想添加一个带有滚动条的文本框,用于显示 only 文本,不接受任何输入,另一个文本框从用户那里获取文本输入,然后是一个按钮来发送文本,用于聊天目的.但是关于我的问题,我什至如何开始布局呢?我知道我需要一个布局,但是有人可以帮助我吗?这是我现在的代码(这段代码现在只设置了对整个屏幕的绘制,现在需要像上图那样将屏幕分割):

I am in the process of making my own java socket game. My game is painting alright to the full screen (where it says "paint graphics here", but im painting to the whole jframe at the moment). I want to add a textbox with a scroll bar for displaying only text, not taking any input and another textbox to take text inputs from the user and then a button to send the text, for chat purposes. But onto my question, how do I even start to lay this out? I understand I need a layout, but can someone help me on this? Here is my code at the moment (this code only sets up painting to the whole screen at the moment, need to divide the screen up now like I have in the picture above):

public class Setup extends JFrame implements Runnable{
     JPanel panel;
     JFrame window;
     public Setup(Starter start, JFrame window){
         window.setSize(600,500);
         window.setLocationRelativeTo(null);
         window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         window.setResizable(false);
         panel = new Display(start);
         this.window = window;
     }
     public void run(){
         window.getContentPane().add(panel);
         window.setBackground(Color.BLACK);
         window.setVisible(true);
     }
}

new Display(start)" - 这扩展了 jpanel,它基本上是我绘制所有图形的地方.

"new Display(start)" - this extends jpanel, its basically where I paint everything graphics wise.

此外,我看到人们在不同的面板中添加,但我不能让它们的大小相同.如图所示,在此处绘制图形"面板是最大的,以此类推.

In addition, I've seen people add in different panels but I cant have them be the same size. Like in the picture, the "paint graphics here" panel is the biggest one, and so on.

推荐答案

JPanel 实际上只是一个容器,你可以在其中放置不同的元素(甚至是其他 JPanel).所以在你的情况下,我会建议一个大的 JPanel 作为你的窗口的某种 主容器.主面板您分配了一个适合您需要的 Layout (这里是布局的介绍).

The JPanel is actually only a container where you can put different elements in it (even other JPanels). So in your case I would suggest one big JPanel as some sort of main container for your window. That main panel you assign a Layout that suits your needs ( here is an introduction to the layouts).

将布局设置到您的主面板后,您可以添加绘画面板和您想要的其他JPanel(比如其中包含文本的那些..).

After you set the layout to your main panel you can add the paint panel and the other JPanels you want (like those with the text in it..).

  JPanel mainPanel = new JPanel();
  mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));

  JPanel paintPanel = new JPanel();
  JPanel textPanel = new JPanel();

  mainPanel.add(paintPanel);
  mainPanel.add(textPanel);

这只是对所有子面板进行垂直(Y 轴)排序的示例.因此,如果您想要在 mainPanel 底部的其他一些东西(可能是一些图标或按钮)应该与另一个布局(如水平布局)一起组织,只需再次创建一个新的 JPanel 作为容器对于所有其他的东西并设置 setLayout(new BoxLayout(mainPanel, BoxLayout.X_AXIS).

This is just an example that sorts all sub panels vertically (Y-Axis). So if you want some other stuff at the bottom of your mainPanel (maybe some icons or buttons) that should be organized with another layout (like a horizontal layout), just create again a new JPanel as a container for all the other stuff and set setLayout(new BoxLayout(mainPanel, BoxLayout.X_AXIS).

您会发现,布局非常严格,可能很难为您的面板找到最佳布局.所以不要放弃,阅读介绍(上面的链接)并查看图片 - 这就是我的做法:)

As you will find out, the layouts are quite rigid and it may be difficult to find the best layout for your panels. So don't give up, read the introduction (the link above) and look at the pictures – this is how I do it :)

或者您可以只使用 NetBeans 来编写您的程序.你有一个非常简单的可视化编辑器(拖放)来创建各种窗口和框架.(事后才理解代码……有时很棘手.)

Or you can just use NetBeans to write your program. There you have a pretty easy visual editor (drag and drop) to create all sorts of Windows and Frames. (only understanding the code afterwards is ... tricky sometimes.)

由于有很多人对这个问题感兴趣,我想提供一个完整的示例,说明如何布局 JFrame 以使其看起来像 OP 想要的那样.

Since there are some many people interested in this question, I wanted to provide a complete example of how to layout a JFrame to make it look like OP wants it to.

该类名为 MyFrame 并扩展了 swings JFrame

The class is called MyFrame and extends swings JFrame

public class MyFrame extends javax.swing.JFrame{

    // these are the components we need.
    private final JSplitPane splitPane;  // split the window in top and bottom
    private final JPanel topPanel;       // container panel for the top
    private final JPanel bottomPanel;    // container panel for the bottom
    private final JScrollPane scrollPane; // makes the text scrollable
    private final JTextArea textArea;     // the text
    private final JPanel inputPanel;      // under the text a container for all the input elements
    private final JTextField textField;   // a textField for the text the user inputs
    private final JButton button;         // and a "send" button

    public MyFrame(){

        // first, lets create the containers:
        // the splitPane devides the window in two components (here: top and bottom)
        // users can then move the devider and decide how much of the top component
        // and how much of the bottom component they want to see.
        splitPane = new JSplitPane();

        topPanel = new JPanel();         // our top component
        bottomPanel = new JPanel();      // our bottom component

        // in our bottom panel we want the text area and the input components
        scrollPane = new JScrollPane();  // this scrollPane is used to make the text area scrollable
        textArea = new JTextArea();      // this text area will be put inside the scrollPane

        // the input components will be put in a separate panel
        inputPanel = new JPanel();
        textField = new JTextField();    // first the input field where the user can type his text
        button = new JButton("send");    // and a button at the right, to send the text

        // now lets define the default size of our window and its layout:
        setPreferredSize(new Dimension(400, 400));     // let's open the window with a default size of 400x400 pixels
        // the contentPane is the container that holds all our components
        getContentPane().setLayout(new GridLayout());  // the default GridLayout is like a grid with 1 column and 1 row,
        // we only add one element to the window itself
        getContentPane().add(splitPane);               // due to the GridLayout, our splitPane will now fill the whole window

        // let's configure our splitPane:
        splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);  // we want it to split the window verticaly
        splitPane.setDividerLocation(200);                    // the initial position of the divider is 200 (our window is 400 pixels high)
        splitPane.setTopComponent(topPanel);                  // at the top we want our "topPanel"
        splitPane.setBottomComponent(bottomPanel);            // and at the bottom we want our "bottomPanel"

        // our topPanel doesn't need anymore for this example. Whatever you want it to contain, you can add it here
        bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS)); // BoxLayout.Y_AXIS will arrange the content vertically

        bottomPanel.add(scrollPane);                // first we add the scrollPane to the bottomPanel, so it is at the top
        scrollPane.setViewportView(textArea);       // the scrollPane should make the textArea scrollable, so we define the viewport
        bottomPanel.add(inputPanel);                // then we add the inputPanel to the bottomPanel, so it under the scrollPane / textArea

        // let's set the maximum size of the inputPanel, so it doesn't get too big when the user resizes the window
        inputPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 75));     // we set the max height to 75 and the max width to (almost) unlimited
        inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.X_AXIS));   // X_Axis will arrange the content horizontally

        inputPanel.add(textField);        // left will be the textField
        inputPanel.add(button);           // and right the "send" button

        pack();   // calling pack() at the end, will ensure that every layout and size we just defined gets applied before the stuff becomes visible
    }

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

请注意,这只是一个示例,有多种布局窗口的方法.这完全取决于您的需求以及您是否希望内容可调整大小/响应.另一个非常好的方法是 GridBagLayout 可以处理相当复杂的布局,但学习起来也相当复杂.

Please be aware that this is only an example and there are multiple approaches to layout a window. It all depends on your needs and if you want the content to be resizable / responsive. Another really good approach would be the GridBagLayout which can handle quite complex layouting, but which is also quite complex to learn.

相关文章