GridBagLayout似乎表现得很奇怪,但在某些特定条件下 - 有人可以在以下条件下运行附加代码并解释页面预览面板向窗口底部调整大小的行为:
为什么布局管理器似乎认为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;
}
}
}
}
}