【问题标题】:Placing of JPanels on the JFrames is not correct在 JFrame 上放置 JPanel 不正确
【发布时间】:2014-08-23 17:42:10
【问题描述】:

我为我的作业编写了一个程序来使用 swing/awt 框架组成一个 GUI。到目前为止,我能够让这些部分一起工作,但是当我将它们全部放入 JFrame 时,它​​们并没有按预期出现。

我最近开始研究 Java GUI 框架,但不确定我的代码中缺少什么。我怎样才能让它正常工作?

我还附上了我得到的输出的屏幕截图(见底部)。

public class MainFrame extends JFrame {

    public MainFrame() {
    addComponentsToPane(this.getContentPane());
    }

    private void addComponentsToPane(Container pane) {

        // Set layout
        GridBagConstraints gbc = new GridBagConstraints();
        this.setTitle("Test tool");
        this.setSize(600, 650);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLayout(new GridLayout(2, 1));

        // Add video JComponent
        mMainPanel = new MainPanel();
        pane.add(mMainPanel, 0);

        // Add conference screen panel
        mFeedPanel = new FeedPanel();
        pane.add(mFeedPanel, 1);

        // Add a button panel
        mButtonPanel = new ButtonPanel();
        pane.add(mButtonPanel, 2);

        this.setResizable(true);
        this.setVisible(true);
        this.pack();
    }
}

// In actual output, there is 1 screen in this panel. 
// mScreen1 is derived from JComponent object.
public class MainPanel() extends JPanel {

    public MainPanel() {
    addMainPanelComponents();
    }

    private void addMainPanelComponents() {
        this.setSize(352, 240);
        setBackground(Color.yellow);
        setLayout(new GridLayout(1, 2));
        add(mScreen);
        setVisible(true);
    }
}

// In actual output, there are 3 screens in this panel. I have shown code for 1 screen only
// mScreen1 is derived from JComponent object.
public class FeedPanel extends JPanel {

    public FeedPanel() {
    addFeedPanelComponents();
    }

    private void addFeedPanelComponents() {

        String img1 = "images/screen1.png";

        setSize(352, 150);
        setBackground(Color.yellow);
        setLayout(new GridLayout(1, 3));                

        Image image1 = ImageIO.read(new File(img1));
        mScreen1.setImage(image1);
        add(mScreen1);
        setVisible(true);
    }
}

public class ButtonPanel extends JPanel {

    public ButtonPanel() {
    addButtonPanelComponents();
    }

    private void addButtonPanelComponents() {

        this.setSize(352, 150);
        this.setBackground(Color.yellow);
        this.setLayout(new GridLayout(1, 
                                      5));

        // Add Button to panel
        mStartButton = new JButton("Start");
        this.add(mStartButton);
        mStartButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                StartButtonActionListener(ae);
            }
        });

        mStopButton = new JButton("Stop");
        this.add(mStopButton);
        mStopButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                StopButtonActionListener(ae);
            }
        });
        setVisible(true);
    }
}

这是在运行代码时默认出现的。

这是在手动调整框架大小之后发生的。

【问题讨论】:

  • 您确定您指定的帧大小正确吗?据我所知,图像大小超过了您指定的帧大小的 75%。
  • 刚刚将我使用的实际帧大小添加到代码中,但结果仍然相同。 FeedPanel 在其网格布局中包含 3 个图像。那么这是否意味着帧宽度应该是图像大小的 3 倍?
  • 请问您为什么不使用 GridLayout 并通过进行一些更改来降低代码的复杂性?
  • 另外,在将 ButtonPanel 添加到大型机 (JFrame) 之前,我正在将按钮添加到它自己的面板中。然而,在调整窗口大小时,按钮也会调整大小。
  • 我正在为 MainFrame 使用 GridLayout。如果您错过了这条线,请查看。 this.setLayout(new GridLayout(2, 1));

标签: java swing user-interface awt layout-manager


【解决方案1】:

BorderLayout 、 GirdLayout 和 BoxLayout 的组合可以为你做到这一点(其实不是唯一的选择)。

代码如下:

import java.awt.BorderLayout;
import java.awt.GridLayout;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class GridLayoutTest {
    public void createUI(){
        JFrame frame = new JFrame();

        JPanel topPanel = new TopPanel();
        JPanel buttomPanel = new ButtomPanel();


        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new BorderLayout());
        mainPanel.add(topPanel,BorderLayout.CENTER);
        mainPanel.add(buttomPanel,BorderLayout.SOUTH);
        frame.add(mainPanel,BorderLayout.CENTER);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        GridLayoutTest test = new GridLayoutTest();
        test.createUI();
    }

    @SuppressWarnings("serial")
    class TopPanel extends JPanel{
        public TopPanel(){
            setLayout(new GridLayout(2, 3));
            ImageIcon icon = new ImageIcon("capture.png");
            JLabel label1 = new JLabel(icon);
            label1.setVisible(false);
            JLabel label2 = new JLabel(icon);
            JLabel label3 = new JLabel(icon);
            label3.setVisible(false);
            JLabel label4 = new JLabel(icon);
            JLabel label5 = new JLabel(icon);
            JLabel label6 = new JLabel(icon);
            add(label1);
            add(label2);
            add(label3);
            add(label4);
            add(label5);
            add(label6);
        }
    }

    @SuppressWarnings("serial")
    class ButtomPanel extends JPanel{
        public ButtomPanel(){
            JButton startButton = new JButton("start");
            JButton stopButton = new JButton("stop");
            JButton recordButton = new JButton("record");

            setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
            add(Box.createHorizontalGlue());
            add(startButton);
            add(Box.createHorizontalStrut(10));
            add(stopButton);
            add(Box.createHorizontalStrut(10));
            add(recordButton);
            add(Box.createHorizontalGlue());
        }
    }
}

BoxLayout 也非常棒,它提供了空白区域并帮助您将组件居中。

    setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
    add(Box.createHorizontalGlue());
    add(startButton);
    add(Box.createHorizontalStrut(10));
    add(stopButton);
    add(Box.createHorizontalStrut(10));
    add(recordButton);
    add(Box.createHorizontalGlue());

在第一个组件之前和最后一个组件之后添加 Glue 将帮助您使组件居中,添加 strut 可以帮助您提供所需的空白。详情可以参考https://stackoverflow.com/a/22525005/3378204

效果如下:

BoxLayout 不会影响组件的大小。希望对你有帮助。

【讨论】:

    【解决方案2】:

    试试这个:

        public class Main{
    
        private JFrame f;
        private JLabel l1, l2, l3,l4;
        private JPanel p1, p2, p3;
        private JButton b1, b2, b3;
    
        public Main(){
    
        this.f = new JFrame();
        this.f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.f.setLayout(new GridLayout(3,1));
    
        this.p1 = new JPanel();
        this.p1.setLayout(null)
        this.p1.setSize(yoursize);
    
        this.l1 = new JLabel();
        this.l1.setBounds(x,y,xspan,yspan);
    
        this.p1.add(l1);
    
        this.p2 = new JPanel();
        this.p2.setLayout(new GridLayout(1,3));
    
        this.l2 = new JLabel();
        this.l3 = new JLabel();
        this.l4 = new JLabel();
    
        this.p2.add(l2);
        this.p2.add(l3);
        this.p2.add(l4);
    
        this.p3 = new JPanel();
        this.p3.setLayout(new GridLayout(1,3));
    
        this.b1 = new JButton();
        this.b2 = new JButton();  
        this.b3 = new JButton();
    
        this.p3.add(b1);       
        this.p3.add(b2);
        this.p3.add(b3);
    
        this.f.add(p1);
        this.f.add(p2);
        this.f.add(p3);
    
        this.f.pack();
        this.f.setResizeable(false)
        }}
    

    添加您的视频组件而不是标签,您可以根据需要更改组件的颜色。 此外,如果您想更好地控制组件的大小和位置,请使用 null 布局并使用 setBounds() 函数单独放置它们,如上面程序所示。这肯定很耗时,但使布局完美。

    【讨论】:

    • 谢谢。让我试试这个,如果我遇到任何其他困难,会告诉你。
    • 欢迎。另外,正如我所提到的,如果您希望按钮大小可调,请改用空布局并手动设置适合您选择的大小。
    • 除了 ButtonPanel 的大小无法控制它也无法根据按钮的高度自行调整之外,我已经完成了大部分工作。我观察到所有三个面板(我给它们赋予了不同的颜色)都具有相同的尺寸。我不确定这是否是因为我在 JFrame 中使用了 GridLayout()。
    • 您需要将由按钮组成的JPanel的布局设置为null,并使用setBounds函数手动设置大小和位置。如果这不起作用,您需要将 JFrame 本身的布局设置为 null 并手动设置所有组件的位置。正如我之前提到的,布局管理器并不完美,因此如果您想要自定义布局以使您的软件看起来完美,您需要创建自己的布局管理器或手动设置它们,如我所示。
    猜你喜欢
    • 2013-09-22
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-30
    • 2017-08-18
    • 2011-11-05
    相关资源
    最近更新 更多