JFrame 底部的白边

White edge at the bottom of JFrame

我正在使用 Javax swing,无法摆脱 JFrame 底部的这个微小的白色边框。我的 JFrame 的结构方式是我向 JPanel 添加了一堆组件(例如按钮、文本字段、标签),然后将其添加到框架中。我已经尝试将面板的首选大小设置为所需的尺寸,然后在 JFrame 上调用 pack() 但无济于事。提前谢谢你。

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

public class SampleGUI {
    JFrame frame;
    JPanel panel;
    JLabel label;
    JTextField field;

    public SampleGUI()
    {
        this.frame = new JFrame();
        this.panel = new JPanel();
        this.label = new JLabel("test");
        this.field = new JTextField(20);

        panel.setPreferredSize(new Dimension(500, 250));
        panel.setLayout(null);

        label.setBounds(50, 75, 80, 25);
        label.setForeground(Color.WHITE);
        panel.add(label);

        field.setBounds(120, 80, 80, 20);
        panel.add(field);

        //Background Config
        try
        {
            URL url = new URL("https://watchandlearn.scholastic.com/content/dam/classroom-magazines/watchandlearn/videos/earth-and-space/earth-science-and-space/what-s-in-the-night-sky/english/wall-2018-whatsinthenightskymp4.transform/content-tile-large/image.png");
            BufferedImage image = ImageIO.read(url);
            JLabel img = new JLabel();
            img.setSize(500, 250);
            img.setIcon(new ImageIcon(image));
            img.setOpaque(false);
            panel.add(img);
        }
        catch(IOException ignored){}

        frame.setSize(500, 250);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(panel);

        frame.setResizable(false);
        frame.setVisible(true);
    }
    public static void main(String[] args)
    {
        SampleGUI sample = new SampleGUI();
    }
}

这是我整理的 GUI。我继续添加其他 Swing 组件。如您所见,底部没有线。

我通过调用 SwingUtilities invokeLater 方法启动了 Swing 应用程序。此方法确保 Swing 组件在 Event Dispatch Thread.

上创建和执行

我创建了一个绘图 JPanel,所以我可以在 JPanel 上绘制图像。我将 JPanel 设置为图像的大小。我使用 GridBagLayout 来布置 JPanel 的组件。 GridBagLayout 会将 Swing 组件放在列中,并将组件组居中。

JFrame 方法调用必须按特定顺序调用。这是我用于 Swing 应用程序的顺序。

这是完整的可运行代码。我将额外的 class 设为内部 class,这样我就可以 post 将这段代码作为一个块。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class StarryNightGUI implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new StarryNightGUI());
    }
    
    private BufferedImage image;
    
    private final BackgroundPanel backgroundPanel;
    
    public StarryNightGUI() {
        try {
            URL url = new URL("https://watchandlearn.scholastic.com/content/dam/"
                + "classroom-magazines/watchandlearn/videos/earth-and-space/"
                + "earth-science-and-space/what-s-in-the-night-sky/english/"
                + "wall-2018-whatsinthenightskymp4.transform/"
                + "content-tile-large/image.png");
            this.image = ImageIO.read(url);
        } catch (Exception e) {
            e.printStackTrace();
            this.image = null;
        }
        
         this.backgroundPanel = new BackgroundPanel();
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Starry Night");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        
        frame.add(backgroundPanel, BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    public class BackgroundPanel extends JPanel {
        
        private static final long serialVersionUID = 1L;

        public BackgroundPanel() {
            this.setPreferredSize(new Dimension(image.getWidth(), 
                    image.getHeight()));
            this.setLayout(new GridBagLayout());
            
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.anchor = GridBagConstraints.LINE_START;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.insets = new Insets(5, 5, 5, 5);
            
            gbc.gridwidth = 2;
            gbc.gridx = 0;
            gbc.gridy = 0;
            String s = "Good Morning: " + LocalDateTime.now().format(
                    DateTimeFormatter.ofPattern("d MMM yyyy  H:mm a"));
            JLabel label = new JLabel(s);
            label.setForeground(Color.WHITE);
            add(label, gbc);
            
            gbc.gridwidth = 1;
            gbc.gridx = 0;
            gbc.gridy++;
            label = new JLabel("Username:");
            label.setForeground(Color.WHITE);
            add(label, gbc);
            
            gbc.gridx++;
            JTextField field = new JTextField(10);
            add(field, gbc);
            
            gbc.gridx = 0;
            gbc.gridy++;
            label = new JLabel("Password:");
            label.setForeground(Color.WHITE);
            add(label, gbc);
            
            gbc.gridx++;
            JPasswordField passwordField = new JPasswordField(10);
            add(passwordField, gbc);
            
            gbc.gridwidth = 2;
            gbc.gridx = 0;
            gbc.gridy++;
            
            JButton button = new JButton("Login");
            add(button, gbc);
        }
        
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(image, 0, 0, this);
        }
        
    }

}

如果您只是想让您的代码正常工作,请将 frame.add(panel); 替换为 frame.setContentPane(panel); 并将其移动到框架包之前

    frame.setContentPane(panel);
    frame.pack();

同时删除 frame.setSize(...),因为 pack 方法会处理大小。

但是,一般来说,我建议您深入了解 Gilber 的回答,这样您就可以学到很多关于在面板中布置元素的知识。