为什么GridBagLayout认为我的组件不适合容器?

时间:2017-06-27 16:16:04

标签: java swing gridbaglayout

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

  1. 运行代码 - 不要在顶部输入名称 - 按下并按住微调器上单元格的向上按钮,直到页面预览更改为一个页面 - 预览不应该有(并且不会有)已调整大小)
  2. 再次运行代码 - 输入" Hello World" (或者在名称字段中任意两个单词开头大写) - 按住横向微调器上单元格的向上按钮,直到页面预览更改为一个页面 - 预览被调整大小,好像它不适合窗口和干扰按钮。
  3. 为什么布局管理器似乎认为PagePreview不再适合?它的尺寸没有被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;
                }
            }
        }
    
    }
    

    }

0 个答案:

没有答案