开发者

Java: Swing: Set position of JButton

I wanted to realize the following layout:

--------------------------------------------
|                                          |
|                                          |
|                                          |
|                                          |
|                                          |
|                 ----------               |
|                 |   OK   |               |
|                 ----------               |
|                                          |
--------------------------------------------

I wanted to set the size of the button and it shoud be centered in the souther position of the JFrame but it shouldn't have the full width of the JFrame and it shouln't be completly on the bottom of the JFrame, it should have a "margin". It would be also possible to set a absolute pixel position of the button because the JFrame has a fixed width/height. At the moment the button has the full JFrame width/height. Please notice that the JFrame has a background image. My Code:

JFrame j = new JFrame("Foobar");
BufferedImage myImage = null;
try {
    myImage = ImageIO.read(new File("background.png"));
} catch (Exception ex) {}

JPanel p = new ImagePanel(myImage);
p.setLayout(new BorderLayout());

JButton button = new JButton("OK");
button.setSize(80, 200);
button.setFont(new Font("Arial", 1,开发者_开发问答 40));
p.add(button);
f.add(p);

class ImagePanel extends JPanel {
    private Image image;
    public ImagePanel(Image image) {
        this.image = image;
    }
    @Override
    protected void paintComponent(Graphics g) {
        g.drawImage(image, 0, 0, null);
    }
}


A combination of simple layout managers should do the trick. For instance the main JPanel could have an EmptyBorder where you add appropriate margins and could use BorderLayout. Then add a southPanel JPanel that uses FlowLayout arranged FlowLayout.CENTER (the default), and you could add your JButton to this southPanel. Don't forget to call pack and to make sure that all JPanels call setOpaque(false). For example:

  JFrame f = new JFrame("Foobar");
  BufferedImage myImage = null;
  try {
      myImage = ImageIO.read(new File("background.png"));
  } catch (Exception ex) {}

  JPanel p = new ImagePanel(myImage);
  p.setLayout(new BorderLayout());
  int gap = 15;
  p.setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));

  JPanel southPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); // new FlowLayout not needed
  southPanel.setOpaque(false);
  JButton button = new JButton("OK");
  //button.setSize(80, 200);
  button.setPreferredSize(new Dimension(80, 200)); // ?? I don't like this.
  button.setFont(new Font("Arial", 1, 40));

  southPanel.add(button);
  p.add(southPanel, BorderLayout.SOUTH);
  f.add(p);
  f.pack(); // call after everything has been added
  f.setLocationRelativeTo(null); // to center
  f.setVisible(true);


Swing provides many "basic" layouts which, when combined together, can make up most of the layouts one can have in mind. But sometimes, it's easier to create its own layout. In your specific case, that's what I'd recommend.

Here is the part of the Swing tutorial you can follow : http://download.oracle.com/javase/tutorial/uiswing/layout/custom.html

If you really want to do this by combining standard layouts, then you can try this :

  • set the layout of the main panel to BorderLayout
  • add a panel in the SOUTH part of the main panel
  • set the layout of this panel to FlowLayout
  • set an EmptyBorder to this panel, and set the bottom value (this is your margin)
  • add the button to this panel

Alternatively, you can add the border to your main panel. It depends on how you want the other components of the main panel to be laid out.


GroupLayout gl_panel = new GroupLayout(panel);
    gl_panel.setHorizontalGroup(
        gl_panel.createParallelGroup(Alignment.LEADING)
            .addGroup(gl_panel.createSequentialGroup()
                .addGap(188)
                .addComponent(**button**)
                .addContainerGap(189, Short.MAX_VALUE))
    );
    gl_panel.setVerticalGroup(
        gl_panel.createParallelGroup(Alignment.LEADING)
            .addGroup(gl_panel.createSequentialGroup()
                .addGap(106)
                .addComponent(**button**)
                .addContainerGap(171, Short.MAX_VALUE))
    );


If you are frequently solving these kind of layout problems, then I'd strongly suggest downloading and leaning MiGLayout - it's basically a layout manager on steroids that can handle pretty much any layout you can think of.

It takes a bit of time to figure out how to use it, but once you get the principles it is a fantastic tool to have in your armoury.


Try using GridBagLayout, it provides the freedom you want but it's a bit hard to learn. But it can definitely do what you are expecting to do.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜