user3371750
user3371750

Reputation:

Java Swing JTextfield Sizing (Height)

I'm having some problems getting a JTextfield in my program to the appropriate size, I am trying to amend the textfield with the text 'Price must be a real value'. This is what I would like it to look like:

enter image description here

And this is what mine currently looks like:

enter image description here

My code is as follows:

package test1;

import java.awt.Container;
import java.awt.FlowLayout;
import javax.swing.*;

public class Test1{

    //Should components be final? Should they be defined outside of the class?
    private final JTextArea outputArea = new JTextArea();
    private final JTextField errorReportField = new JTextField();

    private final JPanel inputPanel = new JPanel();

    private final JLabel nameLabel = new JLabel("Item Name");
    private final JLabel numberLabel = new JLabel("Number of units (or Volume in L)");
    private final JLabel priceLabel = new JLabel("Price per unit (or L) in pence");

    private final JTextField nameField = new JTextField(10);
    private final JTextField numberField = new JTextField(10);
    private final JTextField priceField = new JTextField(10);

    private final JButton addVolumeButton = new JButton("Add by Volume");
    private final JButton addNumberButton = new JButton("Add by number of units");         

    public Test1() {
        JFrame frame = new JFrame("Fuel station shop");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        outputArea.setEditable(false);
        outputArea.setRows(30);
        JScrollPane scrollPanel = new JScrollPane(outputArea);
        scrollPanel.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        errorReportField.setEditable(false);

        //Better way of adding multiple components to panel?
        inputPanel.setLayout(new FlowLayout());
        inputPanel.add(nameLabel);
        inputPanel.add(nameField);
        inputPanel.add(numberLabel);
        inputPanel.add(numberField);
        inputPanel.add(priceLabel);
        inputPanel.add(priceField);
        inputPanel.add(addVolumeButton);
        inputPanel.add(addNumberButton);

        Container contentPane = frame.getContentPane();
        //Why is it adding components from bottom to top?
        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
        contentPane.add(scrollPanel);
        contentPane.add(errorReportField);
        contentPane.add(inputPanel);

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

    public static void main(String[] args) {
        Test1 test = new Test1();
    }

}

So basically I would like to increase the height of the textfield while keeping the text centered, as well as changing the background to white while keeping it non-editable.

Upvotes: 3

Views: 2687

Answers (2)

Paul Samsotha
Paul Samsotha

Reputation: 209102

Use BorderLayout instead of BoxLayout.

Put the text area at BorderLayout.CENTER, and wrap the text field and the bottom panel in another panel with GridLayout(0, 1). Add that panel to BorderLayout.PAGE_END. The text field will be the same size as that bottom panel

Aside


Refactor

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.*;

public class Test1{

    //Should components be final? Should they be defined outside of the class?
    private final JTextArea outputArea = new JTextArea();
    private final JTextField errorReportField = new JTextField();

    private final JPanel inputPanel = new JPanel();

    private final JLabel nameLabel = new JLabel("Item Name");
    private final JLabel numberLabel = new JLabel("Number of units (or Volume in L)");
    private final JLabel priceLabel = new JLabel("Price per unit (or L) in pence");

    private final JTextField nameField = new JTextField(10);
    private final JTextField numberField = new JTextField(10);
    private final JTextField priceField = new JTextField(10);

    private final JButton addVolumeButton = new JButton("Add by Volume");
    private final JButton addNumberButton = new JButton("Add by number of units");         

    public Test1() {
        JFrame frame = new JFrame("Fuel station shop");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //outputArea.setEditable(false);
        outputArea.setRows(30);
        JScrollPane scrollPanel = new JScrollPane(outputArea);
        scrollPanel.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        //errorReportField.setEditable(false);

        //Better way of adding multiple components to panel?
        inputPanel.setLayout(new FlowLayout());
        inputPanel.add(nameLabel);
        inputPanel.add(nameField);
        inputPanel.add(numberLabel);
        inputPanel.add(numberField);
        inputPanel.add(priceLabel);
        inputPanel.add(priceField);
        inputPanel.add(addVolumeButton);
        inputPanel.add(addNumberButton);

        Container contentPane = frame.getContentPane();
        //Why is it adding components from bottom to top?
        contentPane.setLayout(new BorderLayout());
        contentPane.add(scrollPanel);
        JPanel wrapper = new JPanel(new GridLayout(0, 1));
        wrapper.add(errorReportField);
        wrapper.add(inputPanel);
        contentPane.add(wrapper, BorderLayout.PAGE_END);

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

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                Test1 test = new Test1();
            }
        });  
    }
}

Note

If you want the field a little bigger (height-wise), you can add an empty border to the inputPanel, causing the field to expand also. But this would mean that the inputPanel will be a little bigger also (may or may not be desired). But either way, with the GridLayout, the field and the inputPanel will be the same size.

inputPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

Another option would be to give the wrapper panel a BorderLayout and add the field to the center, giving it an EmptyBorder to expand its size.

contentPane.setLayout(new BorderLayout());
contentPane.add(scrollPanel);
JPanel wrapper = new JPanel(new BorderLayout());
wrapper.add(errorReportField);
wrapper.add(inputPanel, BorderLayout.PAGE_END);

Border border = errorReportField.getBorder();
CompoundBorder compound = BorderFactory.createCompoundBorder(
        border,BorderFactory.createEmptyBorder(10, 10, 10, 10));
errorReportField.setBorder(compound);

contentPane.add(wrapper, BorderLayout.PAGE_END);

This will give a slight margin on the left of the field (which may or may not be desireable). If you don't want it, just change the values for the empty border.

createEmptyBorder(top, left, bottom, right)

Upvotes: 1

Sergii Lagutin
Sergii Lagutin

Reputation: 10681

If you want increase field's height, modify its preffered size (apply method to your field):

private void increaseFieldHeight(JTextField field, int times) {
    Dimension d = field.getPreferredSize();
    d.height = d.height * times;
    field.setPreferredSize(d);
}

Upvotes: 0

Related Questions