问题
I'm trying to think of the best layout manager to achieve the picture below. I know absolute positioning is what I am used to, but I can't get the background image using this. GridBagLayout
is excellent, but horrifically hard when ever I try I get a separate image for each grid.
Does anyone know an easy way out of this, or easy code to achieve the following?

回答1:
There are a number of ways you can achieve this.
The simplest might be to just use what's already available

If you don't need the background to be scaled at run-time (ie you can get away with a non-resizable window), simply using a JLabel
as the primary container could make your life significantly easier.
public class LabelBackground {
public static void main(String[] args) {
new LabelBackground();
}
public LabelBackground() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new LoginPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class LoginPane extends JLabel {
public LoginPane() {
try {
setIcon(new ImageIcon(ImageIO.read(getClass().getResource("/background.jpg"))));
} catch (IOException ex) {
ex.printStackTrace();
}
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.EAST;
gbc.insets = new Insets(2, 2, 2, 2);
gbc.gridx = 0;
gbc.gridy = 0;
JLabel nameLabel = new JLabel("Name: ");
nameLabel.setForeground(Color.WHITE);
JLabel passwordLabel = new JLabel("Password: ");
passwordLabel.setForeground(Color.WHITE);
add(nameLabel, gbc);
gbc.gridy++;
add(passwordLabel, gbc);
gbc.anchor = GridBagConstraints.WEST;
gbc.gridx++;
gbc.gridy = 0;
add(new JTextField(20), gbc);
gbc.gridy++;
add(new JTextField(20), gbc);
gbc.gridy++;
gbc.insets = new Insets(10, 2, 2, 2);
gbc.anchor = GridBagConstraints.EAST;
add(new JButton("Submit"), gbc);
}
}
}
Updated with example of left alignment
At the end of the constructor, add...
JPanel filler = new JPanel();
filler.setOpaque(false);
gbc.gridx++;
gbc.weightx = 1;
add(filler, gbc);

You might like to take a look at How to use GridBagLayout for more details
回答2:
There are several ways to do it. These are what I can think of at the moment:
- Create a subclass of JComponent.
- Override the paintComponent(Graphics g) method to paint the image that you want to display.
- Set the content pane of the
JFrame
to be this subclass.
Some sample code:
class ImagePanel extends JComponent {
private Image image;
public ImagePanel(Image image) {
this.image = image;
}
@Override
protected void paintComponent(Graphics g) {
g.drawImage(image, 0, 0, null);
}
}
// elsewhere
BufferedImage myImage = ImageIO.read(...);
JFrame myJFrame = new JFrame("Image pane");
myJFrame.setContentPane(new ImagePanel(myImage));
Note that this code does not handle re-sizing the image to fit the JFrame
, if that's what you wanted.
来源:https://stackoverflow.com/questions/14926425/layout-manager-for-background-images-and-text