如何使组件在面板的某个区域内居中

Posted

技术标签:

【中文标题】如何使组件在面板的某个区域内居中【英文标题】:How to have components centered within a certain area of the panel 【发布时间】:2014-05-23 11:42:18 【问题描述】:

我想定位一些按钮,使它们居中,但在面板的右侧(浅框所在的位置)。 当窗口重新调整大小时,背景会重新调整大小,因此我希望按钮在面板的该区域内保持居中。 背景被分成两半,左侧是徽标,右侧是浅色框(我想要放置按钮的位置)。 我需要四个按钮,以便它们在它们的顶部有四个浅色框,并在重新调整窗口大小时保留在那里,因此所有位置/大小都需要相对于窗口的大小。 当窗口重新调整大小时(就像我使用组件侦听器对背景所做的那样),我怎么能做到这一点而不必手动调整按钮的大小/重新定位按钮?我考虑过可能使用盒子布局,但这只位于程序的中心。

(忽略左上角的按钮)

【问题讨论】:

调整窗口大小时,图片会调整大小吗?如果没有,图片会在哪里? 是的,放大/缩小以适应窗口的大小,每一面只占面板的一半,它们实际上是单独的图像,左边的卡片是动画 gif ,而淡色框是图像,两者都包含在 JLabel 中作为 ImageIcon。 【参考方案1】:

您可以嵌套面板。您可能要考虑的一种选择是使用GridBagLayout(或标签)创建四个面板。使用一些简单的 Photoshop 剪下其中一个浅色框,并将其用作每个面板/标签的背景。然后,您可以将每个按钮添加到面板/标签的顶部。这样,您将确保无论框架尺寸如何,按钮都将显示为苍白图像

这是使用这些图像的示例

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ButtonsWithBackground 

    public ButtonsWithBackground() 
        BufferedImage[] images = getImages();
        ImagePanel backgroundPanel = new ImagePanel(images[0]);
        backgroundPanel.setLayout(new GridLayout(1, 2, 0, 0));
        JPanel buttonsPanel = createButtonsPanel(images);
        JPanel leftPanel = new JPanel();
        leftPanel.setOpaque(false);

        backgroundPanel.add(leftPanel);
        backgroundPanel.add(buttonsPanel);

        JFrame frame = new JFrame();
        frame.setContentPane(backgroundPanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    

    private JPanel createButtonsPanel(BufferedImage[] images) 
        JPanel panel = new JPanel(new GridLayout(4, 1));
        for (int i = 0; i < 4; i++) 
            ImagePanel buttonPanel = new ImagePanel(images[1]);
            buttonPanel.add(new JButton("Hey I'm a Button"));
            panel.add(buttonPanel);
        
        return panel;
    

    private BufferedImage[] getImages() 
        BufferedImage[] bi = new BufferedImage[2];
        try 
            BufferedImage bg = ImageIO.read(new URL("http://i.stack.imgur.com/YFfO4.png"));
            BufferedImage jbtbg = ImageIO.read(new URL("http://i.stack.imgur.com/DtO9U.png"));
            bi[0] = bg;
            bi[1] = jbtbg;
         catch (IOException ex) 
            Logger.getLogger(ButtonsWithBackground.class.getName()).log(Level.SEVERE, null, ex);
        
        return bi;
    

    private class ImagePanel extends JPanel 
        private BufferedImage img;

        public ImagePanel(BufferedImage img) 
            this.img = img;
            setLayout(new GridBagLayout());
        

        @Override
        protected void paintComponent(Graphics g) 
            super.paintComponent(g);
            g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
        
        @Override
        public Dimension getPreferredSize() 
            return new Dimension(img.getWidth(), img.getHeight());
        
    

    public static void main(String[] args) 
        SwingUtilities.invokeLater(new Runnable()
            public void run() 
                new ButtonsWithBackground();
            
        );
    

您可以调整窗口大小,按钮将保持原位。

【讨论】:

【参考方案2】:

将按钮放在一个 JPanel 中:

Jpanel buttonHolder = new JPanel;
buttonHolder.add(button1);
buttonHolder.add(button2);
buttonHolder.add(button3);
buttonHolder.add(button4);

frame.add(buttonHolder, FlowLayout.RIGHT); //justify to the right side

一般来说,将所有按钮放在同一个面板中是个好主意,这样如果您决定添加第五个按钮,这样做真的很容易,而不会破坏您的 GUI 的其余部分。正如 peeskillet 建议的那样,如果您需要 GUI 来处理大小调整,请使用 GridBagLayout(查看提供的链接中的 fill

【讨论】:

以上是关于如何使组件在面板的某个区域内居中的主要内容,如果未能解决你的问题,请参考以下文章

如何在其可点击区域内居中 WPF 复选框?

使谷歌地图标记在区域/区域内可拖动?

如何检查某个区域内的坐标Python

百度地图选择一个不规则区域,判断某个坐标点是否在这个区域内。该怎么去实现!

EXCEL中统计某个区域内多个数字一共出现的次数

如何使边框布局中心区域无限滚动?