Java 为什么GridBagLayout认为我的组件赢了';你装不下这个容器吗?

Java 为什么GridBagLayout认为我的组件赢了';你装不下这个容器吗?,java,swing,gridbaglayout,Java,Swing,Gridbaglayout,GridBagLayout的行为似乎很奇怪,但在某些非常特定的条件下-是否有人可以在以下条件下运行附加的代码,并解释朝向窗口底部的页面预览面板的大小调整行为: 运行代码-不要在顶部输入名称-在微调器上按住单元格的“向上”按钮,直到页面预览更改为一页-预览不应该(也不会调整大小) 再次运行代码-在“名称”字段中输入“Hello World”(或以大写字母开头的任意两个单词)-按住微调器上单元格的向上按钮,直到页面预览更改为一页-预览的大小调整为不适合窗口并干扰按钮 为什么布局管理器似乎认为页面预览

GridBagLayout的行为似乎很奇怪,但在某些非常特定的条件下-是否有人可以在以下条件下运行附加的代码,并解释朝向窗口底部的页面预览面板的大小调整行为:

  • 运行代码-不要在顶部输入名称-在微调器上按住单元格的“向上”按钮,直到页面预览更改为一页-预览不应该(也不会调整大小)
  • 再次运行代码-在“名称”字段中输入“Hello World”(或以大写字母开头的任意两个单词)-按住微调器上单元格的向上按钮,直到页面预览更改为一页-预览的大小调整为不适合窗口并干扰按钮
  • 为什么布局管理器似乎认为页面预览不再合适?setBreaks()方法没有触及它的维度。为什么在文本字段中输入的字符串的性质会影响这一点

    如果在PagePreview类中未重写getWidth()和getHeight()方法,则此行为更为明显

    抱歉,这不是一个较短的SSCCE,但如果没有完整的代码,我无法复制此问题

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JCheckBox;
    import javax.swing.JDialog;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JSpinner;
    import javax.swing.SpinnerModel;
    import javax.swing.SpinnerNumberModel;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
    
    import javax.swing.JSpinner.DefaultEditor;
    import javax.swing.JTextField;
    import javax.swing.border.BevelBorder;
    
    @SuppressWarnings("serial")
    public class ResizeProblem extends JDialog implements ActionListener {
    
    public static void main(String[] args) {
    
        new ResizeProblem(100, 75);
    
    }
    
    private int designWidth;
    private int designHeight;
    
    private JLabel nameLbl;
    private JTextField nameField;
    private JLabel printDesignLbl;
    private JCheckBox printDesign;
    
    private static final double PAGE_RATIO = 0.68;
    private static final int PORTRAIT_ACROSS = 40;
    private static final int LANDSCAPE_ACROSS = 60;
    private int acrossValue;
    private int downValue;
    private boolean isPortrait;
    private JLabel portraitLbl;
    private JCheckBox portrait;
    private JLabel landscapeLbl;
    private JCheckBox landscape;
    
    private JLabel acrossLbl;
    private JSpinner across;
    private JLabel downLbl;
    private JTextField down;
    private JLabel info;
    private PagePreview preview;
    private JButton print;
    
    public ResizeProblem(int designWidth,
            int designHeight) {
        this.designWidth = designWidth;
        this.designHeight = designHeight;
        if (designWidth > designHeight) {
            isPortrait = false;
            acrossValue = LANDSCAPE_ACROSS;
            downValue = PORTRAIT_ACROSS;
        } else {
            isPortrait = true;
            acrossValue = PORTRAIT_ACROSS;
            downValue = LANDSCAPE_ACROSS;
        }
        setTitle("Print Options");
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setModal(true);
        setModalityType(ModalityType.APPLICATION_MODAL);
        setLayout(new GridBagLayout());
        Format format = new Format();
        nameLbl = new JLabel("Project name (optional):");
        add(nameLbl, format.gbc_lw1);
        nameField = new JTextField();
        add(nameField, format.gbc_cw2);
        format.nextLine();
    
        printDesignLbl = new JLabel("Print design image:");
        add(printDesignLbl, format.gbc_lw2);
        printDesign = new JCheckBox();
        printDesign.setSelected(true);
        add(printDesign, format.gbc_rw1);
        format.nextLine();
    
        portraitLbl = new JLabel("Print design in portrait:");
        add(portraitLbl, format.gbc_lw2);
        portrait = new JCheckBox();
        portrait.setSelected(isPortrait);
        portrait.setActionCommand("portrait");
        portrait.addActionListener(this);
        add(portrait, format.gbc_rw1);
        format.nextLine();
    
        landscapeLbl = new JLabel("Print design in landscape:");
        add(landscapeLbl, format.gbc_lw2);
        landscape = new JCheckBox();
        landscape.setSelected(!isPortrait);
        landscape.setActionCommand("landscape");
        landscape.addActionListener(this);
        add(landscape, format.gbc_rw1);
        format.nextLine();
    
        acrossLbl = new JLabel("Number of cells printed across per page:");
        add(acrossLbl, format.gbc_lw2);
        SpinnerModel model = new SpinnerNumberModel(acrossValue, 20, 150, 1);
        across = new JSpinner(model);
        acrossValue = (int) across.getValue();
        downValue = getDownValue();
        across.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent arg0) {
                acrossValue = (int) across.getValue();
                downValue = getDownValue();
                down.setText(downValue + "");
                info.setText(getInfo());
                if (acrossValue <= designWidth || downValue <= designHeight) {
                    preview.setBreaks(acrossValue, downValue);
                }
                repaint();
            }
        });
        ((DefaultEditor) across.getEditor()).getTextField().setEditable(false);
        ((DefaultEditor) across.getEditor()).getTextField().setHorizontalAlignment(JLabel.LEADING);
        ((DefaultEditor) across.getEditor()).getTextField().setHighlighter(null);
        add(across, format.gbc_rw1);
        format.nextLine();
        downLbl = new JLabel("Corresponding printed down:");
        add(downLbl, format.gbc_lw2);
        down = new JTextField();
        down.setText(getDownValue() + "");
        down.setEditable(false);
        down.setCursor(null);
        down.setHighlighter(null);
        add(down, format.gbc_rw1);
        format.nextLine();
    
        info = new JLabel(getInfo());
        add(info, format.gbc_fulll);
        format.nextLine();
    
        preview = new PagePreview(designWidth, designHeight);
        preview.setBorder(new BevelBorder(BevelBorder.RAISED));
        preview.setBreaks(acrossValue, downValue);
        add(preview, format.gbc_fullc);
        format.nextLine();
    
        print = new JButton("Print");
        print.setActionCommand("print");
        print.addActionListener(this);
        add(print, format.gbc_fullc);
        format.nextLine();
        add(new JLabel(), format.gbc_fullc);
        pack();
        setLocationRelativeTo(null);
        setResizable(false);
        setVisible(true);
    }
    
    private int getDownValue() {
        int acrossValue = (int) across.getValue();
        if (isPortrait) {
            return (int) Math.ceil(acrossValue / PAGE_RATIO);
        } else {
            return ((int) (acrossValue * PAGE_RATIO));
        }
    }
    
    private String getInfo() {
        int pages = (getPagesAcross() * getPagesDown());
        if (pages > 1) {
            return "Design will be printed over " + pages + " pages";
        } else {
            return "Design will be printed on 1 page";
        }
    }
    
    private int getPagesAcross() {
        double pages = ((double) designWidth) / acrossValue;
        return (int) Math.ceil(pages);
    }
    
    private int getPagesDown() {
        double pages = ((double) designHeight) / downValue;
        return (int) Math.ceil(pages);
    }
    
    private void print() {
        dispose();
    }
    
    private void swapValues() {
        int temp = acrossValue;
        acrossValue = downValue;
        downValue = temp;
        across.setValue(acrossValue);
        down.setText(downValue + "");
        preview.setBreaks(acrossValue, downValue);
    }
    
    @Override
    public void actionPerformed(ActionEvent event) {
        if (event.getActionCommand().equals("portrait")) {
            landscape.setSelected(false);
            isPortrait = true;
            swapValues();
        } else if (event.getActionCommand().equals("landscape")) {
            portrait.setSelected(false);
            isPortrait = false;
            swapValues();
        } else if (event.getActionCommand().equals("print")) {
            print();
        }
    }
    
    class Format {
    
        GridBagConstraints gbc_lw1;
        GridBagConstraints gbc_lw2;
        GridBagConstraints gbc_cw2;
        GridBagConstraints gbc_rw1;
        GridBagConstraints gbc_fulll;
        GridBagConstraints gbc_fullc;
    
        Format() {
            Insets insets = new Insets(20, 20, 0, 20);
            gbc_lw1 = new GridBagConstraints();
            gbc_lw1.gridx = 0;
            gbc_lw1.gridy = 0;
            gbc_lw1.gridwidth = 1;
            gbc_lw1.weightx = 0;
            gbc_lw1.weighty = 0;
            gbc_lw1.anchor = GridBagConstraints.LINE_START;
            gbc_lw1.fill = GridBagConstraints.NONE;
            gbc_lw1.insets = insets;
            gbc_lw2 = new GridBagConstraints();
            gbc_lw2.gridx = 0;
            gbc_lw2.gridy = 0;
            gbc_lw2.gridwidth = 2;
            gbc_lw2.weightx = 0;
            gbc_lw2.weighty = 0;
            gbc_lw2.anchor = GridBagConstraints.LINE_START;
            gbc_lw2.fill = GridBagConstraints.NONE;
            gbc_lw2.insets = insets;
            gbc_cw2 = new GridBagConstraints();
            gbc_cw2.gridx = 1;
            gbc_cw2.gridy = 0;
            gbc_cw2.gridwidth = 2;
            gbc_cw2.weightx = 1;
            gbc_cw2.weighty = 0;
            gbc_cw2.anchor = GridBagConstraints.LINE_END;
            gbc_cw2.fill = GridBagConstraints.HORIZONTAL;
            gbc_cw2.insets = insets;
            gbc_rw1 = new GridBagConstraints();
            gbc_rw1.gridx = 2;
            gbc_rw1.gridy = 0;
            gbc_rw1.gridwidth = 1;
            gbc_rw1.weightx = 1;
            gbc_rw1.weighty = 0;
            gbc_rw1.anchor = GridBagConstraints.LINE_END;
            gbc_rw1.fill = GridBagConstraints.HORIZONTAL;
            gbc_rw1.insets = insets;
            gbc_fulll = new GridBagConstraints();
            gbc_fulll.gridx = 0;
            gbc_fulll.gridy = 0;
            gbc_fulll.gridwidth = 3;
            gbc_fulll.weightx = 1;
            gbc_fulll.weighty = 0;
            gbc_fulll.anchor = GridBagConstraints.LINE_START;
            gbc_fulll.fill = GridBagConstraints.NONE;
            gbc_fulll.insets = insets;
            gbc_fullc = new GridBagConstraints();
            gbc_fullc.gridx = 0;
            gbc_fullc.gridy = 0;
            gbc_fullc.gridwidth = 3;
            gbc_fullc.weightx = 1;
            gbc_fullc.weighty = 1;
            gbc_fullc.anchor = GridBagConstraints.CENTER;
            gbc_fullc.fill = GridBagConstraints.NONE;
            gbc_fullc.insets = insets;
        }
    
        void nextLine() {
            gbc_lw1.gridy++;
            gbc_lw2.gridy++;
            gbc_cw2.gridy++;
            gbc_rw1.gridy++;
            gbc_fulll.gridy++;
            gbc_fullc.gridy++;
        }
    
    }
    
    class PagePreview extends JPanel {
    
        private static final int BORDER = 10;
    
        private int width;
        private int height;
        private int designWidth;
        private int designHeight;
        private int xbreak;
        private int ybreak;
    
        public PagePreview(int designWidth, int designHeight) {
            this.designWidth = designWidth;
            this.designHeight = designHeight;
            width = designWidth + (BORDER * 2);
            height = designHeight + (BORDER * 2);
            setPreferredSize(new Dimension(width, height));
            setBackground(Color.WHITE);
        }
    
        @Override
        public int getWidth() {
            return width;
        }
    
        @Override
        public int getHeight() {
            return height;
        }
    
        public void setBreaks(int xbreak, int ybreak) {
            this.xbreak = xbreak;
            this.ybreak = ybreak;
            repaint();
        }
    
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.setColor(Color.LIGHT_GRAY);
            g2d.drawRect(BORDER - 1, BORDER - 1, designWidth, designHeight);
            g2d.fillRect(BORDER - 1, BORDER - 1, designWidth, designHeight);
            if (xbreak > 0 && ybreak > 0) {
                g2d.setColor(Color.BLACK);
                int breakpoint = xbreak;
                while (breakpoint < designWidth) {
                    g2d.drawLine(BORDER + breakpoint, 0, BORDER + breakpoint, height);
                    breakpoint += xbreak;
                }
                breakpoint = ybreak;
                while (breakpoint < designHeight) {
                    g2d.drawLine(0, BORDER + breakpoint, width, BORDER + breakpoint);
                    breakpoint += ybreak;
                }
            }
        }
    
    }
    
    导入java.awt.Color;
    导入java.awt.Dimension;
    导入java.awt.Graphics;
    导入java.awt.Graphics2D;
    导入java.awt.GridBagConstraints;
    导入java.awt.GridBagLayout;
    导入java.awt.Insets;
    导入java.awt.event.ActionEvent;
    导入java.awt.event.ActionListener;
    导入javax.swing.JButton;
    导入javax.swing.JCheckBox;
    导入javax.swing.JDialog;
    导入javax.swing.JFrame;
    导入javax.swing.JLabel;
    导入javax.swing.JPanel;
    导入javax.swing.JSpinner;
    导入javax.swing.SpinnerModel;
    导入javax.swing.SpinnerNumberModel;
    导入javax.swing.event.ChangeEvent;
    导入javax.swing.event.ChangeListener;
    导入javax.swing.JSpinner.DefaultEditor;
    导入javax.swing.JTextField;
    导入javax.swing.border.BevelBorder;
    @抑制警告(“串行”)
    公共类ResizeProblem扩展JDialog实现ActionListener{
    公共静态void main(字符串[]args){
    新的调整问题(100,75);
    }
    专用int设计宽度;
    私人室内设计高度;
    私人JLabel nameLbl;
    私有JTextField nameField;
    私人JLabel printDesignLbl;
    私人JCheckBox印刷设计;
    私人静态最终双页_比率=0.68;
    私有静态最终整数纵向_=40;
    私有静态最终int横向=60;
    私有价值;
    私人价值;
    私有布尔isPortrait;
    私人JLabel;
    私人JCheckBox肖像;
    私人JLabel园景;
    私人JCheckBox景观;
    私人JLabel-acrossLbl;
    私人公寓;
    私人JLabel downLbl;
    私人住宅区关闭;
    私人JLabel信息;
    私人网页预览;
    私人按钮打印;
    公共大小调整问题(int designWidth,
    整数(设计高度){
    this.designWidth=设计宽度;
    this.designHeight=设计高度;
    如果(设计宽度>设计高度){
    isPortrait=false;
    acrossValue=横向景观;
    DOWNWALUE=横向纵向;
    }否则{
    isPortrait=true;
    acrossValue=纵向_横向;
    downValue=横向的横向;
    }
    setTitle(“打印选项”);
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    setModal(真);
    setModalityType(ModalityType.APPLICATION_MODAL);
    setLayout(新的GridBagLayout());
    格式=新格式();
    nameLbl=新的JLabel(“项目名称(可选):”;
    添加(nameLbl,格式为.gbc_lw1);
    nameField=新的JTextField();
    添加(名称字段,格式为.gbc_cw2);
    format.nextLine();
    printDesignLbl=新的JLabel(“打印设计图像:”);
    添加(printDesignLbl,格式为.gbc_lw2);
    printDesign=新的JCheckBox();
    printDesign.setSelected(真);
    添加(打印设计,格式.gbc_rw1);
    format.nextLine();
    肖像Lbl=新的JLabel(“肖像中的印刷设计”);
    添加(LBL格式,gbc_lw2);
    纵向=新的JCheckBox();
    肖像。已选定(isPortrait);
    肖像。setActionCommand(“肖像”);
    肖像。addActionListener(此);
    添加(纵向,格式.gbc_rw1);
    format.nextLine();
    landscapeLbl=新的JLabel(“景观中的印刷设计”);
    添加(景观图,格式为gbc_lw2);
    横向=新的JCheckBox();
    选择的景观设置(!isPortrait);
    横向。setActionCommand(“横向”);
    landscape.addActionListener(this);
    添加(横向,格式.gbc_rw1);
    format.nextLine();
    acrossLbl=新的JLabel(“每页打印的单元格数:”);
    添加(acrossLbl,格式为.gbc_lw2);
    喷丝头型号=新喷丝头型号(acrossValue,20,150,1);
    Cross=新的JSpinner(型号);
    acrossValue=(int)横跨.getValue();
    downValue=getDownValue();
    addChangeListener(新的ChangeListener(){
    @凌驾
    公共无效状态已更改(ChangeEvent arg0){
    acrossValue=(int)横跨.getValue();
    downValue=getDownValue();
    down.setText(downValue+“”);
    info.setText(getInfo());
    if(跨值0&&ybreak>0){
    g2d.setColor(Color.BLACK);
    int断点=xbreak;
    while(断点<设计宽度){
    g2d.绘制线(边框+断点,0,边框+断点,高度);
    断点+=xbreak;
    }
    断点=ybreak;
    while(断点<设计高度){
    g2d.绘制线(0,边框+断点,宽度,边框+断点);
    断点+=ybreak;
    }
    }
    }
    }
    

    }

    首先,我不重写
    getWidth/height
    @MadProgrammer我在页面预览类中重写getWidth/height,这会阻止组件的物理大小调整,但布局管理器似乎认为它不再适合,因此无法为它腾出空间。我也不知所措