javaswingjframejtextareasetbounds

Scrollbar JTextarea not working


For some reason my scrollbar is appearing but it is not working. What is suppose to happen is using the scrollbar to scroll through the text of the textarea. Can somebody please explain why this isnt working?

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

public class App extends JFrame{
    private JPanel paneel;

    public App(){   
        paneel = new AppPaneel();
        setContentPane(paneel);
    }

    public static void main(String args[]){
        JFrame frame = new App();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 400);
        frame.setTitle("Auto Clicker");
        frame.setVisible(true);
    }
}

class AppPaneel extends JPanel{
    private JTextField delayField, xLocation, yLocation;
    private JTextArea listArea;
    private JButton addButton, saveButton, runButton;
    private JScrollPane scroll;

    public AppPaneel(){
        setLayout(null);

        delayField = new JTextField();
        delayField.setBounds(10, 10, 85, 25);
        delayField.setText("delay in ms"); 

        xLocation = new JTextField();
        xLocation.setBounds(105, 10, 85, 25);
        xLocation.setText("X position"); 

        yLocation = new JTextField();
        yLocation.setBounds(200, 10, 85, 25);
        yLocation.setText("Y position");

        addButton = new JButton("Add");
        addButton.setBounds(295, 10, 75, 24);
        addButton.addActionListener(new AddHandler());

        listArea = new JTextArea();
        listArea.setBounds(10, 45, 360, 180);
        scroll = new JScrollPane(listArea);
        scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        scroll.setBounds(370, 45, 20, 180);

        saveButton = new JButton("Save");
        saveButton.setBounds(10, 230, 85, 24);

        runButton = new JButton("Run (F1)");
        runButton.setBounds(105, 230, 85, 24);
        runButton.addActionListener(new RunHandler());

        add(delayField);
        add(xLocation);
        add(yLocation);
        add(addButton);
        add(listArea);
        add(saveButton);
        add(runButton);
        add(scroll);
    }

    class AddHandler implements ActionListener{
        public void actionPerformed(ActionEvent a){
            listArea.setText(listArea.getText() + delayField.getText() + ",     " + xLocation.getText() + ", " + yLocation.getText() + ", " + "click;" + "\n");
        }
    }

    class RunHandler implements ActionListener{
        private Robot bot;
        private String text;
        int foo = Integer.parseInt("1234");
        public void actionPerformed(ActionEvent b) {
            try{
                text  = listArea.getText();
                bot = new Robot();
                for(String line : text.split("\\n")){
                int delay = Integer.parseInt((line.substring(0, 4)));
                int xpos = Integer.parseInt((line.substring(6, 10)));
                int ypos = Integer.parseInt((line.substring(12, 16)));
                bot.mouseMove(xpos, ypos);
                Thread.sleep(delay);
                bot.mousePress(InputEvent.BUTTON1_MASK);
                bot.mouseRelease(InputEvent.BUTTON1_MASK);
                }
            } 
            catch (AWTException | InterruptedException e){
                e.printStackTrace();
            }
        }
    }
}

Solution

  • Don't use null layouts and setBounds as it is messing up your program. We tell folks time and time again not to do this for a reason -- by setting the JTextArea's bound you constrain its size so it won't grow when it needs to. The solution, as always -- learn and use the layout managers. Set the JTextArea's column and row properties but not its bounds, its size, or its preferred size.

    Next don't do this: Thread.sleep(delay); in your Swing application as it will put the entire application to sleep. Use a Swing Timer instead for any delays. The tutorials can help you use this.

    For a non-functional layout example:

    import java.awt.BorderLayout;
    import java.awt.GridLayout;
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class App2 extends JPanel {
        private static final int GAP = 5;
        private JTextField textField1 = new JTextField(GAP);
        private JTextField textField2 = new JTextField(GAP);
        private JTextField textField3 = new JTextField(GAP);
        private JTextArea textArea = new JTextArea(15, 30);
    
        public App2() {
            JPanel topPanel = new JPanel(new GridLayout(1, 0, GAP, GAP));
            topPanel.add(textField1);
            topPanel.add(textField2);
            topPanel.add(textField3);
            topPanel.add(new JButton("Add"));
    
            textArea.setWrapStyleWord(true);
            textArea.setLineWrap(true);
            JScrollPane scrollPane = new JScrollPane(textArea);
            scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    
            JPanel bottomPanel = new JPanel(new GridLayout(1, 0, GAP, GAP));
            bottomPanel.add(new JButton("Save"));
            bottomPanel.add(new JButton("Run (F1)"));
            bottomPanel.add(new JLabel(""));
            bottomPanel.add(new JLabel(""));
    
            setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
            setLayout(new BorderLayout(GAP, GAP));
            add(topPanel, BorderLayout.PAGE_START);
            add(scrollPane, BorderLayout.CENTER);
            add(bottomPanel, BorderLayout.PAGE_END);
        }
    
        private static void createAndShowGui() {
            JFrame frame = new JFrame("Auto Clicker");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(new App2());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGui();
                }
            });
        }
    }