java 字段未与 GridBagLayout 对齐,无法实现背景图片

java Fields not aligning right with GridBagLayout, unable to implement background image

所以我一直在努力学习 java 中的写作,并且我越来越接近可用的界面,但我遇到了 2 个问题。当我尝试实现覆盖其中的绘画组件的 CloudPanel 时,它不允许我在该面板中设置 gridbaglayout。为了在弄清楚为什么我无法完成这项工作的同时尝试让其他一切正常工作,我创建了一个新的基本 JPanel 来填充表单。它几乎是正确的,但是它迫使 Price JTextField 离开屏幕的一侧或者只是不显示它,而它的标签位于它的行的中心而不是它应该的左侧。知道我在这里做错了什么吗? ** 编辑 ** 在我的应用程序中显示图像的 2 种方法试图实现,但都不起作用。现在可能被注释掉以测试另一种方法的 bLogin jPanel 仍然无法正常工作,需要澄清 setPreferredSize 建议,以及当我将 imageIcon grabbagconstraints 的代码切换为现在显示的内容而不是与其他方法相同时其中,所有 jlabels 和 jtextfields 重叠。如果我删除其他 lGUI.add 组件中不存在的所有行,那么它将恢复正常,除了没有图像加载,无论是作为标签还是背景。我在验证方面还有更多工作要做(ID 为 int,我会说 6 个字符,这样我可以选择要修改的限制,Price 为 double,我希望可以从中推断出浮点数)。后续步骤?

package newprovider;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;

/*@Michael Christopher,  author/owner */
public class NewProvider {
/** @param args the command line arguments*/

public static class CloudPanel extends JPanel {
    //paint background
    String backgroundPath="/images/CloudBack1.png";
    @Override
    public void paintComponent(Graphics cloud){
    super.paintComponent(cloud);
    Image back = new ImageIcon(getClass().getResource(backgroundPath)).getImage();
    cloud.drawImage(back, 0,0, this);
}
    }
public static void createGUI() {
    //build main frame
    JFrame mainFrame = new JFrame();
    mainFrame.setTitle("New Provider Interface");
   // mainFrame.setOpaque(false);
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //Create the MenuBar - needs menu options
    JMenuBar maintenanceMenuBar = new JMenuBar ();
    maintenanceMenuBar.setOpaque(true);
    maintenanceMenuBar.setBackground(new Color(176,224,230));
    maintenanceMenuBar.setPreferredSize(new Dimension(500, 20));
    //Create Logo
    ImageIcon LogoBox = new ImageIcon("/images/CloudBack.png");
    JLabel logoLabel = new JLabel(LogoBox);
    //create variables
    int addProviderCheck;
    String[] options = {"Yes","No"};
    String[] newExit = {"Exit", "New"};
    Dimension d = new Dimension(400, 224);

    //create labels and JTextFields
    JLabel labelID = new JLabel ("New ProviderID");
    final JTextField textID = new JTextField("providerID ", 20);
    JLabel labelName = new JLabel ("New Provider Name");
    final JTextField textName = new JTextField("Provider Name ", 20);
    JLabel labelPrice = new JLabel ("New Provider Price");
    final JTextField textPrice = new JTextField ("Price ", 20);
    //make Submit, Clear, & Exit buttons
    JButton submit = new JButton("Submit");   
    JButton clear = new JButton("Clear");
    JButton exit = new JButton("Exit");        
    //build main Panel
    CloudPanel bLogin = new CloudPanel();
    bLogin.setPreferredSize(d);
    //bLogin.setLayout(new GridBagLayout());
    bLogin.setOpaque(true);
    JPanel Login = new JPanel(new GridBagLayout());
    JPanel buttonBar = new JPanel(new GridBagLayout());
    buttonBar.setBackground(Color.red);
    buttonBar.setSize(40, 400);
    Login.setOpaque(false);
     //GridBag constraints for buttonBar and InputPane4
    GridBagConstraints bGUI = new GridBagConstraints();
    //Adding buttons to buttonBar Panel
    bGUI.insets = new Insets(5,20,5,20);
    bGUI.gridx = 0;
    bGUI.gridy = 1;
    buttonBar.add(submit,bGUI);
    bGUI.gridx = 1;
    bGUI.gridy = 1;
    buttonBar.add(clear,bGUI);
    bGUI.gridx = 2;
    bGUI.gridy = 1;
    buttonBar.add(exit,bGUI);
    //GridBag Adding Labels and Text to Login with Constraints
    GridBagConstraints lGUI = new GridBagConstraints();
    lGUI.insets = new Insets(50,15,0,0);
    lGUI.anchor = GridBagConstraints.NORTH;
    lGUI.fill = GridBagConstraints.BOTH;
    lGUI.ipady = 100;
    lGUI.weighty = 1.0;
    lGUI.gridx = 0;
    lGUI.gridwidth = 3;
    lGUI.gridy = 0;
    Login.add(logoLabel, lGUI);
    lGUI.anchor = GridBagConstraints.WEST;
    lGUI.gridx = 0;
    lGUI.gridy = 1;
    Login.add(labelID,lGUI);
    lGUI.anchor = GridBagConstraints.EAST;
    lGUI.gridx = 2;
    lGUI.gridy = 1;
    Login.add(textID,lGUI);
    lGUI.anchor = GridBagConstraints.WEST;
    lGUI.gridx = 0;
    lGUI.gridy = 3;
    Login.add(labelName,lGUI);
    lGUI.anchor = GridBagConstraints.EAST;
    lGUI.gridx = 2;
    lGUI.gridy = 3;
    Login.add(textName,lGUI);
    lGUI.anchor = GridBagConstraints.WEST;
    lGUI.gridx = 0;
    lGUI.gridy = 5;
    Login.add(labelPrice,lGUI);
    lGUI.anchor = GridBagConstraints.EAST;
    lGUI.gridx = 2;
    lGUI.gridy = 5;
    Login.add(textPrice,lGUI);
    //add panels to frame
    mainFrame.add(maintenanceMenuBar, BorderLayout.NORTH);
    //bLogin.add(Login, BorderLayout.CENTER);
    //mainFrame.add(bLogin, BorderLayout.CENTER);
    mainFrame.add(Login, BorderLayout.CENTER);
    mainFrame.add(buttonBar, BorderLayout.SOUTH);
    SwingUtilities.invokeLater(new FocusGrabber(clear));
    //empty fields on mouse clicks
    textID.addMouseListener(new MouseListener() { @Override
        public void mouseClicked(MouseEvent e) {textID.setText("");}
        @Override public void mousePressed(MouseEvent e) { //throw new UnsupportedOperationException("Not supported yet."); 
        }@Override public void mouseReleased(MouseEvent e) { //throw new UnsupportedOperationException("Not supported yet."); 
        }@Override public void mouseEntered(MouseEvent e) { //throw new UnsupportedOperationException("Not supported yet."); 
        }@Override public void mouseExited(MouseEvent e) { //throw new UnsupportedOperationException("Not supported yet."); 
        }    }    );
    textName.addMouseListener(new MouseListener() { @Override
        public void mouseClicked(MouseEvent e) {textName.setText("");}
        @Override public void mousePressed(MouseEvent e) { //throw new UnsupportedOperationException("Not supported yet."); 
        }@Override public void mouseReleased(MouseEvent e) { //throw new UnsupportedOperationException("Not supported yet."); 
        }@Override public void mouseEntered(MouseEvent e) { //throw new UnsupportedOperationException("Not supported yet."); 
        }@Override public void mouseExited(MouseEvent e) { //throw new UnsupportedOperationException("Not supported yet."); 
        }    }    );
    textPrice.addMouseListener(new MouseListener() { @Override
        public void mouseClicked(MouseEvent e) {textPrice.setText("");}
        @Override public void mousePressed(MouseEvent e) { //throw new UnsupportedOperationException("Not supported yet."); 
        }@Override public void mouseReleased(MouseEvent e) { //throw new UnsupportedOperationException("Not supported yet."); 
        }@Override public void mouseEntered(MouseEvent e) { //throw new UnsupportedOperationException("Not supported yet."); 
        }@Override public void mouseExited(MouseEvent e) { //throw new UnsupportedOperationException("Not supported yet."); 
        }    }    );
    //focusListeners for Name Field
    textName.addFocusListener(new FocusListener(){ @Override
        public void focusGained(FocusEvent e) { /* throw new UnsupportedOperationException("Not supported yet.");*/ }
        @Override public void focusLost(FocusEvent e) {
                if (!e.isTemporary()) {
                String  checkName = textName.getText();
                Boolean validName = false;
                if (checkName.isEmpty()){JOptionPane.showMessageDialog(mainFrame, "Please enter a valid ID.");}
                else while (validName = false){try {
                        String Name = textName.getText();
                    }catch (NumberFormatException e1){
                        JOptionPane.showMessageDialog(mainFrame, "Please enter a valid ID.");
                        SwingUtilities.invokeLater(new FocusGrabber(textName));
                    }finally {validName = true;}
    }    }    }    }    );
    //ActionListener for Submit button
    submit.addActionListener((ActionEvent e) -> {
        String Name;
        Name = textName.getText();
        int ID = Integer.parseInt(textID.getText());
        double Price = Double.parseDouble(textPrice.getText());
        int submitPress = JOptionPane.showOptionDialog(null,
                "ProviderID: " + ID + "\n" + "Provider Name: " + Name +"\n" 
                        + "Provider Price: " + Price, "Please Verify Content",
                        JOptionPane.YES_NO_OPTION,JOptionPane.WARNING_MESSAGE,
                        null, options,options[0]);
        if (submitPress <= 0) {
            //Store Displayed data
            int providerID = ID;
            String providerName = Name;
            Double providerPrice = Price;
            System.out.println(providerID);
            System.out.println(providerName);
            System.out.println(providerPrice);//add method to store println()s to database
            //Popup Confirm dialog to reset fields or exit
            int confirmNew = JOptionPane.showOptionDialog(null, "New Provider Confirmed\n" + "Would you like to exit the module or add another provider?", "Confirmation", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, newExit, newExit[0]);
            if (confirmNew <=0) {
                mainFrame.setVisible(false);
                mainFrame.dispose(); 
            }   else if (confirmNew > 0) {
                textID.setText("providerID");
                textName.setText("Provider Name");
                textPrice.setText("Price");
        }       }
        else if (submitPress > 0) {
            textID.setText("providerID");
            textName.setText("Provider Name");
            textPrice.setText("Price"); }
    });
    //ActionListener for clear button
    clear.addActionListener((ActionEvent e) -> {
        textID.setText("providerID");
        textName.setText("Provider Name");
        textPrice.setText("Price");
    });
    //ActionListener for Exit Button
    exit.addActionListener((ActionEvent e) -> {
        mainFrame.setVisible(false);
        mainFrame.dispose();
    });
//verify intent to add new provider to system before continuing
addProviderCheck = JOptionPane.showOptionDialog(null,
     "This will add a new service provider to the database.\n" 
    + "Are you sure you wish to continue?",
     "Please Verify Intent",JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE,null, options,options[0]); 
if (addProviderCheck <= 0) {
              //Display Window
    mainFrame.pack();
    mainFrame.setSize(400, 400);
    mainFrame.setVisible(true);}
else { //else close app
    mainFrame.setVisible(false);
    mainFrame.dispose();
}
  //  mainFrame.setVisible(true);
}
public static void main(String[] args){
    //draw and show the GUI
    javax.swing.SwingUtilities.invokeLater(() -> {
        createGUI();
    });        
    //store new provider data
    }
}                                                                        Ive got it working (after manual resize) - well, the image as a logo is working, not the background.  I've tried defining the size different places and none of them are changing it, it starts to small and once I resize it slightly wider and nearly twice as tall it then snaps to proper alignment.  Here's the pieces I added:   
    mainFrame.setSize(new Dimension(800,425));
    ImageIcon LogoBox = new ImageIcon("images/CloudBack.png");
    JLabel logoLabel = new JLabel(LogoBox);                                                                                                                        
    //create panel to stack logo and login
    JPanel logFrame = new JPanel(new GridBagLayout());
    logFrame.setOpaque(false);                                                              [....Unchanged code...]
    JPanel Login = new JPanel(new GridBagLayout());
    Login.setSize(800, 425);
    JPanel buttonBar = new JPanel(new GridBagLayout());
    buttonBar.setBackground(Color.red);
    buttonBar.setSize(40, 400);
    Login.setOpaque(false);                                               [....Unchanged code....]                         
    Login.add(textPrice,lGUI);
    //GridBag Adding login and logo to panel
    GridBagConstraints pGUI = new GridBagConstraints();
    pGUI.insets = new Insets(5,10,15,20);
    pGUI.anchor = GridBagConstraints.CENTER;
    pGUI.fill = GridBagConstraints.BOTH;
    pGUI.ipady = 400;
    pGUI.weighty = 1.0;
    pGUI.gridx = 0;
    pGUI.gridy = 0;
    logFrame.add(logoLabel, pGUI);
    pGUI.anchor = GridBagConstraints.SOUTH;
    pGUI.gridx = 0;
    pGUI.gridy = 1;
    logFrame.add(Login, pGUI);                                        [....Unchanged Code....]
    mainFrame.add(logFrame, BorderLayout.CENTER);                        [....Unchanged Code....]

. When I try to implement the CloudPanel that I overrode the paint component in, it won't let me set a gridbaglayout in that panel.

不确定你到底在问什么,但我注意到两个问题。

  1. 您创建了一个 CloudPanel 实例,但您从未对该实例执行任何操作。也就是说,您不将面板添加到另一个面板或将任何组件添加到面板。

  2. 您没有将 CloudPanel class 的 getPreferredSize() 方法重写为图像的大小。因此大小将是 (0, 0) 所以你不能将它添加到另一个面板。

此外,您永远不应该 I/O 在绘画方法中。每当 Swing 确定组件需要重新绘制并且您不想继续读取图像时,将调用绘制方法。

您的 textPrice 字段没有显示,因为您没有将它添加到面板,只需对一行代码做一点小改动,

lGUI.gridx = 0;
lGUI.gridy = 3;
Login.add(labelPrice,lGUI);
lGUI.gridx = 1;
lGUI.gridy = 3;
Login.add(textPrice,lGUI);  <===== this one, you are adding labelPrice again