Java Swing GridBagLayout JTextField在添加错误消息后更改大小
我一直在追踪这个bug有一段时间了,但似乎还没弄明白。我有一个带有标签和文本字段列表的小型GUI。在具有label+文本字段的行之间,有一个空行包含一个JLabel,以便根据需要填充错误消息。问题是,当这个错误消息被填充时,它们上面的文本字段由于某种原因被压缩,并且在尝试了几个小时不同的事情之后,我似乎无法找出原因。看起来所有的标签/文本区域彼此之间的压缩程度也略有不同。有人能指出这个问题吗 我已经尝试在面板布局中给每个元素更多的空间。这似乎并没有改变最终结果 如果查看代码,元素位于“continuousTransferPanel”上,“singleTransferPanel”也有相同的问题,只有2行Java Swing GridBagLayout JTextField在添加错误消息后更改大小,java,swing,jpanel,layout-manager,gridbaglayout,Java,Swing,Jpanel,Layout Manager,Gridbaglayout,我一直在追踪这个bug有一段时间了,但似乎还没弄明白。我有一个带有标签和文本字段列表的小型GUI。在具有label+文本字段的行之间,有一个空行包含一个JLabel,以便根据需要填充错误消息。问题是,当这个错误消息被填充时,它们上面的文本字段由于某种原因被压缩,并且在尝试了几个小时不同的事情之后,我似乎无法找出原因。看起来所有的标签/文本区域彼此之间的压缩程度也略有不同。有人能指出这个问题吗 我已经尝试在面板布局中给每个元素更多的空间。这似乎并没有改变最终结果 如果查看代码,元素位于“conti
这不是一个真正的答案,但我无法用我的尝试重现您的问题。请注意使用数组和集合(此处为映射)来简化代码:
import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
@SuppressWarnings("serial")
public class MyPanel extends JPanel {
public static final String[] LABELS = {"Job Name:", "Source Folder:", "Destination:", "File Regex:"};
private static final int TF_COLS = 20;
private static final Font LABEL_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 12);
private static final Font ERROR_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 8);
private static final String ERROR_MESSAGE = "Cannot Be Empty";
private static final Color BACKGROUND = new Color(49, 49, 47);
private Map<String, JTextField> labelFieldMap = new HashMap<>();
private Map<String, JLabel> errorLabelMap = new HashMap<>();
public MyPanel() {
setLayout(new BorderLayout());
setBackground(BACKGROUND);
JPanel labelFieldPanel = new JPanel(new GridBagLayout());
labelFieldPanel.setOpaque(false);
for (int i = 0; i < LABELS.length; i++) {
String text = LABELS[i];
JLabel label = new JLabel(text);
JTextField textField = new JTextField(TF_COLS);
JLabel errorLabel = new JLabel(" ");
label.setFont(LABEL_FONT);
label.setForeground(Color.WHITE);
errorLabel.setFont(ERROR_FONT);
errorLabel.setForeground(Color.RED);
labelFieldMap.put(text, textField);
errorLabelMap.put(text, errorLabel);
GridBagConstraints gbc = createLabelConstraint(i);
labelFieldPanel.add(label, gbc);
gbc = createTextFieldConstraints(i);
labelFieldPanel.add(textField, gbc);
gbc = createErrorLabelConstraints(i);
labelFieldPanel.add(errorLabel, gbc);
// add blank JLabel at the 0 position
gbc.gridx = 0;
labelFieldPanel.add(new JLabel(), gbc);
}
JButton acceptButton = new JButton("Accept");
acceptButton.setMnemonic(KeyEvent.VK_A);
acceptButton.addActionListener(e -> {
for (int i = 0; i < LABELS.length - 1; i++) {
String text = LABELS[i];
JTextField textField = labelFieldMap.get(text);
JLabel errorLabel = errorLabelMap.get(text);
if (textField.getText().trim().isEmpty()) {
errorLabel.setText(ERROR_MESSAGE);
} else {
errorLabel.setText(" ");
System.out.println(text + " " + textField.getText());
}
}
System.out.println();
});
JPanel btnPanel = new JPanel();
btnPanel.setOpaque(false);
btnPanel.add(acceptButton);
add(labelFieldPanel, BorderLayout.CENTER);
add(btnPanel, BorderLayout.PAGE_END);
}
private GridBagConstraints createErrorLabelConstraints(int i) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 2 * i + 1;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(0, 5, 0, 5);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 0.0;
return gbc;
}
private GridBagConstraints createTextFieldConstraints(int i) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 2 * i;
gbc.anchor = GridBagConstraints.EAST;
gbc.insets = new Insets(5, 0, 0, 5);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 0.0;
return gbc;
}
private GridBagConstraints createLabelConstraint(int i) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 2 * i;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(5, 5, 0, 5);
gbc.weightx = 0.0;
gbc.weighty = 0.0;
return gbc;
}
private static void createAndShowGui() {
MyPanel mainPanel = new MyPanel();
JFrame frame = new JFrame("MyPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
import java.awt.*;
导入java.awt.event.*;
导入java.util.HashMap;
导入java.util.Map;
导入javax.swing.*;
@抑制警告(“串行”)
公共类MyPanel扩展了JPanel{
公共静态最终字符串[]标签={“作业名称:”,“源文件夹:”,“目标:”,“文件正则表达式:”};
私有静态最终整数TF_COLS=20;
私有静态最终字体标签\u Font=新字体(Font.SANS\u SERIF,Font.BOLD,12);
私有静态最终字体错误\u Font=新字体(Font.SANS\u SERIF,Font.BOLD,8);
私有静态最终字符串错误\u MESSAGE=“不能为空”;
私有静态最终颜色背景=新颜色(49,49,47);
私有映射labelFieldMap=newHashMap();
私有映射errorLabelMap=new HashMap();
公共事务委员会(){
setLayout(新的BorderLayout());
挫折背景(背景);
JPanel labelFieldPanel=新的JPanel(新的GridBagLayout());
labelFieldPanel.Set不透明(假);
对于(int i=0;i{
对于(int i=0;icreateAndShowGui());
}
}
结果GUI:
由于问题出在JTextField的边框上,并且由于无法完全重置默认边框而不出现问题,一种解决方案是为JTextField创建一个复合边框,外边框是一个使用与JPanel背景色相同颜色的线边框,内边框是JTextField的默认边框然后在你的动作监听器中,简单地用crea
import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
@SuppressWarnings("serial")
public class MyPanel extends JPanel {
public static final String[] LABELS = {"Job Name:", "Source Folder:", "Destination:", "File Regex:"};
private static final int TF_COLS = 20;
private static final Font LABEL_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 12);
private static final Font ERROR_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 8);
private static final String ERROR_MESSAGE = "Cannot Be Empty";
private static final Color BACKGROUND = new Color(49, 49, 47);
private Map<String, JTextField> labelFieldMap = new HashMap<>();
private Map<String, JLabel> errorLabelMap = new HashMap<>();
public MyPanel() {
setLayout(new BorderLayout());
setBackground(BACKGROUND);
JPanel labelFieldPanel = new JPanel(new GridBagLayout());
labelFieldPanel.setOpaque(false);
for (int i = 0; i < LABELS.length; i++) {
String text = LABELS[i];
JLabel label = new JLabel(text);
JTextField textField = new JTextField(TF_COLS);
JLabel errorLabel = new JLabel(" ");
label.setFont(LABEL_FONT);
label.setForeground(Color.WHITE);
errorLabel.setFont(ERROR_FONT);
errorLabel.setForeground(Color.RED);
labelFieldMap.put(text, textField);
errorLabelMap.put(text, errorLabel);
GridBagConstraints gbc = createLabelConstraint(i);
labelFieldPanel.add(label, gbc);
gbc = createTextFieldConstraints(i);
labelFieldPanel.add(textField, gbc);
gbc = createErrorLabelConstraints(i);
labelFieldPanel.add(errorLabel, gbc);
// add blank JLabel at the 0 position
gbc.gridx = 0;
labelFieldPanel.add(new JLabel(), gbc);
}
JButton acceptButton = new JButton("Accept");
acceptButton.setMnemonic(KeyEvent.VK_A);
acceptButton.addActionListener(e -> {
for (int i = 0; i < LABELS.length - 1; i++) {
String text = LABELS[i];
JTextField textField = labelFieldMap.get(text);
JLabel errorLabel = errorLabelMap.get(text);
if (textField.getText().trim().isEmpty()) {
errorLabel.setText(ERROR_MESSAGE);
} else {
errorLabel.setText(" ");
System.out.println(text + " " + textField.getText());
}
}
System.out.println();
});
JPanel btnPanel = new JPanel();
btnPanel.setOpaque(false);
btnPanel.add(acceptButton);
add(labelFieldPanel, BorderLayout.CENTER);
add(btnPanel, BorderLayout.PAGE_END);
}
private GridBagConstraints createErrorLabelConstraints(int i) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 2 * i + 1;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(0, 5, 0, 5);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 0.0;
return gbc;
}
private GridBagConstraints createTextFieldConstraints(int i) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 2 * i;
gbc.anchor = GridBagConstraints.EAST;
gbc.insets = new Insets(5, 0, 0, 5);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 0.0;
return gbc;
}
private GridBagConstraints createLabelConstraint(int i) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 2 * i;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(5, 5, 0, 5);
gbc.weightx = 0.0;
gbc.weighty = 0.0;
return gbc;
}
private static void createAndShowGui() {
MyPanel mainPanel = new MyPanel();
JFrame frame = new JFrame("MyPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
// create JTextField with TF_COLS int column count value
JTextField textField = new JTextField(TF_COLS);
// get the JTextField's default border and make it our inner border
Border innerBorder = textField.getBorder();
// create an outer LineBorder that uses the JPanel's background color
Border outerBorder = BorderFactory.createLineBorder(BACKGROUND);
// create the compound border with these two borders
CompoundBorder myBorder = BorderFactory.createCompoundBorder(outerBorder, innerBorder);
// and set the JTextField's border with it
textField.setBorder(myBorder);
// loop through all the JLabel texts
for (int i = 0; i < LABELS.length; i++) {
String text = LABELS[i]; // get the array item
// use it to get the JTextField associated with this String
JTextField textField = labelFieldMap.get(text);
// same for the error JLabel
JLabel errorLabel = errorLabelMap.get(text);
// get our current JTextField's border which is a compound border
CompoundBorder myBorder = (CompoundBorder) textField.getBorder();
// the insideBorder, the original JTextField's border, will be unchanged
Border insideBorder = myBorder.getInsideBorder();
// if the text field is empty (and not the last jtext field)
if (i < LABELS.length - 1 && textField.getText().trim().isEmpty()) {
errorLabel.setText(ERROR_MESSAGE); // set the error JLabel
// set txt field's color if we want
textField.setBackground(ERROR_BG_COLOR);
// okToTransfer = false;
// create a compound border, the outer border now a line border, RED
Border outsideBorder = BorderFactory.createLineBorder(Color.RED);
CompoundBorder newBorder = BorderFactory.createCompoundBorder(outsideBorder, insideBorder);
// set the JTextField's border to this one
textField.setBorder(newBorder);
} else {
// else all OK
errorLabel.setText(" ");
textField.setBackground(Color.WHITE);
// set the JTextField's border back to our original compound border
Border outsideBorder = BorderFactory.createLineBorder(BACKGROUND);
CompoundBorder newBorder = BorderFactory.createCompoundBorder(outsideBorder,
insideBorder);
textField.setBorder(newBorder);
}
System.out.println(text + " " + textField.getText());
}
import java.awt.*;
import java.awt.Dialog.ModalityType;
import java.awt.event.*;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
@SuppressWarnings("serial")
public class MyPanel extends JPanel {
public static final String[] LABELS = { "Job Name:", "Source Folder:", "Destination:",
"File Regex:" };
private static final int TF_COLS = 30;
private static final Font LABEL_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 12);
private static final Font ERROR_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 8);
private static final String ERROR_MESSAGE = "Cannot Be Empty";
private static final Color BACKGROUND = new Color(49, 49, 47);
private static final String TITLE = "File Transfer Job Editor";
private static final Color TITLE_COLOR = new Color(243, 112, 33);
private static final Font TITLE_FONT = new Font("Arial", Font.BOLD, 28);
private static final Color ERROR_BG_COLOR = new Color(255, 220, 220);
private Map<String, JTextField> labelFieldMap = new HashMap<>();
private Map<String, JLabel> errorLabelMap = new HashMap<>();
public MyPanel() {
JLabel titleLabel = new JLabel(TITLE, SwingConstants.CENTER);
titleLabel.setForeground(TITLE_COLOR);
titleLabel.setFont(TITLE_FONT);
JPanel titlePanel = new JPanel();
titlePanel.setOpaque(false);
titlePanel.add(titleLabel);
titlePanel.setBorder(BorderFactory.createEtchedBorder());
JPanel labelFieldPanel = new JPanel(new GridBagLayout());
labelFieldPanel.setOpaque(false);
int bGap = 3;
labelFieldPanel.setBorder(BorderFactory.createEmptyBorder(bGap, bGap, bGap, bGap));
for (int i = 0; i < LABELS.length; i++) {
String text = LABELS[i];
JLabel label = new JLabel(text);
JTextField textField = new JTextField(TF_COLS);
JLabel errorLabel = new JLabel(" ");
Border innerBorder = textField.getBorder();
Border outerBorder = BorderFactory.createLineBorder(BACKGROUND);
CompoundBorder myBorder = BorderFactory.createCompoundBorder(outerBorder, innerBorder);
textField.setBorder(myBorder);
label.setFont(LABEL_FONT);
label.setForeground(Color.WHITE);
errorLabel.setFont(ERROR_FONT);
errorLabel.setForeground(Color.RED);
labelFieldMap.put(text, textField);
errorLabelMap.put(text, errorLabel);
GridBagConstraints gbc = createLabelConstraint(i);
labelFieldPanel.add(label, gbc);
gbc = createTextFieldConstraints(i);
labelFieldPanel.add(textField, gbc);
gbc = createErrorLabelConstraints(i);
labelFieldPanel.add(errorLabel, gbc);
// add blank JLabel at the 0 position
gbc.gridx = 0;
labelFieldPanel.add(new JLabel(), gbc);
}
JButton acceptButton = new JButton("Accept");
acceptButton.setMnemonic(KeyEvent.VK_A);
acceptButton.addActionListener(e -> {
boolean okToTransfer = true;
for (int i = 0; i < LABELS.length; i++) {
String text = LABELS[i];
JTextField textField = labelFieldMap.get(text);
JLabel errorLabel = errorLabelMap.get(text);
CompoundBorder myBorder = (CompoundBorder) textField.getBorder();
Border insideBorder = myBorder.getInsideBorder();
if (i < LABELS.length - 1 && textField.getText().trim().isEmpty()) {
errorLabel.setText(ERROR_MESSAGE);
textField.setBackground(ERROR_BG_COLOR);
okToTransfer = false;
Border outsideBorder = BorderFactory.createLineBorder(Color.RED);
CompoundBorder newBorder = BorderFactory.createCompoundBorder(outsideBorder, insideBorder);
textField.setBorder(newBorder);
} else {
errorLabel.setText(" ");
textField.setBackground(Color.WHITE);
Border outsideBorder = BorderFactory.createLineBorder(BACKGROUND);
CompoundBorder newBorder = BorderFactory.createCompoundBorder(outsideBorder, insideBorder);
textField.setBorder(newBorder);
}
System.out.println(text + " " + textField.getText());
}
System.out.println();
if (okToTransfer) {
// TODO: transfer code here
// Window win = SwingUtilities.getWindowAncestor(MyPanel.this);
// win.dispose();
}
});
JButton cancelBtn = new JButton("Cancel");
cancelBtn.setMnemonic(KeyEvent.VK_C);
cancelBtn.addActionListener(e -> {
Window win = SwingUtilities.getWindowAncestor(MyPanel.this);
win.dispose();
});
int btnPanelGap = 15;
JPanel btnPanel = new JPanel(new GridLayout(1, 0, btnPanelGap, 0));
btnPanel.setBorder(BorderFactory.createEmptyBorder(4, btnPanelGap, 4, btnPanelGap));
btnPanel.setOpaque(false);
btnPanel.add(acceptButton);
btnPanel.add(cancelBtn);
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
setBackground(BACKGROUND);
add(titlePanel);
add(labelFieldPanel);
add(btnPanel);
}
private GridBagConstraints createErrorLabelConstraints(int i) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 2 * i + 1;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(0, 5, 0, 5);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 0.0;
return gbc;
}
private GridBagConstraints createTextFieldConstraints(int i) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 2 * i;
gbc.anchor = GridBagConstraints.EAST;
gbc.insets = new Insets(5, 0, 0, 5);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 0.0;
return gbc;
}
private GridBagConstraints createLabelConstraint(int i) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 2 * i;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(5, 5, 0, 5);
gbc.weightx = 0.0;
gbc.weighty = 0.0;
return gbc;
}
private static void createAndShowGui() {
MyPanel mainPanel = new MyPanel();
JDialog dialog = new JDialog((JFrame) null, "Job Editor", ModalityType.APPLICATION_MODAL);
dialog.getContentPane().add(mainPanel);
dialog.setResizable(false);
dialog.pack();
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
System.exit(0);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}