Search code examples
javaswingscrollbarjscrollpanejtextarea

How can I add ScrollBar to JTextArea in Java Swing?


Anyone help me how to add a scroll bar to a JTextArea with Swing in Java?

The JTextArea just disappear when I add the scroll bar on it.

Hope somebody get me add a vertical scrollbar on it.

Additional explanation will be very thankful

public class Practice extends JFrame {
    JFrame frame = new JFrame("AAA");

    JTextArea textarea = new JTextArea();
    JScrollPane scroll = new JScrollPane(textarea);
    JPanel panelForScroll = new JPanel(null);

    public Practice(){
        frame.setLayout(null);
        frame.setBounds(100,100,400,710);
        frame.setResizable(false);
        frame.setVisible(true);

        textarea.setEditable(false);
        textarea.setFont(new Font("arian", Font.BOLD, 16));
        textarea.setBounds(20, 280, 340, 70);

        panelForScroll.add(scroll);
        frame.add(panelForScroll); //can't find text area....
    }

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

Solution

  • There are several errors in your code:

    1. You're using a null layout, this is discouraged as it produces more problems than solutions, specially when you try to use JScrollPanes, since they take the preferredSize of the Component to decide whether to add the scroll bars or not. See Why is it frowned upon to use a null layout in Swing? for more information about this. To fix this, remove this line:

       frame.setLayout(null);
      

      And instead use a layout manager or combinations of them along with borders for extra spacing between components.

      While null layouts might seem like the best, easiest and faster way to design complex GUIs for Swing newbies, the more you progress in it, the more problems related to the use of them you'll find (as it's the case)

    2. You're extending your class from JFrame and you're creating an instance of JFrame in it too, please use one or the other. When you extend JFrame you're saying your class is a JFrame and thus it cannot be placed inside another Container because JFrame is a rigid container. I recommend to forget the extends JFrame part, since anyway you're not using the JFrame that is generated by this action and stay with the object you created. See https://stackoverflow.com/questions/41252329/java-swing-using-extends-jframe-vs-calling-it-inside-of-class for a more detailed answer about this problem.

    3. You're making your GUI visible before you have added all the elements, this could cause your GUI to not display all the elements until you hover over them, this line:

       frame.setVisible(true);
      

      Should be one of the last lines in your program

    4. You're not placing your program on the Event Dispatch Thread (EDT) which makes your application to not be thread safe, you can fix it by writing this on your main method.

       SwingUtilities.invokeLater(new Runnable() {
           @Override
           public void run() {
               //Place your constructor here
           }
       });
      
    5. You're setting bounds for the textArea but not for the scrollPane, but you should really not be setting the bounds manually (see point #1 again).


    Now, you can make a simple GUI with a JTextArea with a JScrollPane as follows:

    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.SwingUtilities;
    
    public class ScrollPaneToTextArea {
    
        private JTextArea textArea;
        private JFrame frame;
        private JScrollPane scroll;
        
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new ScrollPaneToTextArea().createAndShowGui();
                }
            });
        }
        
        public void createAndShowGui() {
            frame = new JFrame("ScrollPane to TextArea");
            textArea = new JTextArea(10, 20); //Rows and cols to be displayed
            scroll = new JScrollPane(textArea);
    //      scroll = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
            
            frame.add(scroll); //We add the scroll, since the scroll already contains the textArea
            frame.pack();
            frame.setVisible(true);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    }
    

    Which produces this output and the scroll bars are added when needed (i.e. when text goes further than the rows it can handle in the view)

    enter image description here enter image description here

    If you want the vertical scroll bars to appear always you can uncomment the line:

    scroll = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    

    Which will produce the following outputs:

    enter image description here enter image description here

    You can read more about JScrollPane in the docs and JTextArea also in their own docs.