How does java swing fix the percentage size of the JTextArea so that it doesn't change?

80 Views Asked by At

I am developing a GUI interface using Java Swing's GridBagLayout, in which I use JTextArea, which I set to 40% on the left side after adding it to the JScrollPane, and a JList on the right side after adding the JScrollPane to 60%. When I first opened the JTextArea and the JList components were normal, but when I pasted text into the JTextArea, the size of the JTextArea changed, which bothered me for a long time.

I would like to ask the gods of stackoverflow how to solve this problem. How to guarantee that no matter what I type in JTextArea, no matter how big the form is, JTextArea is always guaranteed to be 40% and JList is always guaranteed to be 60%.

The interface after first opening the program

The size of the JTextArea changes after the text is entered

Sometimes, when I maximize the window and minimize it may change for a while, and then for a while JTextArea's broadband will be stretched out again. It's really upsetting and I don't know what to do about it.

I use GridBagLayout, I don't know if something is not adjusted properly.

the program code snippet 1

the program code snippet 2

At first, I thought it was the problem of GridBagLayout parameter setting. Other people had set weightx to 1.0, so I also set it to 1.0. In the beginning, I used 0.4 and 0.6. Both are set to 1.0, so that the ratio is 50%, but this does not help, the size of the JTextArea will still be widened after entering the text. I adjusted it back.

Others say to use new JTextArea(20,10) to specify rows and columns, but I've tried that too and it doesn't work.

I updated the dynamic effect of the JTextArea image

I found the reason, this is the code, and the reason is that I added the insert and change and delete listening events to the textArea. I added a function to these events to set the content of the JLabel to the number of words in the TextArea, and then this happened. But I haven't solved it yet.

package jlist.demo;

import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rtextarea.RTextArea;
import org.fife.ui.rtextarea.RTextScrollPane;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;

public class TestWinFrame2 extends JFrame {

    RTextArea textArea;
    RTextScrollPane scrollForTextArea;

    RTextArea textArea2;
    RTextScrollPane ScrollForTextArea2;

    JPanel leftPanel;

    JList jList;
    JScrollPane listScrollPane;

    JLabel wordNumberLabel;
    JToolBar toolBar;

    public TestWinFrame2() {
        GridBagLayout gridBagLayout = new GridBagLayout();
        setLayout(gridBagLayout);

        toolBar = new JToolBar(JToolBar.HORIZONTAL);

        // Add the toolbar to the panel, not the frame or contentPane
        GridBagConstraints bag = new GridBagConstraints();
        bag.anchor = GridBagConstraints.NORTHWEST; // Adjust the position of the toolbar
        bag.gridx = 0;
        bag.gridy = 0;
        bag.gridheight = 1;
        bag.gridwidth = 2;
        bag.weightx = 1.0; // Make the toolbar span the whole width of the panel
        bag.fill = GridBagConstraints.HORIZONTAL; // Make the toolbar fill the horizontal space
        wordNumberLabel = new JLabel("word-count");
        toolBar.add(wordNumberLabel);

        add(toolBar, bag);


        textArea = new RSyntaxTextArea();
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        scrollForTextArea = new RTextScrollPane(textArea);
        GridBagConstraints gbc_ScrollForTextArea = new GridBagConstraints();
        gbc_ScrollForTextArea.anchor = GridBagConstraints.WEST;
        gbc_ScrollForTextArea.fill = GridBagConstraints.BOTH;
        gbc_ScrollForTextArea.gridx = 0;
        gbc_ScrollForTextArea.gridy = 1;
        gbc_ScrollForTextArea.gridheight = 1;
        gbc_ScrollForTextArea.gridwidth = 1;
        gbc_ScrollForTextArea.weightx = 0.3d;
        gbc_ScrollForTextArea.weighty = 0.5d;
        add(scrollForTextArea, gbc_ScrollForTextArea);


        textArea2 = new RSyntaxTextArea();
        textArea2.setLineWrap(true);
        textArea2.setWrapStyleWord(true);
        ScrollForTextArea2 = new RTextScrollPane(textArea2);
        textAreaAddInsertListener();
        GridBagConstraints gbc_ScrollForTextArea2 = new GridBagConstraints();
        gbc_ScrollForTextArea2.anchor = GridBagConstraints.WEST;
        gbc_ScrollForTextArea2.fill = GridBagConstraints.BOTH;
        gbc_ScrollForTextArea2.gridx = 0;
        gbc_ScrollForTextArea2.gridy = 2;
        gbc_ScrollForTextArea2.gridheight = 1;
        gbc_ScrollForTextArea2.gridwidth = 1;
        gbc_ScrollForTextArea2.weightx = 0.3d;
        gbc_ScrollForTextArea2.weighty = 0.5d;
        add(ScrollForTextArea2, gbc_ScrollForTextArea2);

        jList = new JList();
        listScrollPane = new JScrollPane(jList);
        GridBagConstraints gbc_listScrollPane = new GridBagConstraints();
        gbc_listScrollPane.anchor = GridBagConstraints.WEST;
        gbc_listScrollPane.fill = GridBagConstraints.BOTH;
        gbc_listScrollPane.gridx = 1;
        gbc_listScrollPane.gridy = 1;
        gbc_listScrollPane.gridheight = 2;
        gbc_listScrollPane.gridwidth = 1;
        gbc_listScrollPane.weightx = 1.0d;
        gbc_listScrollPane.weighty = 1.0d;
        add(listScrollPane, gbc_listScrollPane);


        setSize(1200, 800);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public void textAreaAddInsertListener() {
        textArea.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                System.out.println("insertUpdate---------------");
                wordNumberLabel.setText(textArea.getText().length() + "");
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                System.out.println("removeUpdate---------------");
                wordNumberLabel.setText(textArea.getText().length() + "");
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                System.out.println("changedUpdate---------------");
                wordNumberLabel.setText(textArea.getText().length() + "");
            }
        });
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestWinFrame2();
            }
        });
    }

}

2

There are 2 best solutions below

2
ControlAltDel On

One simple, kind of "klugy" solution

public MyGridBagLayout extends GridBagLayout {
  public void layoutContainer(Container parent) {
    super.layoutContainer(parent);
    // Now check the TextArea is the taking up the correct amount of space
    // And if not, adjust it and the Component to the right
  }
}

Like I've already admitted, this is a kludge. But IMO the time you spend learning to master Swing is time better spent learning CSS 3.

0
John H On

It doesn't look like the upper left text area is scrollable horizontally. If you add that, the textarea shouldn't resize anymore, yes?

new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED)

I use an old Sun layout class called VariableGridLayout that I modified to do variable width columns. I imagine RelativeLayout is probably an option, too.