JTextField 可以在网格布局中调整大小吗?

can JTextField resizable in a gridlayout?

下面是我测试BorderLayoutGridLayout的代码,但是我发现JPanel中的JTextField使用GridLayout是不可调整大小的, JTextField.setPreferredSize 无论我改多少次,它还是一样。

public class Boderlayout implements ActionListener {
    JButton bCalculate;
    JLabel lPrinAmount,lInterestRate,lPayPerYear,lResult;
    JTextField tPrinAmount,tInterestRate,tPayPerYear,tResult;
    
    public static void main (String[] args) {
        new Boderlayout();
    }

    public Boderlayout() {
        JFrame frame = new JFrame();
        frame.setLayout(new BorderLayout());
        
        JPanel p2 = new JPanel();
        p2.setBackground(Color.BLUE);
        p2.setPreferredSize(new Dimension(600,100));
        frame.add(p2,BorderLayout.SOUTH);
        
        bCalculate = new JButton("Calculate");
        bCalculate.setPreferredSize(new Dimension(550,85));
        p2.add(bCalculate);
        bCalculate.addActionListener(this);
        
        JPanel p3 = new JPanel();
        p3.setBackground(Color.GREEN);
        p3.setLayout(new GridLayout(6,1));
        p3.setPreferredSize(new Dimension(300,300));
        frame.add(p3,BorderLayout.CENTER);
            
        lPrinAmount = new JLabel("Principle Amount: ");
        lPrinAmount.setPreferredSize(new Dimension(200,40));
        p3.add(lPrinAmount);
            
        tPrinAmount = new JTextField(20);
        tPrinAmount.setPreferredSize(new Dimension(170,40));
        p3.add(tPrinAmount);
            
        tPrinAmount.addActionListener(this);
            
        lInterestRate = new JLabel("Interest Rate: ");
        lInterestRate.setPreferredSize(new Dimension(200,40));
        p3.add(lInterestRate);
            
        tInterestRate = new JTextField(20);
        tInterestRate.setPreferredSize(new Dimension(100,40));
        p3.add(tInterestRate);
            
        tInterestRate.addActionListener(this);
            
        lPayPerYear = new JLabel("Payment Period (Year): ");
        lPayPerYear.setPreferredSize(new Dimension(200,40));
        p3.add(lPayPerYear);
            
        tPayPerYear = new JTextField(20);
        tPayPerYear.setPreferredSize(new Dimension(170,40));
        p3.add(tPayPerYear);
            
        tPayPerYear.addActionListener(this);
        
        JPanel p5 = new JPanel();
        p5.setLayout(new GridLayout(2,1));
        p5.setBackground(Color.WHITE);
        p5.setPreferredSize(new Dimension(300,300));
        frame.add(p5,BorderLayout.EAST);
        
        lResult = new JLabel("Result");
        lResult.setPreferredSize(new Dimension(170,40));
        p5.add(lResult);
            
        tResult = new JTextField(50);
        tResult.setPreferredSize(new Dimension(170,200));
        tResult.setEditable(false);
        p5.add(tResult);
        
        frame.pack();
        frame.setVisible(true);
    }
    
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        if (e.getSource() == bCalculate) {
            double prinAmount = Double.parseDouble(tPrinAmount.getText());
            double interestRate = Integer.parseInt(tInterestRate.getText());
            double paymentYear = Integer.parseInt(tPayPerYear.getText());
            
            double interestRatePercentage = interestRate / 100;
            double loanInterest = prinAmount * interestRatePercentage;
            double year = 12 * paymentYear;
            double mortgageResult = (loanInterest * (Math.pow((1 + (interestRatePercentage / 12)), year)) / (Math.pow((1 + (interestRatePercentage) / 12), year) - 1)) / 12;
            
            String stringmortgageResult = Double.toString(mortgageResult);
            String newline = System.getProperty("line.separator");
            String finalResult = "Principle Amount: " + tPrinAmount.getText() + newline + "Interest Rate: " + tInterestRate.getText() + "%" + newline + "Payment Period: " + tPayPerYear.getText()
            + newline + "Mortgage: " + stringmortgageResult;
            tResult.setText(finalResult);
        }
    }
}

参考How to Use GridLayout.
这是该网页的引述:

A GridLayout object places components in a grid of cells. Each component takes all the available space within its cell, and each cell is exactly the same size.

换句话说,GridLayout没有考虑它包含的组件的首选大小。

确实考虑其包含的组件的首选大小的布局管理器是 GridBagLayout

BorderLayout 仅考虑其包含的部分组件的首选大小。对于 EAST 组件,BorderLayout 使用其首选宽度而不是其首选高度。 BorderLayout 最初将使用其 CENTER 组件的首选宽度和高度。

这是我 运行 你的代码时得到的 window。

这是您修改后的代码,使用 GridBagLayout 而不是 GridLayout

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class Boderlayout implements ActionListener {
    JButton bCalculate;
    JLabel lPrinAmount, lInterestRate, lPayPerYear, lResult;
    JTextArea tResult;
    JTextField tPrinAmount, tInterestRate, tPayPerYear;

    public static void main(String[] args) {
        new Boderlayout();
    }

    public Boderlayout() {
        JFrame frame = new JFrame();

        JPanel p2 = new JPanel();
        p2.setBackground(Color.BLUE);
        p2.setPreferredSize(new Dimension(600, 100));
        frame.add(p2, BorderLayout.SOUTH);

        bCalculate = new JButton("Calculate");
        bCalculate.setPreferredSize(new Dimension(550, 85));
        p2.add(bCalculate);
        bCalculate.addActionListener(this);

        JPanel p3 = new JPanel();
        p3.setBackground(Color.GREEN);
        p3.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        p3.setPreferredSize(new Dimension(300, 300));
        frame.add(p3, BorderLayout.CENTER);

        lPrinAmount = new JLabel("Principle Amount: ");
        lPrinAmount.setPreferredSize(new Dimension(200, 40));
        gbc.gridx = 0;
        gbc.gridy = 0;
        p3.add(lPrinAmount, gbc);

        tPrinAmount = new JTextField(20);
        tPrinAmount.setPreferredSize(new Dimension(170, 40));
        gbc.gridy = 1;
        p3.add(tPrinAmount, gbc);

        tPrinAmount.addActionListener(this);

        lInterestRate = new JLabel("Interest Rate: ");
        lInterestRate.setPreferredSize(new Dimension(200, 40));
        gbc.gridy = 2;
        p3.add(lInterestRate, gbc);

        tInterestRate = new JTextField(20);
        tInterestRate.setPreferredSize(new Dimension(100, 40));
        gbc.gridy = 3;
        p3.add(tInterestRate, gbc);

        tInterestRate.addActionListener(this);

        lPayPerYear = new JLabel("Payment Period (Year): ");
        lPayPerYear.setPreferredSize(new Dimension(200, 40));
        gbc.gridy = 4;
        p3.add(lPayPerYear, gbc);

        tPayPerYear = new JTextField(20);
        tPayPerYear.setPreferredSize(new Dimension(170, 40));
        gbc.gridy = 5;
        p3.add(tPayPerYear, gbc);

        tPayPerYear.addActionListener(this);

        JPanel p5 = new JPanel();
        p5.setLayout(new BoxLayout(p5, BoxLayout.PAGE_AXIS));
        p5.setBackground(Color.WHITE);
        p5.setPreferredSize(new Dimension(300, 300));
        frame.add(p5, BorderLayout.EAST);

        lResult = new JLabel("Result");
        lResult.setPreferredSize(new Dimension(170, 40));
        p5.add(lResult);

        tResult = new JTextArea();
        tResult.setPreferredSize(new Dimension(170, 200));
        tResult.setEditable(false);
        tResult.setBorder(BorderFactory.createLineBorder(Color.darkGray));
        p5.add(tResult);

        frame.pack();
        frame.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == bCalculate) {
            double prinAmount = Double.parseDouble(tPrinAmount.getText());
            double interestRate = Integer.parseInt(tInterestRate.getText());
            double paymentYear = Integer.parseInt(tPayPerYear.getText());

            double interestRatePercentage = interestRate / 100;
            double loanInterest = prinAmount * interestRatePercentage;
            double year = 12 * paymentYear;
            double mortgageResult = (loanInterest
                    * (Math.pow((1 + (interestRatePercentage / 12)), year))
                    / (Math.pow((1 + (interestRatePercentage) / 12), year) - 1)) / 12;

            String stringmortgageResult = Double.toString(mortgageResult);
            String newline = System.getProperty("line.separator");
            String finalResult = "Principle Amount: " + tPrinAmount.getText() + newline
                    + "Interest Rate: " + tInterestRate.getText() + "%" + newline
                    + "Payment Period: " + tPayPerYear.getText() + newline + "Mortgage: "
                    + stringmortgageResult;
            tResult.setText(finalResult);
        }
    }
}

这是我 运行 上述代码时得到的 window。

请注意,我将 tResult 更改为 JTextArea 而不是 JTextField