簡體   English   中英

JPanel背景圖片不適用於其中的JPanel

[英]JPanel background image doesn't apply to a JPanel inside it

我正在開發一個簡單的注冊窗口,該窗口在java應用程序打開時出現。

它是一個JFrame ,里面有一個JPanel ,它有文本字段,標簽和另一個包含文本字段和標簽的面板。 我的問題是外部面板有一個背景圖像,但它不適用於它內部的面板,如下所示:

這是整個窗口代碼:

public void start() {

    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception ex) {
        ex.printStackTrace();
    }

    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    frame = new JFrame("Chat");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //frame.setMaximumSize(new Dimension((int)screenSize.getWidth()-1000, (int)screenSize.getHeight()-1000));
    frame.setMinimumSize(new Dimension((int)screenSize.getWidth()/2-200,(int) screenSize.getHeight()/2));
    frame.setResizable(false);

        welcome = new LoginPanel();
        welcome.setLayout(new BoxLayout(welcome, BoxLayout.Y_AXIS));
        welcome.setBorder(BorderFactory.createEmptyBorder(50, welcome.getWidth()/2-500, 50, welcome.getWidth()/2 -500));

        //repaintThread = new Thread(new RepaintRunnable(frame, welcome));
        //repaintThread.start();


            request = new JLabel("Please fill the required fields below:");
            request.setFont(new Font("Serif", Font.BOLD, 20));
            request.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
            request.setAlignmentX(Component.CENTER_ALIGNMENT);

            userInfo = new JPanel();
            userInfo.setLayout(new BoxLayout(userInfo, BoxLayout.Y_AXIS));
            userInfo.setAlignmentX(Component.CENTER_ALIGNMENT);

                Font fieldType = new Font("Serif", Font.PLAIN, 15);

                PlainDocument doc = new PlainDocument();
                doc.setDocumentFilter(new NameDocument());

                enterFirstName = new JLabel("First name:");
                enterFirstName.setAlignmentX(Component.LEFT_ALIGNMENT);
                enterFirstName.setFont(fieldType);
                firstName = new JTextField(20);
                firstName.setMaximumSize(firstName.getPreferredSize());
                firstName.setDocument(NameDocument.getNewNameDocument(NameDocument.NO_SPACE));
                firstName.getDocument().addDocumentListener(new ChangeDocumentListener());
                firstName.addActionListener(new ConfirmListener());
                firstName.setAlignmentX(Component.LEFT_ALIGNMENT);

                enterSecName= new JLabel("Surname:");
                enterSecName.setAlignmentX(Component.LEFT_ALIGNMENT);
                enterSecName.setFont(fieldType);
                secName = new JTextField(30);
                secName.setMaximumSize(secName.getPreferredSize());
                secName.setDocument(NameDocument.getNewNameDocument(NameDocument.HAS_SPACE));
                secName.getDocument().addDocumentListener(new ChangeDocumentListener());
                secName.addActionListener(new ConfirmListener());
                secName.setAlignmentX(Component.LEFT_ALIGNMENT);

                enterNickname = new JLabel("Nickname (how other people will see you in chat):");
                enterNickname.setAlignmentX(Component.LEFT_ALIGNMENT);
                enterNickname.setFont(fieldType);
                nickname = new JTextField(30);
                nickname.setMaximumSize(nickname.getPreferredSize());
                nickname.setDocument(NameDocument.getNewNameDocument(NameDocument.NO_SPACE));
                nickname.addActionListener(new ConfirmListener());
                nickname.setAlignmentX(Component.LEFT_ALIGNMENT);

            userInfo.add(enterFirstName);
            userInfo.add(firstName);
            userInfo.add(enterSecName);
            userInfo.add(secName);
            userInfo.add(enterNickname);
            userInfo.add(nickname);

            confirm = new JButton("Submit");
            confirm.setAlignmentX(Component.CENTER_ALIGNMENT);
            confirm.setEnabled(false);
            confirm.addActionListener(new ConfirmListener());

        welcome.add(request);
        welcome.add(userInfo);
        welcome.add(new Box.Filler(new Dimension(10, 10), new Dimension(10, 10), new Dimension(10, 10)));
        welcome.add(confirm);

    frame.getContentPane().add(BorderLayout.CENTER, welcome);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}

這是LoginPanel代碼(外部JPanel):

public class LoginPanel extends JPanel {
public void paintComponent(Graphics g) {
    try {
        super.paintComponent(g);
        BufferedImage background = ImageIO.read(new File("Background.jpg"));
        g.drawImage(background, 0, 0, getWidth(), getHeight(), null);
    } catch(Exception ex) {
        ex.printStackTrace();
    }
}
}

如果有人會就如何改進這些代碼給我建議,那也很棒,因為我是Java的初學者。

記得調用setOpaque(false); 在任何內部JPanels(以及其他一些組件 - 雖然不是全部)上覆蓋你的圖像顯示JPanel。 這將允許顯示背景圖像。 您不必使用JLabel執行此操作,因為默認情況下它們是透視(非透明),但您使用JPanels。

所以對你來說它將是:

userInfo = new JPanel();
userInfo.setOpaque(false);

另外一個問題是,你應該從方法的paintComponent內讀取的圖像。 可以經常調用此方法,並且為什么在可以且應該只讀取一次的情況下重新讀取圖像。 更重要的是,這種方法應該盡可能快,因為不必要地減慢它會降低程序的感知響應速度。 一次讀取圖像,並將其存儲在隨后在paintComponent中顯示的變量中。

例如,

public class LoginPanel extends JPanel {
    private BufferedImage background;

    public LoginPanel(BufferedImage background) {
        this.background = background;
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (background != null) {
            g.drawImage(background, 0, 0, getWidth(), getHeight(), this);
        }
    }
}

讀入圖像,然后將其傳遞給LoginPanel類的構造函數。

與您的問題無關但是:

frame.getContentPane().add(BorderLayout.CENTER, welcome);

從JDK 4開始,您不需要使用getContentPane()方法,只需使用frame.add(...) ,該組件就會被添加到內容窗格中。

你也使用了錯誤的add(...)方法。 您正在使用add(約束,組件)。 如果您閱讀該方法的API,它將告訴您使用add(component, constraint)方法。

所以你可以使用:

frame.add(welcome, BorderLayout.CENTER);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM