0

I have a Java swing app like the screenshot below:

enter image description here

I need that when changing the size of the window, the text field on the bottom right also changes its size. Now it's always the same size.

Layouts I used:

  • 3 x BorderLayout (red) - one for the entire GUI, one each for the PAGE_START and PAGE_END constraints of the main GUI panel.

  • In the panel used in the PAGE_START, 2 x FlowLayout (green), one in the LINE_START, the other in the LINE_END. (1)

  • In the panel in the PAGE_END, 2 x GridLayout (blue), the first a 3 x 3, the other a single column.

enter image description here

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class MyJFrame extends JFrame {

    JPanel pan1 = new JPanel(); // top_left
    JPanel pan2 = new JPanel(); // top_right
    JPanel tPan = new JPanel(); // top
    JPanel pan4 = new JPanel(); // bottom_left
    JPanel pan5 = new JPanel(); // bottom_right
    JPanel bPan = new JPanel(); // bottom
    JPanel mPan = new JPanel(); // main

    JButton jButton1 = new JButton("FR");
    JButton jButton2 = new JButton("FG");
    JButton jButton3 = new JButton("FB");
    JButton jButton4 = new JButton("A");
    JButton jButton5 = new JButton("B");
    JButton jButton6 = new JButton("C");

    JTextArea textArea = new JTextArea();

    public MyJFrame(){

        setTitle("Simple Swing App");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        textArea.setFont(new Font("Ubuntu Mono", Font.PLAIN, 22));
        textArea.setEnabled(false);
        textArea.setText(" Obszar tekstowy typu jTextArea\n\n");
        textArea.setDisabledTextColor(Color.RED);

        JScrollPane scrollPane = new JScrollPane(textArea);

        jButton1.setBackground(Color.red);
        jButton2.setBackground(Color.green);
        jButton3.setBackground(Color.blue);

        jButton1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                textArea.setDisabledTextColor(Color.red);
                mPan.updateUI();
            }
        });
        jButton2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                textArea.setDisabledTextColor(Color.green);
                mPan.updateUI();
            }
        });
        jButton3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                textArea.setDisabledTextColor(Color.blue);
                mPan.updateUI();
            }
        });

        pan1.setLayout(new FlowLayout());
        pan2.setLayout(new FlowLayout());
        tPan.setLayout(new BorderLayout());
        pan4.setLayout(new GridLayout(3,3,2,2));
        pan5.setLayout(new GridLayout(3,1,0,2));
        bPan.setLayout(new BorderLayout());
        mPan.setLayout(new BorderLayout(2,2));

        bPan.setBorder(BorderFactory.createEmptyBorder(4,4,4,4));

        for (int i=1; i<10; i++) {
            JButton jButton = new JButton(i+"");
            pan4.add(jButton);
        }

        for (int i=1; i<4; i++){
            JTextField jTextField = new JTextField(" Pole tekstowe " + i + " typu jTextField ");
            jTextField.setBackground(Color.WHITE);
            jTextField.setBorder(BorderFactory.createLineBorder(Color.CYAN));
            jTextField.addKeyListener(new KeyAdapter() {
                @Override
                public void keyReleased(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER){
                        textArea.append(jTextField.getText() + "\n\n");
                        mPan.updateUI();
                    }
                }
            });
            pan5.add(jTextField);
        }

        pan1.add(jButton1);
        pan1.add(jButton2);
        pan1.add(jButton3);

        pan2.add(jButton4);
        pan2.add(jButton5);
        pan2.add(jButton6);

        tPan.add(pan1, BorderLayout.LINE_START);
        tPan.add(pan2, BorderLayout.LINE_END);

        bPan.add(pan4, BorderLayout.WEST);
        bPan.add(pan5, BorderLayout.EAST);

        mPan.add(tPan, BorderLayout.PAGE_START);
        mPan.add(scrollPane);
        mPan.add(bPan, BorderLayout.PAGE_END);

        add(mPan);
        setResizable(true);
        setSize(600,400);
        setLocationRelativeTo(null);
        setVisible(true);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
redtmp
  • 23
  • 2
  • 1
    Aside: You forgot to ask a question again. Fortunately I was familiar with your earlier question and comment, which was *"Is it possible to somehow ensure that the text field also changes its size?"*. It's always best practice to assume the reader has no idea what is required, and ask that type of simple, clear question within the initial post. – Andrew Thompson May 22 '21 at 10:33
  • *the text field on the bottom right also changes its size.* - define "changes its size". Do you mean veritcally, horizontally or both? Do you want the text field to take up all the extra space in the panel? Do you want fixed space between the buttons and the text fields. You need to be explicit when stating a requirement. You were given a link to the Swing tutorial on `How to Use a BorderLayout` in your last question. Did you read the link and download the demo code to play with it to understand how the BorderLayout works as the frame is resized? – camickr May 22 '21 at 13:40
  • Also, in the future post a proper [mre] when asking a question. Your question is about the resizing the component in the bottom panel. So the code posted should be only for the bottom panel. The code for the top two panels is irrelevant. We don't have time to read through your entire application code to understand the problem. – camickr May 22 '21 at 13:51
  • 1
    Other comments: 1) Don't use the `updateUI()` method. That method is invoked internally by Swing on a Look and Feel change. You never need to invoke that method directly. 2) Don't use a KeyListener. You can add an ActionListener to the text field. It will be activated when the Enter key is pressed. – camickr May 22 '21 at 13:52

1 Answers1

2

The trick to solving this is in understanding how BorderLayout assigns extra space to the areas within it. For example, let's say this is the initial size.

enter image description here

We can ignore the green areas, not relevant in the GUI in the question. But focus on the red / blue areas in the middle 'row'.

enter image description here

As the user drags the GUI larger, the red areas (LINE_START & LINE_END) will be assigned any extra height available, while the blue are will receive any extra height or width.

The GUI puts the text fields in the LINE_END. To have them gain any extra width, they need to be in the CENTER.

But wait, now the text fields will not be given any 'white space' between the first red area and the blue area in the center. There are various ways to fix this:

  1. Assign extra horizontal space to the border layout when it is constructed. Something like new BorderLayout(0, 100).
  2. Add an EmptyBorder to either the LINE_START or CENTER component. For the center component, it might look like this new EmptyBorder(0,100,0,0).

I would use the second, but either should create the effect needed.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 1
    *The trick to solving this is in understanding how BorderLayout assigns extra space* agreed. The OP was given a link to the Swing tutorial on `How to Use BorderLayout` in their last question: https://stackoverflow.com/questions/67639463/simple-window-in-swing-java. It would be nice if people actually take the time to read the tutorial to understand suggestions given rather than just copying code. This is a comment for the OP when they read the solution suggested here. – camickr May 22 '21 at 13:46