【问题标题】:How to use layout managers when building a GUI with JFrame and JPanel?使用 JFrame 和 JPanel 构建 GUI 时如何使用布局管理器?
【发布时间】:2017-01-31 17:16:23
【问题描述】:

我正在尝试构建一个如下所示的 GUI:

主要思想是在侧面有按钮和显示结果的表格。

这是我目前的代码:

public class GUI {

    private JButton usdJpyButton = new JButton("USD/JPY");
    private JButton usdGbpButton = new JButton("USD/GBP");

    public void mainScreen(){

        JFrame frame = new JFrame("Window");
        frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        frame.setSize(900,600);
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);

        GridLayout layout = new GridLayout(0,4);
        frame.setLayout(layout);


        JPanel sidePanel = new JPanel(new GridBagLayout());
        sidePanel.setBackground(Color.black);

        GridBagConstraints cons = new GridBagConstraints();
        cons.insets = new Insets(50,0,0,0);
        cons.gridy = 1;
        cons.anchor = GridBagConstraints.NORTH;

        sidePanel.add(usdJpyButton);

        cons.gridy = 2;

        sidePanel.add(usdGbpButton);

        frame.add(sidePanel);
        frame.setVisible(true);

    }

按钮未对齐,我不确定应该使用哪个布局管理器以获得最佳效果。此外,每个按钮都会有一个针对不同表的动作侦听器,所以我需要为每个表创建单独的 JPanel 吗??

【问题讨论】:

  • 使用您在构建JPanel 时指定的GridBagConstraints,例如sidePanel.add(usdJpyButton, cons);

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


【解决方案1】:

我不确定应该使用哪个布局管理器以获得最佳效果。

您很少使用单一的布局管理器。通常,您会使用不同的布局管理器来嵌套面板,以达到您想要的效果。

阅读 Layout Managers 上的 Swing 教程部分,了解每个布局管理器的工作示例。

在这种情况下,您可能需要两个面板,一个用于按钮,另一个用于在您单击按钮时显示的面板。

所以对于按钮,您可以使用BorderLayout 创建一个面板。然后使用GridLayout 创建第二个面板。使用GridLayout 将按钮添加到面板。然后将此面板添加到BorderLayoutPAGE_START。然后将此面板添加到框架内容窗格使用的BorderLayout 中的LINE_START

然后,要让面板显示每个表格,您将使用CardLayout。然后为每个货币表创建一个单独的面板并将其添加到CardLayout。您可以将此面板添加到内容窗格的BorderLayout 中的CENTER

然后在您的按钮的ActionListener 中,您根据单击的按钮交换CardLayout 中的面板。

同样,我提供的教程链接包含 BorderLayout、GridLayout 和 CardLayout 的工作示例。

【讨论】:

  • 当我使用 BorderLayout 时,屏幕上不能有两个大小不同的面板,当我使用 GridLayout 时,面板不会覆盖整个窗口
  • @Emir54,当然可以。你有没有看过 BorderLayout 教程???如果你这样做了,你可以从图像中看出组件的大小可以不同!!!
  • 我之前已经检查过这些教程,但无法让它工作,因此为什么我在 stackoverflow 上创建了这个问题?
  • @Emir54,所以发布您的SSCCE 来证明问题。您已获得解决方案,因此请根据给出的建议向我们展示您尝试编写的代码。如果您无法理解工作示例,请发布特定问题。我们猜不出您会感到困惑。
【解决方案2】:

我会推荐MigLayout经理。

用这个经理来做这件事并不是特别困难。

package com.zetcode;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import net.miginfocom.swing.MigLayout;

public class InstaMetrixEx extends JFrame implements ActionListener {

    public InstaMetrixEx() {

        initUI();
    }

    private void initUI() {

        JButton btn1 = new JButton("Client Overview");
        JButton btn2 = new JButton("Seo Reports");
        JButton btn3 = new JButton("Social media reports");
        JButton btn4 = new JButton("Campaigns");
        JButton btn5 = new JButton("Webmaster tools");
        JButton btn6 = new JButton("Dashboard");
        JButton btn7 = new JButton("Tasks");

        JComboBox combo1 = new JComboBox();
        combo1.addItem("Bulk actions");

        JButton btn8 = new JButton("Submit");

        JTable table = new JTable(20, 7);
        JScrollPane spane = new JScrollPane(table);

        createLayout(btn1, combo1, btn8, btn2, btn3, btn4,
                btn5, btn6, btn7, spane );

        setTitle("InstaMetrixEx");
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    private void createLayout(JComponent... arg) {

        setLayout(new MigLayout());

        add(arg[0], "sgx");
        add(arg[1], "gapx 10lp, split 2");
        add(arg[2], "wrap");
        add(arg[3], "split 6, aligny top, flowy, sgx");
        add(arg[4], "sgx");
        add(arg[5], "sgx");
        add(arg[6], "sgx");
        add(arg[7], "sgx");
        add(arg[8], "sgx");

        add(arg[9], "gapx 10lp, spanx, wrap, push, grow");

        pack();
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        JOptionPane.showMessageDialog(this, "Button clicked",
                "Information", JOptionPane.INFORMATION_MESSAGE);
    }

    public static void main(String[] args) {

        EventQueue.invokeLater(() -> {
            InstaMetrixEx ex = new InstaMetrixEx();
            ex.setVisible(true);
        });
    }
}

截图:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-22
    • 2020-06-27
    • 2019-08-24
    • 1970-01-01
    • 2016-10-23
    相关资源
    最近更新 更多