java框架不改变颜色

java框架不改变颜色,java,swing,intellij-idea,Java,Swing,Intellij Idea,我无法在下面的Java代码中更改帧的颜色。我知道更改它的代码是frame.getContentPane.setBackgroundColor.gray;但是,这对我来说不起作用,我不确定这背后的原因是什么,但是如果你能解决问题,一定要让我知道,谢谢 public class UserLoginPage implements ActionListener { //Put all JLabels,Frames and buttons here etc JPanel panel = n

我无法在下面的Java代码中更改帧的颜色。我知道更改它的代码是frame.getContentPane.setBackgroundColor.gray;但是,这对我来说不起作用,我不确定这背后的原因是什么,但是如果你能解决问题,一定要让我知道,谢谢

public class UserLoginPage implements ActionListener {
    //Put all JLabels,Frames and buttons here etc
    JPanel panel = new JPanel();
    JFrame frame = new JFrame();
    JLabel userLabel = new JLabel("Username");
    JLabel passwordLabel = new JLabel("Password");
    JTextField userText = new JTextField();
    JTextField passwordText = new JTextField();
    JButton loginButton = new JButton("Login");

    //Label for successful login
    JLabel success = new JLabel();

    //Default Constructor to add the frames and panels etc
    public UserLoginPage(){
        panel.setLayout(null);
        userLabel.setBounds(10,20,80,25);
        panel.add(userLabel);
        passwordLabel.setBounds(10,50,80,25);
        panel.add(passwordLabel);

        userText.setBounds(100,20,165,25);
        panel.add(userText);
        passwordText.setBounds(100,50,165,25);
        panel.add(passwordText);

        loginButton.setBounds(10,80,80,25);
        loginButton.addActionListener(this);
        panel.add(loginButton);

        success.setBounds(10,110,300,25);
        panel.add(success);
        //success.setText();

        frame.setSize(500,500);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.getContentPane().setBackground(Color.gray);
        frame.setVisible(true);
        frame.add(panel);

    }


    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new UserLoginPage();
            }
        });
    }


    @Override
    public void actionPerformed(ActionEvent e) {
        String user = userText.getText();
        String password = passwordText.getText();
        System.out.println(user + ", " + password);

        if(user.equals("Jackson") && password.equals("1234")){
            JOptionPane.showMessageDialog(frame,"Login successful");
        }
        else{
            JOptionPane.showMessageDialog(frame,"Invalid password or username");
        }
    }
}
您正在向JFrame添加panel,一个JPanel,由于JFrame的contentPane使用了一个BorderLayout,这个不透明的JPanel将完全覆盖contentPane,从而阻止contentPane背景的可视化

解决方案: 通过panel.setOpaquefalse使面板不不透明;因此,现在它的容器的颜色或图像将显示出来 或者将其保留为默认不透明,为其而不是contentPane提供所选的背景色。 不相关的问题在这里:

panel.setLayout(null)
你真的不想这样做有很多原因,包括因为这将使你的GUI只在一个平台上工作良好/看起来不错。这也使得以后很难升级和增强GUI

例如,结合Andrew Thompson的一些建议,下面是一个用于创建JPanel的登录GUI示例,在本例中,它被放置到一个类似于JOptionPane的模态JDialog中,但具有更大的灵活性和显示能力。代码在添加组件时使用GridBagLayout和GridBagConstraints,以一种在所有平台上都能正常工作的令人愉悦的方式将它们放置在我希望的位置,并且如果我想添加更多组件,它允许轻松和灵活:

import java.awt.Color;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class UserLoginPanel extends JPanel {
    private static final Color BACKGROUND = new Color(200, 200, 200);
    private JTextField userText = new JTextField(15);
    private JPasswordField passwordText = new JPasswordField(15);
    LoginAction loginAction = new LoginAction(this, "Login", KeyEvent.VK_L);
    JButton loginButton = new JButton(loginAction);

    public UserLoginPanel() {
        super(new GridBagLayout());
        setBackground(BACKGROUND);
        
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0; 
        gbc.gridy = 0;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;
        int insetGap = 4;
        gbc.insets = new Insets(insetGap, insetGap, insetGap, insetGap);
        
        add(new JLabel("User Name:"), gbc);
        
        gbc.gridx = 1;
        add(userText, gbc);
        
        gbc.gridx = 0;
        gbc.gridy = 1;
        add(new JLabel("Password"), gbc);
        
        gbc.gridx = 1;
        add(passwordText, gbc);
        
        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.gridwidth = 2;
        add(loginButton, gbc);
        
        insetGap = 8;
        setBorder(BorderFactory.createEmptyBorder(insetGap, insetGap, insetGap, insetGap));
    }
    
    public String getUserName() {
        return userText.getText();
    }
    
    public char[] getPassword() {
        return passwordText.getPassword();
    }
    
    public static void main(String[] args) {
        UserLoginPanel loginPanel = new UserLoginPanel();
        JDialog dialog = new JDialog(null, "User Login", ModalityType.APPLICATION_MODAL);
        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        dialog.add(loginPanel);
        dialog.pack();
        dialog.setLocationByPlatform(true);
        dialog.setVisible(true);
    }
}

答案很好,但有几点需要注意:1我会选择默认的不透明,因为Swing会因透明度而变得不稳定。更多的是局部的,而不是完整的,但是当我们可以设置顶部面板的颜色时,为什么还要麻烦呢?2在空布局上展开。。Java GUI必须在不同的操作系统、屏幕大小、屏幕分辨率等上工作,在不同的地区使用不同的PLAF。因此,它们不利于像素完美布局。而是使用布局管理器,或与…的布局填充和边框一起使用。3登录在JDialog或JOptionPane中更常见、更好地显示。4.frame.setVisibletrue;frame.addpanel;应为frame.addpanel;frame.pack;frame.setVisibletrue;请注意,对于任何顶级容器来说,pack都是必需的,并且会破坏空布局,除非在空布局的hack之上添加“特殊措施”hack。@AndrewThompson:谢谢您的点评建议。实际上,在看到您的评论之前,我正在创建一个示例,其中包含了许多建议,但它们非常完美。
@SuppressWarnings("serial")
class LoginAction extends AbstractAction {
    private UserLoginPanel loginPanel;
    
    public LoginAction(UserLoginPanel loginPanel, String name, int mnemonic) {
        super(name);
        putValue(MNEMONIC_KEY, KeyEvent.VK_L);
        this.loginPanel = loginPanel;
    }
    
    @Override
    public void actionPerformed(ActionEvent e) {
        String userName = loginPanel.getUserName();
        char[] password = loginPanel.getPassword();
        
        System.out.println("User Name: " + userName);
        System.out.println("Password:  " + new String(password));
        
        Component source = (Component) e.getSource();
        if (source != null) {
            Window window = SwingUtilities.getWindowAncestor(source);
            if (window != null) {
                window.dispose();
            }
        }
    }
}