问题
Okay, I have a Jpanel which is shown as white in the below image using an overlay layout. It holds a ScrollPane holding an image ("No Image Available") and a JButton ("Comment").

I want to position this button in the bottom right hand corner of the JPanel. I have tried multiple layout approaches and I cant seem to get it to work. At most the button moves about 3/4 of the way South-East and I have no idea why.
Any help is greatly appreciated..
回答1:
There are a lot of possible solutions using different layout managers. I don't know the OverlayLayout, but I like WindowBuilder Pro (free): https://developers.google.com/java-dev-tools/wbpro/ for help with Swing design.
Using it, I wrote a SpringLayout implementation of your question (SpringLayout seems like a pain to deal with without a GUI-builder).
JPanel panel = new JPanel();
SpringLayout sl_panel = new SpringLayout();
panel.setLayout(sl_panel);
JButton button = new JButton("Comments");
sl_panel.putConstraint(SpringLayout.SOUTH, button, 0, SpringLayout.SOUTH, panel);
sl_panel.putConstraint(SpringLayout.EAST, button, 0, SpringLayout.EAST, panel);
panel.add(button);
JScrollPane scrollPane = new JScrollPane();
sl_panel.putConstraint(SpringLayout.NORTH, scrollPane, 5, SpringLayout.NORTH, panel);
sl_panel.putConstraint(SpringLayout.WEST, scrollPane, 3, SpringLayout.WEST, panel);
sl_panel.putConstraint(SpringLayout.SOUTH, scrollPane, 3, SpringLayout.SOUTH, panel);
sl_panel.putConstraint(SpringLayout.EAST, scrollPane, 3, SpringLayout.EAST, panel);
panel.add(scrollPane);
JLabel lblNewLabel = new JLabel();
lblNewLabel.setIcon(new ImageIcon(foo.class.getResource("sSdA3.png")));
scrollPane.setViewportView(lblNewLabel);
Here's a picture of the code running:

You can see the button (mine, not the picture of yours...) is floating above the scroll-pane in the bottom. We could adjust the margins above so the button wasn't floating on top of the scroll-bars, but this is just to show you where it is on the z-axis.
回答2:
Add the first JPanel
with image at CENTER
position of the content pane and Simply set the Layout of your JPanel to FlowLayout.RIGHT
and add your JButton
to it, now add this JPanel
to the PAGE_END
position of the BorderLayout
of your content pane. Have a look at this example
import java.awt.*;
import java.awt.event.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class ApplicationCloseExample
{
private Image image;
private static final String HTML =
"<html>" +
"<style type'text/css'>" +
"body, html { padding: 0px; margin: 0px; }" +
"</style>" +
"<body>" +
"<img src='http://pscode.org/media/starzoom-thumb.gif'" +
" width=320 height=240>" +
"";
private void displayGUI()
{
final JFrame frame = new JFrame("Application Close Example");
frame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent we)
{
int result = JOptionPane.showConfirmDialog(
frame, "Do you want to Exit ?"
, "Exit Confirmation : ", JOptionPane.YES_NO_OPTION);
if (result == JOptionPane.YES_OPTION)
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
else if (result == JOptionPane.NO_OPTION)
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}
});
JPanel contentPane = new JPanel();
contentPane.setOpaque(true);
JLabel label = new JLabel(HTML);
contentPane.add(label);
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 5));
JButton button = new JButton("Comment");
bottomPanel.add(button);
frame.getContentPane().add(contentPane, BorderLayout.CENTER);
frame.getContentPane().add(bottomPanel, BorderLayout.PAGE_END);
frame.pack();
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new ApplicationCloseExample().displayGUI();
}
});
}
}
Here is the output :

回答3:
You mentioned using an OverlayLayout
; do you want the button to actually overlap the image?
If that isn't important to you, use one of the other good suggestions, as they are much simpler. But if you really want the button to overlap the image, here's one solution: Use a JLayeredPane
to layer two JPanel
s, which in turn lay out the button and the image. Unfortunately, JLayeredPane
doesn't have a layout manager, so it is necessary to add a component listener to resize the JPanel
s whenever the JLayeredPane
is resized.
Here is a SSCCE:
public class SSCCE {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = frame.getContentPane();
contentPane.setLayout(new BorderLayout());
final JLayeredPane layeredPane = new JLayeredPane();
contentPane.add(layeredPane,BorderLayout.CENTER);
final JPanel btnPane = new JPanel(new GridBagLayout());
btnPane.setOpaque(false);
JButton btn = new JButton("Comment");
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.anchor = GridBagConstraints.SOUTHEAST;
btnPane.add(btn,gbc);
final JPanel lblPane = new JPanel(new GridBagLayout());
lblPane.setBackground(Color.CYAN);
JLabel lbl = new JLabel("No Image Available");
gbc = new GridBagConstraints();
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.anchor = GridBagConstraints.CENTER;
lblPane.add(lbl,gbc);
layeredPane.add(btnPane,0);
layeredPane.add(lblPane,1);
layeredPane.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
lblPane.setBounds(0, 0, layeredPane.getWidth(), layeredPane.getHeight());
btnPane.setBounds(0, 0, layeredPane.getWidth(), layeredPane.getHeight());
}
});
frame.setSize(300,200);
frame.setVisible(true);
}
}
回答4:
I'll recommand you to use GridBagLayout
instead of the default layout. With GridBagLayout you control everything.
Here is a link to help you: how to use GridBagLayout
回答5:
I would say a JPanel
with a BorderLayout
with the button added in the EAST
position, and put that panel in the main container (with a BorderLayout
) at the SOUTH
position.
So you get:
-------------
| |
| |
| Image |
| |
|-----------|
|______Button
回答6:
Check SpringLayout. It allows you to position the element to a certain distance from the NORTH, WEST, EAST or SOUTH of a component. Your code will look like:
SpringLayout layout = new SpringLayout();
setLayout(layout);
...
add(_button);
...
layout.putConstraint(SpringLayout.EAST, _button, -20, SpringLayout.EAST, this);
layout.putConstraint(SpringLayout.SOUTH, _button, -20, SpringLayout.SOUTH, this);
来源:https://stackoverflow.com/questions/10741506/jbutton-positioning-issues