簡體   English   中英

如何在Jpanel中調整JTextField的大小

[英]How can I resize my JTextFields in my Jpanel

作為編程的新手,我在調整已添加到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。 為什么這么小? 因為您尚未設置JTextField的columns屬性,所以它們默認為列大小0並顯示如下:

在此處輸入圖片說明

因此,最好給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,並且也切斷了底部:

在此處輸入圖片說明

為什么? 由於您是人為地限制了包含的JPanel的大小,因此主要通過以下方式進行:

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

這個包含JPanel的像素只有128像素寬,20像素高,這意味着它甚至不能很好地顯示一個JTextField。

一種解決方案是使用布局管理器和JPanels以及JScrollPane的混合使用,以允許添加JPanels網格,如下所示(嘗試一下!):

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時,它們將被添加到JScrollPane中,如下所示:

在此處輸入圖片說明

但我們仍然可以做得更好。 為什么不創建一個類來保存一行數據,就像這樣:

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);
    }
}

看起來像:

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM