Search code examples
javaswingjscrollpanejtextarea

JTextArea truncating at JFrame bounds


When printing up to 363 lines in a JTextArea, the TextArea will truncate at about line 43 (frame bounds). I already put the JTextArea into a JScrollPane, and set the ScrollPolicy to ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS.... How do I make the JTextArea scrollable while writing content beyond the frame bounds?

public static double principalAmt, intRate, balance, monthlyIntRate, monthlyPayment, monthlyIntPayment, monthlyPrincipalPayment;
public static int termLength, months;

static Box infoBox = Box.createVerticalBox();
static Box graphBox = Box.createVerticalBox();

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

public AmortizationTable() {

    // User input
    principalAmt = 150000;
    termLength = 15;
    intRate = 0.05;

    // Calculated values
    balance = principalAmt;
    monthlyIntRate = intRate / 1200;
    months = termLength * 12;
    monthlyPayment = principalAmt * (monthlyIntRate *
            Math.pow(1 + monthlyIntRate, months) / (Math.pow(1 + monthlyIntRate, months) - 1));

    JFrame amortFrame = new JFrame();
    JPanel amortPanel = new JPanel();
    Box amortBox = Box.createVerticalBox();
    JTextArea amortText = new JTextArea();
    amortText.setEditable(false);

    String[] amortArray = new String[months];

    JLabel amortTitle1 = new JLabel("---------------------------------------------------"
            + "-------------------------------------------");
    JLabel amortTitle2 = new JLabel("Payment\tMonthly Payment\tInterest Paid\t\tPrincipal Paid\t\tBalance");
    JLabel amortTitle3 = new JLabel("-------------------------------------------------"
            + "---------------------------------------------");

    amortText.setText(amortText.getText() + amortTitle1.getText() + "\n");
    amortText.setText(amortText.getText() + amortTitle2.getText() + "\n");
    amortText.setText(amortText.getText() + amortTitle3.getText() + "\n");

    for(int i=0; i<months; i++) {

        monthlyIntPayment = balance * monthlyIntRate;
        monthlyPrincipalPayment = monthlyPayment - monthlyIntPayment;
        balance -= monthlyPrincipalPayment;
        if(balance<0)
            balance = -balance;

        amortArray[i] = ("" + (i+1) + "\t" + 
            new DecimalFormat("$0.00").format(monthlyPayment) + "\t\t" +
                new DecimalFormat("$0.00").format(monthlyIntPayment) + "\t\t" +
            new DecimalFormat("$0.00").format(monthlyPrincipalPayment) + "\t\t" +
                new DecimalFormat("$0.00").format(balance) + "\t\n");

        amortText.setText(amortText.getText() + amortArray[i]);

    }

    JScrollPane amortScroll = new JScrollPane(amortText);
    amortScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    amortBox.add(amortScroll);
    amortPanel.add(amortBox);
    amortFrame.add(amortPanel);
    amortFrame.setVisible(true);
}

Solution

  • You should always invoke frame.pack() or frame.setSize(...) before invoking frame.setVisible(true). Generally it is better to use frame.pack() to let the Swing components be painted at their preferred sizes.

    So next you actually need to give the text area a suggestion as to what its preferred size should be. This is done by doing:

    JTextArea amortText = new JTextArea(25, 70);
    

    Finally a better Swing component to use would be a JTable since it support tabular data. A JTextArea should not be used for formatted data.