CardLayout无法在Windows上正确呈现

时间:2016-06-23 22:58:13

标签: java windows swing jbutton cardlayout

我一直在为新项目的登录屏幕工作,并遇到了一个奇怪的渲染"错误"在Windows上使用CardLayout时。

Mac上的SignUp屏幕:SignUp Screen Mac

屏幕在我的Mac电脑上正确加载,但是在点击"注册"或点击"返回"。

Windows上的相同屏幕:SignUp Screen Windows

正如您所看到的,在Windows上,SignUp" card"来自CardLayout的是通过Login" card"没有隐藏另一个,反之亦然,不像在mac上。

现在我的问题是,这可能是因为透明的背景造成的,因此窗户认为后面的人应该仍然可见,或者可能是创造一个全新的卡片#34;每次我切换,或者只是忘记隐藏在后面的那一个?

为什么这适用于Mac而不适用于Windows?

而且,我怎么能解决这个问题?

我会把整个课程都放在一起,这样你就可以自己测试了。

(旁注:您可能还会注意到按钮"注册"显示窗口上的白色按钮形状,即使它有btnRegister.setBorder(null);设置(适用于Mac))

完整的一个类代码:

package testing;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import utilities.ComponentMover;

import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Insets;

import javax.swing.JSeparator;
import javax.swing.JPasswordField;

@SuppressWarnings("serial")
public class ClientStarter extends JFrame implements ActionListener {

JPanel cards;

private int height = 450;
private int width = 700;
private int trasparancy = 90;
private int labelWidth = 400;

final static String BACK = "Back";
final static String REGISTER = "Register";

private Color textLine = Color.GRAY;
private Color textColor = Color.WHITE;
private Color tipColor = Color.GRAY;
private Color disabledTipColor = new Color(90, 90, 90);



//   LOGIN //

JPanel loginCard;

public static JTextField usernameIn = new JTextField();
private JLabel userLabel = new JLabel("Username :");

public static JPasswordField passwordIn = new JPasswordField();
private JLabel passLabel = new JLabel("Password :");

private JButton btnLogin = new JButton("Login");
private JButton btnRegister = new JButton(REGISTER);
private JLabel registerLabel = new JLabel("Don't own an Account? ");

private JSeparator separatorUser = new JSeparator();
private JSeparator separatorPass = new JSeparator();

//    SIGNUP   //

JPanel joinCard;

public static JTextField emailNew = new JTextField();
public static JLabel newEmailLabel = new JLabel("Email : (Not Available)");

public static JTextField usernameNew = new JTextField();
public static JLabel newUserLabel = new JLabel("Username :");

public static JTextField passwordNew = new JTextField();
public static JLabel newPassLabel = new JLabel("Password :");

public static JTextField passwordNew2 = new JTextField();
public static JLabel newPassLabel2 = new JLabel("Re-enter password :");


private JButton btnSignUp = new JButton("Signup");
private JButton btnBack = new JButton(BACK);

private JSeparator separatorMailNew = new JSeparator();
private JSeparator separatorUserNew = new JSeparator();
private JSeparator separatorPassNew = new JSeparator();
private JSeparator separatorPassNew2 = new JSeparator();

public ClientStarter() {
    getContentPane().setBackground(Color.GRAY);
    setUndecorated(true);
    setBackground(new Color(0, 0, 0, trasparancy));
    setTitle("EnChant");
    setSize(width, height);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
    setVisible(true);
    setResizable(false);

    //Create the cards
    //     LOGIN     //
    Font avenir = new Font("Avenir", Font.PLAIN, 18);

    loginCard = new JPanel();
    loginCard.setLayout(null);

    usernameIn.setBounds(348, 150, 327, 35);
    usernameIn.setColumns(10);
    usernameIn.setFont(avenir);
    usernameIn.setBorder(null);

    passwordIn.setBounds(348, usernameIn.getY() + 74, 327, 35);
    passwordIn.setColumns(10);
    passwordIn.setFont(avenir);
    passwordIn.setBorder(null);

    userLabel.setBounds(usernameIn.getX(), usernameIn.getY() - 20, labelWidth, 16);
    userLabel.setFont(avenir);

    passLabel.setBounds(passwordIn.getX(), passwordIn.getY() - 20, labelWidth, 16);
    passLabel.setFont(avenir);

    btnLogin.setBounds(348, passwordIn.getY() + 81, 327, 45);
    btnLogin.addActionListener(this);

    registerLabel.setBounds(btnLogin.getX(), btnLogin.getY() + btnLogin.getHeight() + 5, labelWidth, 16);
    registerLabel.setFont(new Font("Avenir", Font.PLAIN, 13));  
    btnRegister.setBounds(btnLogin.getX() + 130, registerLabel.getY() - 1, 70, 16);
    btnRegister.addActionListener(this);
    btnRegister.setBorder(null);


    loginCard.setBackground(new Color(0, 0, 0, trasparancy));

    usernameIn.setBackground(new Color(0, 0, 0, 0));
    usernameIn.setForeground(textColor);

    passwordIn.setBackground(new Color(0, 0, 0, 0));
    passwordIn.setForeground(textColor);


    userLabel.setForeground(tipColor);
    passLabel.setForeground(tipColor);


    btnLogin.setForeground(new Color(70, 130, 180));
    btnLogin.setBackground(Color.WHITE);

    btnRegister.setForeground(new Color(70, 130, 180));
    registerLabel.setForeground(tipColor);


    separatorUser.setForeground(textLine);
    separatorUser.setBounds(usernameIn.getX(), usernameIn.getY()+usernameIn.getHeight()-8, usernameIn.getWidth(), 6);

    separatorPass.setForeground(textLine);
    separatorPass.setBounds(passwordIn.getX(), passwordIn.getY()+passwordIn.getHeight()-8, passwordIn.getWidth(), 6);

    loginCard.add(usernameIn);
    loginCard.add(separatorUser);
    loginCard.add(userLabel);
    loginCard.add(passwordIn);
    loginCard.add(separatorPass);
    loginCard.add(passLabel);
    loginCard.add(btnLogin);
    loginCard.add(btnRegister);
    loginCard.add(registerLabel);



    //    SIGNUP   //
    joinCard = new JPanel();
    joinCard.setLayout(null);

    emailNew.setBounds(348, 62, 327, 35);
    emailNew.setColumns(10);
    emailNew.setFont(avenir);
    emailNew.setBorder(null);
    emailNew.setEditable(false);

    usernameNew.setBounds(348, emailNew.getY() + 74, 327, 35);
    usernameNew.setColumns(10);
    usernameNew.setFont(avenir);
    usernameNew.setBorder(null);

    passwordNew.setBounds(348, usernameNew.getY() + 74, 327, 35);
    passwordNew.setColumns(10);
    passwordNew.setFont(avenir);
    passwordNew.setBorder(null);

    passwordNew2.setBounds(348, passwordNew.getY() + 74, 327, 35);
    passwordNew2.setColumns(10);
    passwordNew2.setFont(avenir);
    passwordNew2.setBorder(null);

    //32, 106, 180, 254  : 2, 76, 150, 224

    newEmailLabel.setBounds(emailNew.getX(), emailNew.getY() - 20, labelWidth, 16);
    newEmailLabel.setFont(avenir);

    newUserLabel.setBounds(usernameNew.getX(), usernameNew.getY() - 20, labelWidth, 16);
    newUserLabel.setFont(avenir);

    newPassLabel.setBounds(passwordNew.getX(), passwordNew.getY() - 20, labelWidth, 16);
    newPassLabel.setFont(avenir);

    newPassLabel2.setBounds(passwordNew2.getX(), passwordNew2.getY() - 20, labelWidth, 16);
    newPassLabel2.setFont(avenir);


    btnSignUp.setBounds(348, passwordNew2.getY() + 71, 327, 45); //335  // +81
    btnSignUp.addActionListener(this);

    btnBack.setBounds(btnSignUp.getX()-70, btnSignUp.getY(), 70, 45); //380 
    btnBack.addActionListener(this);


    joinCard.setBackground(new Color(0, 0, 0, trasparancy));

    emailNew.setBackground(new Color(0, 0, 0, 0));
    emailNew.setForeground(textColor);

    usernameNew.setBackground(new Color(0, 0, 0, 0));
    usernameNew.setForeground(textColor);

    passwordNew.setBackground(new Color(0, 0, 0, 0));
    passwordNew.setForeground(textColor);

    passwordNew2.setBackground(new Color(0, 0, 0, 0));
    passwordNew2.setForeground(textColor);

    newEmailLabel.setForeground(disabledTipColor);
    newUserLabel.setForeground(tipColor);
    newPassLabel.setForeground(tipColor);
    newPassLabel2.setForeground(tipColor);

    btnSignUp.setForeground(new Color(70, 130, 180));
    btnBack.setBackground(Color.WHITE);


    separatorMailNew.setBounds(emailNew.getX(), emailNew.getY()+emailNew.getHeight()-8, emailNew.getWidth(), 6);
    separatorMailNew.setForeground(textLine);

    separatorUserNew.setBounds(usernameNew.getX(), usernameNew.getY()+usernameNew.getHeight()-8, usernameNew.getWidth(), 6);
    separatorUserNew.setForeground(textLine);

    separatorPassNew.setBounds(passwordNew.getX(), passwordNew.getY()+passwordNew.getHeight()-8, passwordNew.getWidth(), 6);
    separatorPassNew.setForeground(textLine);

    separatorPassNew2.setBounds(passwordNew2.getX(), passwordNew2.getY()+passwordNew2.getHeight()-8, passwordNew2.getWidth(), 6);
    separatorPassNew2.setForeground(textLine);

    joinCard.add(emailNew);
    joinCard.add(newEmailLabel);
    joinCard.add(usernameNew);
    joinCard.add(newUserLabel);
    joinCard.add(passwordNew);
    joinCard.add(newPassLabel);
    joinCard.add(passwordNew2);
    joinCard.add(newPassLabel2);
    joinCard.add(btnSignUp);
    joinCard.add(btnBack);
    joinCard.add(separatorMailNew);
    joinCard.add(separatorUserNew);
    joinCard.add(separatorPassNew);
    joinCard.add(separatorPassNew2);



    //    End    //

    JPanel whiteRectLogin = new JPanel();
    whiteRectLogin.setBackground( Color.WHITE );
    whiteRectLogin.setBounds(0, 0, 250, height);
    loginCard.add(whiteRectLogin);

    JPanel whiteRectJoin = new JPanel();
    whiteRectJoin.setBackground( Color.WHITE );
    whiteRectJoin.setBounds(0, 0, 250, height);
    joinCard.add(whiteRectJoin);



    cards = new JPanel(new CardLayout());
    cards.setBackground(new Color(0, 0, 0, trasparancy));

    cards.add(loginCard, BACK);
    cards.add(joinCard, REGISTER);

    getContentPane().add(cards); 

    //Top, Left, bottom, right
    ComponentMover cm = new ComponentMover(this, this);
    cm.setEdgeInsets(new Insets(-50, 1, 0, -50));

    validate();

    repaint();
    getContentPane().setLayout(null);


}


public void actionPerformed(ActionEvent e) {
    if(e.getSource() == btnRegister) {
        CardLayout cl = (CardLayout) (cards.getLayout());
        cl.show(cards, REGISTER);
        loginCard.setVisible(false);

    }
    if(e.getSource() == btnBack) {
        CardLayout cl = (CardLayout) (cards.getLayout());
        cl.show(cards, BACK);
        loginCard.setVisible(false);
    }
    if(e.getSource() == btnSignUp) {
        //new SignUpCheck();
    }
}

public static void main(String[] args) {
    new ClientStarter();
}
}

1 个答案:

答案 0 :(得分:2)

  

这可能是因为透明背景

造成的

可能。 Swing不会正确渲染透明背景。 Swing期望组件完全不透明或完全透明。

查看Backgrounds With Transparency以获取问题的完整描述和几个解决方案。

您可以使用以下代码进行自定义绘制每个组件:

JPanel panel = new JPanel()
{
    protected void paintComponent(Graphics g)
    {
        g.setColor( getBackground() );
        g.fillRect(0, 0, getWidth(), getHeight());
        super.paintComponent(g);
    }
};
panel.setOpaque(false); // background of parent will be painted first
panel.setBackground( new Color(255, 0, 0, 20) );
frame.add(panel);

或者您可以使用AlphaContainer班为您进行绘画。

此外,您还有其他几个问题:

  1. 不要为Swing组件使用静态变量。这不是static关键字的正确用法。

  2. 不要使用null布局和setBounds()。 Swing旨在与布局管理器一起使用。布局管理器在多个平台上运行良好。

  3. 不要使用alpha值0. 0表示完全透明,因此只需在组件上使用setOpaque(false)方法。

  4. 不要继续创建新的Color个对象。每个组件都可以使用相同的Color对象。它可以节省资源,并且可以更轻松地同时更改所有组件的所有颜色。

  5. 不要在类的构造函数中使用validate()和repaint()。在调用setVisible(true)之前,应将所有组件添加到框架中,以便不需要这些方法。