首页 > 解决方案 > 如何强制 JPanel 大小为 Graphic 大小?

问题描述

我有一个带有paintComponent 方法的JPanel,可以将事物绘制成方形。我希望该正方形始终在我的 JFrame 中水平居中(填充框架的整个高度),并让两个黑色 JPanel(每侧一个)填充其余宽度(它们将包含按钮和文本)。

但是我无法强制包含 Graphic 对象的 JPanel 是我需要的。JPanel 总是填满屏幕的其余部分,我不知道如何解决这个问题或强制侧面板来到正方形的两侧。

我想达到的目标:

https://i.stack.imgur.com/iHHeu.png

我现在拥有的:

https://i.stack.imgur.com/Uh5sc.png

标签: javaswinguser-interface

解决方案


您想要的不是 Java Swing 通常如何分配空间。

我创建了一个保持中心JPanel正方形的 GUI。

这是定义大小的 GUI。

三重 JPanel GUI

这是我手动拉伸后的 GUI。

三重 JPanel GUI 2

Stack Overflow 缩小了图像以适应答案。您可以判断,因为文本字体似乎缩小了。

注意:如果您通过单击右上角的方块来最大化 GUI,您将无法将 GUI 恢复到其原始大小。

我通过创建三个JPanels并设置它们的首选大小来做到这一点。我把这三个JPanels放在 main 里面,JPanel我用ComponentListener.

当您JFrame通过抓取边缘并拖动来调整大小时, 会ComponentListener计算三个 的新大小JPanels,保持中心正方形,并在 left和 rightJPanel之间划分其余空间。JPanelJPanel

我用FlowLayouts了三个JPanels。您也可以使用GridBagLayout. 您选择使用的布局管理器必须尊重JPanel调整大小。

这是完整的可运行代码。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TripleJPanelGUI implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new TripleJPanelGUI());
    }
    
    private JFrame frame;
    
    private JPanel leftPanel;
    private JPanel centerPanel;
    private JPanel rightPanel;

    @Override
    public void run() {
        frame = new JFrame("Triple JPanel GUI");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        PanelListener listener = new PanelListener(this);
        
        frame.add(createMainPanel(listener), BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JPanel createMainPanel(PanelListener listener) {
        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0));
        panel.addComponentListener(listener);
        
        leftPanel = createLeftPanel();
        centerPanel = createCenterPanel();
        rightPanel = createRightPanel();
                
        panel.add(leftPanel);
        panel.add(centerPanel);
        panel.add(rightPanel);
        
        return panel;
    }
    
    private JPanel createLeftPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBackground(Color.YELLOW);
        panel.setPreferredSize(new Dimension(100, 400));
        
        JLabel label = new JLabel("JPanel");
        label.setFont(panel.getFont().deriveFont(24f));
        panel.add(label);
        
        return panel;
    }
    
    private JPanel createCenterPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBackground(Color.GREEN);
        panel.setPreferredSize(new Dimension(400, 400));
        
        JLabel label = new JLabel("Always a Square");
        label.setFont(panel.getFont().deriveFont(24f));
        panel.add(label);
        
        
        return panel;
    }
    
    private JPanel createRightPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBackground(Color.BLUE);
        panel.setPreferredSize(new Dimension(100, 400));
        
        JLabel label = new JLabel("JPanel");
        label.setFont(panel.getFont().deriveFont(24f));
        label.setForeground(Color.WHITE);
        panel.add(label);
        
        return panel;
    }
    
    public void updateLeftPanel(int width, int height) {
        leftPanel.setPreferredSize(new Dimension(width, height));
    }
    
    public void updateCenterPanel(int width, int height) {
        centerPanel.setPreferredSize(new Dimension(width, height));
    }
    
    public void updateRightPanel(int width, int height) {
        rightPanel.setPreferredSize(new Dimension(width, height));
    }
    
    public JFrame getFrame() {
        return frame;
    }
    
    private class PanelListener extends ComponentAdapter {
        
        private TripleJPanelGUI frame;

        public PanelListener(TripleJPanelGUI frame) {
            this.frame = frame;
        }

        @Override
        public void componentResized(ComponentEvent event) {
            JPanel panel = (JPanel) event.getSource();
            Dimension d = panel.getSize();
            int width = (d.width - d.height) / 2; 
            int height = d.height;
            
            frame.updateLeftPanel(width, height);
            frame.updateCenterPanel(height, height);
            frame.updateRightPanel(width, height);
            frame.getFrame().pack();
        }
        
    }

}

推荐阅读