gpt4 book ai didi

java - 如何调整 Jpanel 中 JTextField 的大小

转载 作者:行者123 更新时间:2023-12-02 02:30:03 24 4
gpt4 key购买 nike

作为编程新手,我在调整添加到 JPanel 的文本字段大小时遇到​​了一个小问题。虽然我可以使用自己的文本字段创建单独的面板,但我认为最好将所有组件添加到一个面板中。我的整体想法的一部分是让我的添加按钮引用包含文本字段的面板,在跟踪器上添加更多文本字段以供用户填写,并且当我在上实现 setBounds 方法时可以获取要显示的字段我的面板对象,我很难弄清楚如何在面板本身中调整它们的大小。如果您对我的整体结构有任何其他建议,我欢迎。

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;


public class UI {
JFrame frame;
JLabel Title,Name, CheckOut, CheckIn, Email;
JTextField NameField,CheckOutField, CheckInField, EmailField;
JButton Add, Delete;
JPanel buttons, textfields, primary;

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UI window = new UI();
window.frame.setVisible(true);


} catch (Exception e) {
e.printStackTrace();
}
}
});
}

public UI(){
design();

}

private void design(){


frame = new JFrame("Form 48 Tracker");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(100, 100, 750, 400);
frame.getContentPane().setLayout(null);


Title = new JLabel();
Title.setText("Form 48 Tracker");
Title.setFont(new Font("Calibri", Font.PLAIN, 28));
Title.setBounds(233, 11, 200, 75);
frame.getContentPane().add(Title);
Title.setForeground(Color.BLACK);

Name = new JLabel();
Name.setText("Name");
Name.setFont(new Font("Calibri", Font.PLAIN, 15));
Name.setBounds(50, 80, 128, 20);
frame.getContentPane().add(Name);
Name.setForeground(Color.BLACK);

CheckOut = new JLabel();
CheckOut.setText("Check Out Date");
CheckOut.setFont(new Font("Calibri", Font.PLAIN, 15));
CheckOut.setBounds(200, 80, 128, 20);
frame.getContentPane().add(CheckOut);
CheckOut.setForeground(Color.BLACK);

CheckIn = new JLabel();
CheckIn.setText("Check In Date");
CheckIn.setFont(new Font("Calibri", Font.PLAIN, 15));
CheckIn.setBounds(350, 80, 128, 20);
frame.getContentPane().add(CheckIn);
CheckIn.setForeground(Color.BLACK);

Email = new JLabel();
Email.setText("Email");
Email.setFont(new Font("Calibri", Font.PLAIN, 15));
Email.setBounds(500, 80, 128, 20);
frame.getContentPane().add(Email);
Email.setForeground(Color.BLACK);


Add = new JButton("Add");
buttons = new JPanel();
buttons.add(Add);
buttons.setBounds(200, 270, 157, 50); //x , y , width , height//
frame.getContentPane().add(buttons);
Add.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){


}
});

Delete = new JButton("Delete");
buttons = new JPanel();
buttons.add(Delete);
buttons.setBounds(605, 101, 128, 50);
frame.getContentPane().add(buttons);



primary = new JPanel();
NameField = new JTextField();
CheckOutField = new JTextField();
CheckInField = new JTextField();
EmailField = new JTextField();
primary.add(NameField);
primary.add(CheckOutField);
primary.add(CheckInField);
primary.add(EmailField);
primary.setBounds(50, 110, 128, 20);
frame.getContentPane().add(primary);

}


}

最佳答案

让我们专注于导致问题的代码,并且仅关注该代码。我创建了一个最小的示例程序,它有足够的代码来编译和运行,并且演示了问题,但没有不必要的代码:

import javax.swing.*;

public class UiFoo {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Foo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null); // **** no!! ****

JPanel primary = new JPanel();
JTextField NameField = new JTextField();
JTextField CheckOutField = new JTextField();
JTextField CheckInField = new JTextField();
JTextField EmailField = new JTextField();
primary.add(NameField);
primary.add(CheckOutField);
primary.add(CheckInField);
primary.add(EmailField);
primary.setBounds(50, 110, 128, 20);

frame.getContentPane().add(primary);

frame.setSize(600, 250);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}

因此,如果运行此代码,您将看到 4 个非常小的 JTextField。为什么它们这么小?因为您尚未设置 JTextFields 的 columns 属性,所以它们默认为列大小 0 并显示如下:

enter image description here

因此,如果您可以为 JTextField 提供 columns 属性,以便它们具有一定的宽度,例如进行以下更改,那就更好了:

JPanel primary = new JPanel();
int columns = 8;
JTextField NameField = new JTextField(columns);
JTextField CheckOutField = new JTextField(columns);
JTextField CheckInField = new JTextField(columns);
JTextField EmailField = new JTextField();

但这仅显示一个 JTextField,并且还切断了底部:

enter image description here

为什么?因为您人为地限制了包含 JPanel 的大小,主要通过:

primary.setBounds(50, 110, 128, 20);

这个包含 JPanel 的宽度仅为 128 像素,高度为 20 像素,这意味着它甚至无法很好地显示一个 JTextField。

一种解决方案是混合使用布局管理器和 JPanel 以及 JScrollPane 来允许添加 JPanel 网格,如下所示(尝试一下!):

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.*;

@SuppressWarnings("serial")
public class UiFoo2 extends JPanel {
JPanel singleColumnPanel = new JPanel(new GridLayout(0, 1, 2, 2));

public UiFoo2() {
JButton addButton = new JButton("Add");
addButton.addActionListener(e -> {
JPanel rowPanel = new JPanel(new GridLayout(1, 4, 2, 2));
for (int i = 0; i < 4; i++) {
rowPanel.add(new JTextField(8));
}

singleColumnPanel.add(rowPanel);
singleColumnPanel.revalidate();
singleColumnPanel.repaint();
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(addButton);

JPanel labelPanel = new JPanel(new GridLayout(1, 4, 2, 2));
labelPanel.add(new JLabel("Name", SwingConstants.CENTER));
labelPanel.add(new JLabel("Check Out Date", SwingConstants.CENTER));
labelPanel.add(new JLabel("Check In Date", SwingConstants.CENTER));
labelPanel.add(new JLabel("Email", SwingConstants.CENTER));

singleColumnPanel.add(labelPanel);

JPanel containerPanel = new JPanel(new BorderLayout(5, 5));
containerPanel.add(singleColumnPanel, BorderLayout.PAGE_START);
JScrollPane scrollPane = new JScrollPane(containerPanel);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setPreferredSize(new Dimension(650, 400));
setLayout(new BorderLayout());
add(scrollPane, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.PAGE_END);
}

private static void createAndShowGui() {
UiFoo2 mainPanel = new UiFoo2();

JFrame frame = new JFrame("UiFoo2");
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());
}
}

这将创建一行 JPanel,其中包含四个 JTextField,当按下添加 JButton 时,这些 JTextField 将添加到 JScrollPane,如下所示:

enter image description here

但我们仍然可以做得更好。为什么不创建一个类来保存一行数据,如下所示:

import java.util.Date;

public class Form48Customer {
private String name;
private Date checkIn;
private Date checkOut;
private String Email;

public Form48Customer(String name, Date checkIn, Date checkOut, String email) {
this.name = name;
this.checkIn = checkIn;
this.checkOut = checkOut;
Email = email;
}

public Date getCheckIn() {
return checkIn;
}

public void setCheckIn(Date checkIn) {
this.checkIn = checkIn;
}

public Date getCheckOut() {
return checkOut;
}

public void setCheckOut(Date checkOut) {
this.checkOut = checkOut;
}

public String getName() {
return name;
}

public String getEmail() {
return Email;
}

// should override hashCode and equals here

}

然后创建一个带有自定义模型的JTable来显示这种类型的对象,然后在GUI中显示它们。这更加干净、更加灵活并且可扩展。像这样:

import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.*;
import java.util.Date;
import javax.swing.*;
import javax.swing.JFormattedTextField.AbstractFormatter;
import javax.swing.table.*;

@SuppressWarnings("serial")
public class Form48TrackerPanel extends JPanel {
public static final String TITLE = "Form 48 Tracker";
private static final String DATE_FORMAT_TXT = "MM/dd/yyyy";
private Form48TableModel model = new Form48TableModel();
private JTable table = new JTable(model);
private JButton addButton = new JButton("Add");
private JButton deleteButton = new JButton("Delete");
private JButton exitButton = new JButton("Exit");

public Form48TrackerPanel() {
final SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_TXT);
TableCellRenderer dateRenderer = new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if( value instanceof Date) {
value = dateFormat.format(value);
}
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
};
table.getColumnModel().getColumn(1).setCellRenderer(dateRenderer);
table.getColumnModel().getColumn(2).setCellRenderer(dateRenderer);
JLabel titleLabel = new JLabel(TITLE, SwingConstants.CENTER);
titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, 28f));

addButton.addActionListener(new AddListener());
addButton.setMnemonic(KeyEvent.VK_A);
deleteButton.addActionListener(new DeleteListener());
deleteButton.setMnemonic(KeyEvent.VK_D);
exitButton.addActionListener(new ExitListener());
exitButton.setMnemonic(KeyEvent.VK_X);

JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 0));
buttonPanel.add(addButton);
buttonPanel.add(deleteButton);
buttonPanel.add(exitButton);

setPreferredSize(new Dimension(800, 500));
int ebGap = 8;
setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
setLayout(new BorderLayout(ebGap, ebGap));
add(titleLabel, BorderLayout.PAGE_START);
add(new JScrollPane(table), BorderLayout.CENTER);
add(buttonPanel, BorderLayout.PAGE_END);

model.addRow(new Form48Customer("John Smith", new Date(), new Date(), "JSmith@Yahoo.com"));
model.addRow(new Form48Customer("Fred Flinstone", new Date(), new Date(), "FFlinstone@GMail.com"));
}

private class AddListener implements ActionListener {

@Override
public void actionPerformed(ActionEvent e) {
AddForm48Panel addFormPanel = new AddForm48Panel();
int result = JOptionPane.showConfirmDialog(Form48TrackerPanel.this,
addFormPanel, "Add Customer", JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
Form48Customer customer = addFormPanel.getForm48Customer();
model.addRow(customer);
}
}
}

private class DeleteListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
// TODO *** finish this code ***

}
}

private class ExitListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Window win = SwingUtilities.getWindowAncestor(Form48TrackerPanel.this);
win.dispose();
}
}

private static void createAndShowGui() {
Form48TrackerPanel mainPanel = new Form48TrackerPanel();

JFrame frame = new JFrame(TITLE);
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());
}
}

@SuppressWarnings("serial")
class AddForm48Panel extends JPanel {
private static final int TFIELD_COLS = 10;
private static final String DATE_FORMAT_TXT = "MM/dd/yyyy";
private static final Format DATE_FORMAT = new SimpleDateFormat(DATE_FORMAT_TXT);
private static final Insets INSETS = new Insets(5, 5, 5, 5);
private JTextField nameField = new JTextField(TFIELD_COLS);
private JFormattedTextField checkOutDateField = new JFormattedTextField(DATE_FORMAT);
private JFormattedTextField checkInDateField = new JFormattedTextField(DATE_FORMAT);
private JTextField emailField = new JTextField(TFIELD_COLS);
private JComponent[] fields = {nameField, checkOutDateField, checkInDateField, emailField};
private String[] labels = {"Name", "Check Out Date", "Check In Date", "Email"};

public AddForm48Panel() {
InputVerifier verifier = new DateFieldVerifier();
checkInDateField.setInputVerifier(verifier);
checkOutDateField.setInputVerifier(verifier);

setLayout(new GridBagLayout());
for (int i = 0; i < fields.length; i++) {
add(new JLabel(labels[i] + ":"), createGbc(0, i));
add(fields[i], createGbc(1, i));
}
}

public String getName() {
return nameField.getText();
}

public String getEmail() {
return emailField.getText();
}

public Date getCheckOut() {
return (Date) checkOutDateField.getValue();
}

public Date getCheckIn() {
return (Date) checkInDateField.getValue();
}

public Form48Customer getForm48Customer() {
String name = getName();
Date checkOut = getCheckOut();
Date checkIn = getCheckIn();
String email = getEmail();
return new Form48Customer(name, checkIn, checkOut, email);
}

private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.insets = INSETS;
gbc.anchor = x == 0 ? GridBagConstraints.WEST :GridBagConstraints.EAST;
gbc.fill = GridBagConstraints.HORIZONTAL;
return gbc;
}

private class DateFieldVerifier extends InputVerifier {

@Override
public boolean verify(JComponent input) {
if (input instanceof JFormattedTextField) {
JFormattedTextField ftf = (JFormattedTextField)input;
AbstractFormatter formatter = ftf.getFormatter();
if (formatter != null) {
String text = ftf.getText();
try {
formatter.stringToValue(text);
return true;
} catch (ParseException pe) {
return false;
}
}
}
return true;
}

@Override
public boolean shouldYieldFocus(JComponent input) {
boolean verify = verify(input);
if (!verify) {
String message = "Enter a valid date, e.g.: 01/05/2017";
String title = "Invalid Date Format";
int type = JOptionPane.ERROR_MESSAGE;
JOptionPane.showMessageDialog(input, message, title, type);
}
return verify;
}
}
}

@SuppressWarnings("serial")
class Form48TableModel extends DefaultTableModel {
private static final String[] COL_NAMES = {"Name", "Check Out Date", "Check In Date", "Email"};

public Form48TableModel() {
super(COL_NAMES, 0);
}

public void addRow(Form48Customer customer) {
Object[] rowData = {
customer.getName(),
customer.getCheckOut(),
customer.getCheckIn(),
customer.getEmail()
};
addRow(rowData);
}

public Form48Customer getRow(int row) {
String name = (String) getValueAt(row, 0);
Date checkIn = (Date) getValueAt(row, 1);
Date checkOut = (Date) getValueAt(row, 2);
String email = (String) getValueAt(row, 3);
return new Form48Customer(name, checkIn, checkOut, email);
}

@Override
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 1:
return Date.class;
case 2:
return Date.class;

default:
break;
}
return super.getColumnClass(columnIndex);
}
}

看起来像:

enter image description here

关于java - 如何调整 Jpanel 中 JTextField 的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47249849/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com