Search code examples
javaswingjscrollpanejtextareagridbaglayout

Adding JScrollPane in JTextArea using GridBagLayout


I'm having an issue adding JScrollPane in JTextArea using GridBagLayout. Basically the program runs fine when the scrollbar isn't needed but the layout gets messed up and the content gets cut off when it is. The relevent code is as follows

import java.io.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;

public class testGUI extends JFrame
{
    public static String name;
    static JTextField textfield = new JTextField(30);
    static JTextArea  textarea = new JTextArea(30,30);

    public static void main( String[] args)
    {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("Checkem");
        frame.setLocation(500,400);
        frame.setSize(800,800);

        JPanel panel = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        JScrollPane scrolltxt = new JScrollPane(textarea,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        scrolltxt.setWheelScrollingEnabled(true); 
        scrolltxt.getVerticalScrollBar().isVisible();
        panel.add(scrolltxt, c); 

        JLabel label = new JLabel("Enter the Name of the file:");
        c.gridx = 0;
        c.gridy = 0;
        c.insets = new Insets(2,2,2,2);

        panel.add(label,c);

        c.gridx = 0;
        c.gridy = 1;
        panel.add(textarea,c);      

        JButton button = new JButton("Search");
        c.gridx = 1;
        c.gridy = 1;
        panel.add(button,c);

        c.gridx = 1;
        c.gridy = 0;
        panel.add(textfield,c);


        frame.getContentPane().add(panel, BorderLayout.NORTH);
        frame.pack();
        frame.setVisible(true);

        button.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                Checkem record = new Checkem();
                name = textfield.getText();         
                String [] print = record.run(name);

                for (int i=0;i<print.length;i++)
                {
                    if(print[i] == null || print[i].isEmpty())
                    {
                        continue;
                    }
                    else
                    {
                        textarea.append(print[i] + "\n");
                    }
                }
            }
        });

    }
}

I'm really new to swing and I'm really at a loss where to go from here. Thanks for all your help.


Solution

    • First please learn Java Naming Conventions, that makes it a bit easier for the other person to understand the Java code.

    Now to the actual thingy :-)

    • Why not simply use JTextArea.setLineWrap(true) and JTextArea.setWrapStyleWord(true) instead of defining JScrollBar policy, this will even look nice on the view :-)
    • Moreover, instead of specifying setSize()/setLocation() methods, simply use frameReference.pack() and frame.setLocationByPlatform(true), a very wonderful answer regarding the benefit of the latter is mentioned in this answer, how to best position Swing GUIs
    • Do not make so many static fields in a class, this smells like a bad programming design, and makes your class less extensible.
    • You are extending JFrame to your TestGUI class and then inside it's main() method you creating an instance of the same. Actually again, try to give more weightage to composition over inheritance, since over here, you not actually trying to modify the already defined features of JFrame, instead you just using them as is, so there is no need to extend JFrame in this case atleast :-)
    • Read about Concurrency in Swing

    Here is your modified code :

    import java.io.*;
    import java.awt.*;
    import javax.swing.*;
    import java.awt.event.*;
    import java.util.*;
    
    public class TestGUI {
    
        private String name;
        private JTextField textfield = new JTextField(30);
        private JTextArea  textarea = new JTextArea(30,30);
    
        private void displayGUI() {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setTitle("Checkem");        
    
            JPanel panel = new JPanel(new GridBagLayout());
            GridBagConstraints c = new GridBagConstraints();
            textarea.setLineWrap(true);
            textarea.setWrapStyleWord(true);
            JScrollPane scrolltxt = new JScrollPane();
            scrolltxt.setViewportView(textarea);
            scrolltxt.setWheelScrollingEnabled(true);
    
            JLabel label = new JLabel("Enter the Name of the file:");
            c.gridx = 0;
            c.gridy = 0;
            c.insets = new Insets(2,2,2,2);
    
            panel.add(label,c);
    
            c.gridx = 0;
            c.gridy = 1;
            panel.add(scrolltxt,c);      
    
            JButton button = new JButton("Search");
            c.gridx = 1;
            c.gridy = 1;
            panel.add(button,c);
    
            c.gridx = 1;
            c.gridy = 0;
            panel.add(textfield,c);
    
    
            frame.getContentPane().add(panel, BorderLayout.NORTH);      
            //frame.setSize(800,800);
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
    
            button.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent ae)
                {
                    /*Checkem record = new Checkem();
                    name = textfield.getText();         
                    String [] print = record.run(name);
    
                    for (int i=0;i<print.length;i++)
                    {
                        if(print[i] == null || print[i].isEmpty())
                        {
                            continue;
                        }
                        else
                        {
                            textarea.append(print[i] + "\n");
                        }
                    }*/
                }
            });
        }
    
        public static void main( String[] args) {
            Runnable r = new Runnable() {
                @Override
                public void run() {
                    new TestGUI().displayGUI();
                }
            };
            EventQueue.invokeLater(r);
        }
    }