当前位置: 首页 > 知识库问答 >
问题:

为什么我的JPanel占用了JFrame?

魏鹤轩
2023-03-14

我对编程相对较新,所以如果这个问题很愚蠢,我很抱歉。我正在创建一个Java程序,它在JPanel中包含一个JButton,而JPanel在JFrame中。另一个按钮在JPanel之外,但仍在JFrame中。我将布局设置为BoxLayout。我的问题是,我把面板做成黑色,除了第二个按钮之外,它占据了整个JFrame。如何使JPanel只占用第一个按钮周围的区域?

public class alt {
    JFrame frame = new JFrame();
    JPanel panel = new JPanel();
    JButton button1 = new JButton("button 1");
    JButton button2 = new JButton("button 2");
    public alt(){
        frame.setVisible(true);
        frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
        panel.setBackground(Color.black);
        frame.setTitle("test");
        frame.setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
        panel.add(button1);
        frame.add(panel);
        frame.add(button2);
        button2.setAlignmentX(Component.CENTER_ALIGNMENT);
    }
}

共有1个答案

訾旭
2023-03-14

面板占据框架内容窗格大部分的原因在于BoxLayout管理器处理组件的最小值、首选值和最大值的方式。它考虑了组件的最大值。而且由于JPanel的最大值很大,它占用了所有可用空间。解决方案是更改面板的最大值。然而,这是不好的做法。我不建议使用BoxLayout管理器--它很弱,会导致代码糟糕。

我建议使用miglayout管理器或grouplayout管理器。

我提供了三个解决方案:更正的BoxLayout解决方案、MigLayout解决方案和GroupLayout解决方案。

BoxLayout解决方案

我们确定按钮的最大大小,并将面板的大小改为比按钮大一点。

package com.zetcode;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class BoxLayoutPanel extends JFrame {

    public BoxLayoutPanel() {

        initUI();
    }

    private void initUI() {

        JPanel cpane = (JPanel) getContentPane();
        cpane.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
        cpane.setLayout(new BoxLayout(cpane, 
                BoxLayout.Y_AXIS));        

        JPanel pnl = new JPanel();

        JButton btn1 = new JButton("Button 1");
        JButton btn2 = new JButton("Button 2");

        Dimension dm = btn1.getMaximumSize();
        dm.height += 15;
        dm.width += 15;

        pnl.setMaximumSize(dm);

        pnl.setBackground(Color.black);
        add(pnl);
        add(Box.createVerticalStrut(10));
        pnl.add(btn1);
        btn2.setAlignmentX(Component.CENTER_ALIGNMENT);
        add(btn2);

        setTitle("BoxLayout solution");
        pack();
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

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

这不是一个干净的解决方案。通常,我们应该避免在应用程序代码中调用getmaximumsize()setmaximumsize()--这是布局管理器的工作。同样在三种情况下,我们使用固定的像素宽度:当我们定义一个空边框、一个垂直支柱和一个最大面板大小时。然而,此代码是不可移植的。当屏幕分辨率改变时,像素宽度也会改变。这是BoxLayout管理器的一个缺点。

MigLayout解决方案

这种解决方案更干净,也更便携。miglayout是第三方管理器,因此我们需要下载其他库。

package com.zetcode;

import java.awt.Color;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;


public class MigLayoutPanel extends JFrame {

    public MigLayoutPanel(){

        initUI();

        setTitle("MigLayout solution");
        setLocationRelativeTo(null);       
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private void initUI() {

        JPanel main = new JPanel(new MigLayout("center"));

        JPanel pnl2 = new JPanel();

        JButton btn1 = new JButton("Button 1");
        JButton btn2 = new JButton("Button 2");

        pnl2.setBackground(Color.black);

        pnl2.add(btn1);
        main.add(pnl2, "wrap");
        main.add(btn2, "alignx center");

        add(main);

        pack();
    }


    public static void main(String[] args){

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                MigLayoutPanel ex = new MigLayoutPanel();
                ex.setVisible(true);
            }
        });
    }
}

GroupLayout解决方案

Grouplayout是一个内置的布局管理器。使用miglayout,它们是最可移植和灵活的布局管理器。

package com.zetcode;

import java.awt.Color;
import java.awt.Container;
import java.awt.EventQueue;
import javax.swing.GroupLayout;
import static javax.swing.GroupLayout.Alignment.CENTER;
import static javax.swing.GroupLayout.DEFAULT_SIZE;
import static javax.swing.GroupLayout.PREFERRED_SIZE;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import static javax.swing.LayoutStyle.ComponentPlacement.RELATED;


public class GroupLayoutPanel extends JFrame {

    public GroupLayoutPanel(){

        initUI();

        setTitle("GroupLayout solution");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);        
    }

    private void initUI() {

        Container pane = getContentPane();
        GroupLayout gl = new GroupLayout(pane);
        pane.setLayout(gl); 

        JPanel pnl = new JPanel();

        JButton btn1 = new JButton("Button 1");
        pnl.add(btn1);

        JButton btn2 = new JButton("Button 2");

        pnl.setBackground(Color.black);

        gl.setAutoCreateGaps(true);

        gl.setHorizontalGroup(gl.createSequentialGroup()
                .addContainerGap(DEFAULT_SIZE, Integer.MAX_VALUE)
                .addGroup(gl.createParallelGroup(CENTER)
                        .addComponent(pnl, DEFAULT_SIZE, DEFAULT_SIZE, 
                                PREFERRED_SIZE)
                        .addComponent(btn2))
                .addContainerGap(DEFAULT_SIZE, Integer.MAX_VALUE)
        );

        gl.setVerticalGroup(gl.createSequentialGroup()
                .addContainerGap()
                .addComponent(pnl, DEFAULT_SIZE, DEFAULT_SIZE, 
                        PREFERRED_SIZE)
                .addPreferredGap(RELATED)
                .addComponent(btn2)
                .addContainerGap()
        );

        pack();
    }


    public static void main(String[] args){

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                GroupLayoutPanel ex = new GroupLayoutPanel();
                ex.setVisible(true);
            }
        });
    }
}
 类似资料:
  • 问题内容: 这最终会消耗我所有的可用内存,然后进程被杀死。我曾尝试将标签从更改为“较小”标签,但这并没有什么不同。 我在做什么错/如何处理这个大文件? 我可以轻松地将其切碎并以较小的块进行处理,但这比我想要的还要难看。 问题答案: 当遍历整个文件时,将构建一棵树,并且不会释放任何元素。这样做的好处是元素可以记住其父元素是谁,并且您可以形成引用祖先元素的XPath。缺点是它会消耗大量内存。 为了在解

  • 问题内容: 之间有什么区别: 和 我知道JPanel是GUI组件的容器,但我确实看不到使用它的实用程序。当然,我错了,但我是从Swing开始的,所以…为什么我应该使用JPanel?真正的目的是什么? 问题答案: 为什么我应该使用JPanel? 您可以使用JPanel获得以下一项或多项好处: 将组件分组在一起。 为了更好地组织您的组件。 为了使我们能够使用 多种布局 并组合其效果。(例如,用于数字键

  • 我试图将24个添加到我的的,但当我运行它时,我发现没有添加任何按钮。(至少,它们不可见!)。我试着给一个背景色,它是可见的。有人知道我做错了什么吗? 这是我的代码(还有一个类): 其他(主要)类别:

  • 问题内容: 我的应用程序在Linux上作为后台进程运行。当前在“终端”窗口的命令行中启动。 最近,一个用户执行该应用程序一段时间后,它神秘地死了。文本: 被杀 在航站楼上。这发生了两次。我问其他终端是否有人使用kill命令杀死进程?没有。 Linux在什么情况下会决定终止我的进程?我相信外壳程序显示为“ killed”,因为该进程在收到kill(9)信号后就死了。如果Linux发送了kill信号,

  • 问题内容: 这是从CruiseControl执行时得到的: 同时,从命令行启动它可以提供正确的结果。为什么要进入这个?为什么忽略了我?我该如何解决? 我不知道从CC启动when 的值是什么。我真的很想获得这些信息,但我不知道如何。CC本身是从用户开始与该用户给我(这是CentOS的5.4): 问题答案: 假设您有一台linux机器。 看一下,这是一个符号链接。查看此符号链接的目标位置(在我的情况下

  • 认证之后,如果我调用任何方法,比如< code>os.compute()。口味()。list()或< code>os.images()。list(),我得到< code >连接超时。为什么会这样? 我在GoogleCloudsPlataform VM上设置了一个带有RDO包堆栈的OpenStack。我正在对域和项目进行身份验证。我尝试了没有项目的身份验证,方法调用没有超时,但是响应是错误的,例如,