How do I add a scroll bar in a null layout?

2.3k views Asked by At

I have been trying to get a scroll bar on my JTextArea for days, I've tried every way to do it as I could find. I am making a Chat Client and I have the JPanel setup with a null layout. I've tried using the Layout Managers but I don't understand how to get it to look the way I want.

I just want a scroll bar on the text area. I'm a beginner and for what I've read it isn't possible to have one with a null layout? I'm open to help changing the layout if that's easier also.

Chat Server Client

package guiserver;

import com.apple.eawt.Application;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;

public class GUIserver extends JFrame implements ActionListener {

JFrame login = new JFrame();
JPanel panel = new JPanel();
JPanel main = new JPanel();
JFrame accept = new JFrame();
JPanel acpt = new JPanel();
JPanel buttonpanel = new JPanel();
JButton acceptinvite = new JButton("Accept Invite");
JButton denyinvite = new JButton("Deny Invite");
JLabel acceptlabel = new JLabel();
JLabel acceptname = new JLabel();
JPanel loginpanel = new JPanel();
JTextArea chat = new JTextArea(" Waiting to Start Client...");
JSplitPane chatsplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
JTextField input = new JTextField();
JScrollPane pane = new JScrollPane(chat);
JButton send = new JButton("Send");
JLabel IP = new JLabel("IP:... ");
JButton start = new JButton("Start");
sendThread s1 = new sendThread();
fromThread f1 = new fromThread();
infoFromThread f2 = new infoFromThread();
infoToThread s2 = new infoToThread();
RPSpickTimer pt = new RPSpickTimer();
myCanvas contact = new myCanvas();
myCanvas logo = new myCanvas();
JButton rock = new JButton("Rock");
JButton paper = new JButton("Paper");
JButton scissors = new JButton("Scissors");
JTextField username = new JTextField();
JLabel loguser = new JLabel("Username:");
JLabel logpass = new JLabel("Password:");
JPasswordField password = new JPasswordField();
JButton signin = new JButton("Sign in");
String inputText = "0";
String chatCurrent;
String out1;
String in;
boolean pause = true;
boolean rps = false;
int P1pick = 0;
int P2pick = 0;
String user = "User 1";
String user2 = "Jacob Abthorpe";
String pass;
int badge;
int sendinvite = 0;
char answerinvite = '-';
boolean pauseInfo = true;
int winner = 0;

public GUIserver() {
    Application application = Application.getApplication();
    Image image = Toolkit.getDefaultToolkit().getImage("src/icon.png");
    application.setDockIconImage(image);

    login.setVisible(true);
    login.setSize(400, 500);
    login.setLocationRelativeTo(null);
    login.setTitle("Login");
    login.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    login.add(loginpanel);
    loginpanel.setLayout(null);
    loginpanel.add(username);
    loginpanel.add(password);
    loginpanel.add(signin);
    loginpanel.add(logpass);
    loginpanel.add(loguser);
    loginpanel.add(logo);
    login.setAlwaysOnTop(true);
    username.setHorizontalAlignment(JTextField.CENTER);
    password.setHorizontalAlignment(JTextField.CENTER);
    username.setBounds(50, 290, 300, 30);
    password.setBounds(50, 350, 300, 30);
    loguser.setBounds(55, 265, 300, 30);
    logpass.setBounds(55, 325, 300, 30);
    signin.setBounds(150, 400, 100, 30);
    logo.setBounds(110, 50, 150, 150);
    username.addActionListener(this);
    password.addActionListener(this);
    signin.addActionListener(this);

    setVisible(false);
    setSize(500, 600);
    setLocationRelativeTo(null);
    setTitle("Chat Server Client");
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    setAlwaysOnTop(true);
    panel.setLayout(null);
    panel.setLocation(300, 0);
    panel.add(pane);
    panel.add(input);
    panel.add(send);
    panel.add(IP);
    panel.add(start);
    panel.add(rock);
    panel.add(paper);
    panel.add(scissors);
    contact.picx = 120;
    contact.picy = 120;
    contact.setBackground(Color.white);
    contact.setBounds(370, 10, 120, 120);
    panel.add(contact);
    input.addActionListener(this);
    send.addActionListener(this);
    start.addActionListener(this);
    rock.addActionListener(this);
    paper.addActionListener(this);
    scissors.addActionListener(this);
    chat.setEditable(false);
    pane.setBounds(10, 10, 350, 450);
    input.setEditable(false);
    input.setBounds(10, 470, 350, 80);
    start.setBounds(370, 470, 115, 80);
    IP.setBounds(15, 520, 480, 80);
    rock.setVisible(false);
    paper.setVisible(false);
    scissors.setVisible(false);
    scissors.setBounds(370, 430, 115, 30);
    paper.setBounds(370, 400, 115, 30);
    rock.setBounds(370, 370, 115, 30);
    setContentPane(panel);


    accept.setVisible(false);
    accept.setSize(400, 125);
    accept.setLocationRelativeTo(null);
    accept.setTitle("Rock, Paper, Scissors");
    accept.setAlwaysOnTop(true);
    accept.setResizable(false);
    accept.add(acpt);
    acpt.setLayout(null);
    acpt.add(acceptlabel);
    acpt.add(buttonpanel);
    acpt.add(acceptname);
    buttonpanel.setBounds(0, 60, 400, 40);
    buttonpanel.setLayout(new FlowLayout());
    acceptlabel.setHorizontalAlignment(SwingConstants.CENTER);
    acceptlabel.setText("would like to play Rock, Paper, Scissors. Accept?");
    acceptlabel.setBounds(0, 25, 400, 40);
    acceptname.setHorizontalAlignment(SwingConstants.CENTER);
    acceptname.setText(user2 + "");
    acceptname.setBounds(0, 3, 400, 40);
    buttonpanel.add(acceptinvite);
    buttonpanel.add(denyinvite);
    acceptinvite.addActionListener(this);
    denyinvite.addActionListener(this);
}

public void actionPerformed(ActionEvent e) {
    if (e.getSource() == input) {
        if (input.getText().startsWith("/")) {
            if (input.getText().contentEquals("/")) {
                chat.append("\n\n >Type '/help' for list of all commands");
            }
            if (input.getText().contentEquals("/start RPS")) {
                chat.append("\n \n >Waiting for opponent to accept invite. . .");
                pauseInfo = false;
                sendinvite = 10;
            }
            if (input.getText().contentEquals("/help")) {
                chat.append("\n\n >Type '/help' for list of all commands");
                chat.append("\n >Type '/start RPS' to play Rock Paper Scissors");
                chat.append("\n >Type '/end' to quit current game");
            }
            if (input.getText().contentEquals("/end")) {
                if (rps == true) {
                    chat.append("\n\n >Quiting Rock, Paper, Scissors. . .");
                    rps = false;
                    rock.setVisible(false);
                    paper.setVisible(false);
                    scissors.setVisible(false);
                }
            }
            input.setText("");
        } else {
            if ((input.getText().contentEquals("")) && (input.getText().contentEquals(" "))) {
                Toolkit.getDefaultToolkit().beep();
            } else {
                pause = false;
                chat.append("\n \n " + user + " says: \n        " + input.getText());
                inputText = input.getText();
                input.setText("");
            }
        }
    }
    if (e.getSource() == send) {
        //chat.append("\n \n Dale Schmidt says: \n        " + inputText);
        //pause = false;
    }
    if (e.getSource() == username) {
        user = username.getText();
    }
    if (e.getSource() == signin) {
        login.setVisible(false);
        setVisible(true);
    }
    if (e.getSource() == start) {
        try {
            s1.start();
            f1.start();
            s2.start();
            f2.start();
            setAlwaysOnTop(false);
            chat.append("\n " + InetAddress.getLocalHost() + "\n Server started.");
            IP.setText("IP: " + InetAddress.getLocalHost());
            start.setVisible(false);
            send.setVisible(true);
            input.setEditable(true);
            send.setBounds(370, 470, 115, 80);
        } catch (Exception s) {
            System.out.print("YOLOerror starting server");
        }
    }
    if (e.getSource() == rock) {
        if ((rps == true) && (P1pick == 0)) {
            P1pick = 1;
            chat.append("\n\n >You picked 'Rock'");
            if (P2pick != 0) {
                pt.start();
            }
        }
    }
    if (e.getSource() == paper) {
        if ((rps == true) && (P1pick == 0)) {
            P1pick = 2;
            chat.append("\n\n >You picked 'Paper'");
            if (P2pick != 0) {
                pt.start();
            }
        }
    }
    if (e.getSource() == scissors) {
        if ((rps == true) && (P1pick == 0)) {
            P1pick = 3;
            chat.append("\n\n >You picked 'Scissors'");
            if (P2pick != 0) {
                pt.start();
            }
        }
    }
    if (e.getSource() == acceptinvite) {
        rps = true;
        rock.setVisible(true);
        paper.setVisible(true);
        scissors.setVisible(true);
        answerinvite = 'y';
        accept.dispose();
    }
    if (e.getSource() == denyinvite) {
        answerinvite = 'n';
        accept.dispose();
    }
}

class myCanvas extends Canvas {

    int x = 10, y = 10;
    int picx = 150, picy = 150;

    public void paint(Graphics g) {
        Image image1 = Toolkit.getDefaultToolkit().getImage("src/icon.png");
        g.drawImage(image1, x, y, picx, picy, this);
    }
}    

class sendThread extends Thread {

    ServerSocket s1;
    Socket sendclientSocket = null;

    public void run() {
        inputText = input.getText();
        try {
            System.err.println("Starting Send Server");
            System.out.println(InetAddress.getLocalHost());
            s1 = new ServerSocket(4444);
            sendclientSocket = s1.accept();
            System.err.println("Started Send Server");
        } catch (Exception s1) {
            System.exit(1);
        }
        while (true) {
            try {
                PrintWriter out = new PrintWriter(sendclientSocket.getOutputStream(), true);

                if (pause == false) {
                    badge = 0;
                    out.println(input.getText());
                    System.out.println("sent");
                    pause = true;
                }
            } catch (Exception e) {
                System.err.println("Error Sending.");
                System.err.println(e.getMessage());
                System.exit(2);
            }
        }
    }
}

class fromThread extends Thread {

    ServerSocket s2;
    Socket fromclientSocket = null;

    public void run() {
        try {
            System.err.println("Starting Recieve Server");
            s2 = new ServerSocket(4441);
            fromclientSocket = s2.accept();
            System.err.println("Started Recieve Server");
        } catch (Exception s2) {
            System.exit(1);
        }

        while (true) {
            try {

                BufferedReader in = new BufferedReader(new InputStreamReader(fromclientSocket.getInputStream()));

                String fromClient = in.readLine();

                if (fromClient.contentEquals("")) {

                } else {                        
                    Toolkit.getDefaultToolkit().beep();
                    chat.append("\n\n " + user2 + " says:\n        " + fromClient);
                    badge++;
                    Application.getApplication().setDockIconBadge(Integer.toString(badge));
                }

            } catch (Exception e) {
                System.err.println("Error Receiving.");
                System.err.println(e.getMessage());
                System.exit(3);
            }
        }
    }
}

class infoFromThread extends Thread {

    ServerSocket s3;
    Socket infoFromClientSocket = null;

    public void run() {
        try {
            s3 = new ServerSocket(4446);
            infoFromClientSocket = s3.accept();
        } catch (Exception s3) {
            System.exit(7);
        }

        while (true) {
            try {

                BufferedReader in = new BufferedReader(new InputStreamReader(infoFromClientSocket.getInputStream()));

                String infoFromClient = in.readLine();

                if (infoFromClient.contentEquals("10")) {
                    accept.setVisible(true);
                    sendinvite = 0;
                } else if (infoFromClient.contentEquals("y")) {
                    chat.append("\n >Invite Accepted");
                    rps = true;
                    rock.setVisible(true);
                    paper.setVisible(true);
                    scissors.setVisible(true);
                    answerinvite = '-';
                } else if (infoFromClient.contentEquals("n")) {
                    chat.append("\n\n >Invite Declined");
                    answerinvite = '-';
                } else if (infoFromClient.contentEquals("1")) {
                    chat.append("\n\n >Opponent made selection");
                    P2pick = 1;
                    if (P1pick != 0) {
                        pt.start();
                    }
                } else if (infoFromClient.contentEquals("2")) {
                    chat.append("\n\n >Opponent made selection");
                    P2pick = 2;
                    if (P1pick != 0) {
                        pt.start();
                    }
                } else if (infoFromClient.contentEquals("3")) {
                    chat.append("\n\n >Opponent made selection");
                    P2pick = 3;
                    if (P1pick != 0) {
                        pt.start();
                    }
                }

            } catch (Exception e) {
                System.err.println("Error Receiving Information.");
                System.err.println(e.getMessage());
                System.exit(3);
            }
        }
    }
}

class infoToThread extends Thread {

    ServerSocket s4;
    Socket infoToClientSocket = null;

    public void run() {
        inputText = input.getText();
        try {
            s4 = new ServerSocket(4447);
            infoToClientSocket = s4.accept();
        } catch (Exception s4) {
            System.exit(8);
        }
        while (true) {
            try {
                PrintWriter out = new PrintWriter(infoToClientSocket.getOutputStream(), true);

                if (sendinvite == 10) {
                    out.println(sendinvite);
                    sendinvite = 0;
                    pauseInfo = false;
                }
                if ((answerinvite == 'y') || (answerinvite == 'n')) {
                    out.println(answerinvite);
                    answerinvite = '-';
                }

                    if (winner == 1) {
                        out.println("Loser");
                    }
                    else if (winner == 2) {
                        out.println("Winner");
                    }
                    else if (winner == 3) {
                        out.println("Tie");
                    }
                    //winner = 0;

                //System.err.println("infoToClient");
            } catch (Exception e) {
                System.err.println("Error Sending Information.");
                System.err.println(e.getMessage());
                System.exit(2);
            }
        }
    }
}
class RPSpickTimer extends Thread {

    public void run() {
        while (true) {
            try {
                if (P1pick != 0) {
                if (P1pick == 1) {
                    if (P2pick == 1) {
                        //tie
                        chat.append("\n\n Tie!");
                        winner = 3;
                    } else if (P2pick == 2) {
                        //P2wins
                        chat.append("\n\n " + user2 + " wins!");
                        winner = 2;
                    } else if (P2pick == 3) {
                        //P1wins
                        chat.append("\n\n " + user + " wins!");
                        winner = 1;
                    }

                } else if (P1pick == 2) {
                    if (P2pick == 1) {
                        //P1wins
                        chat.append("\n\n " + user + " wins!");
                        winner = 1;
                    } else if (P2pick == 2) {
                        //tie
                        chat.append("\n\n Tie!");
                        winner = 3;
                    } else if (P2pick == 3) {
                        //P2wins
                        chat.append("\n\n " + user2 + " wins!");
                        winner = 2;
                    }

                } else if (P1pick == 3) {
                    if (P2pick == 1) {
                        //P2wins
                        chat.append("\n\n " + user2 + " wins!");
                        winner = 2;
                    } else if (P2pick == 2) {
                        //P1wins
                        chat.append("\n\n " + user + " wins!");
                        winner = 1;
                    } else if (P2pick == 3) {
                        //tie
                        chat.append("\n\n Tie!");
                        winner = 3;
                    }
                }
                P1pick = 0;
                P2pick = 0;
            }
            else {
                sleep(250);
            }  

            } catch (Exception e) {
                System.err.println("Error Picking Winner.");
                System.err.println(e.getMessage());
                System.exit(2);
            }
        }
    }
}

public static void main(String[] args) {
    GUIserver s = new GUIserver();

}`
3

There are 3 answers

1
Nico On BEST ANSWER

This line:

panel.add(chat);

Instead of adding chat, add pane, like:

panel.add(pane);
1
CrazyCasta On

From JTextArea docs "The java.awt.TextArea internally handles scrolling. JTextArea is different in that it doesn't manage scrolling, but implements the swing Scrollable interface. This allows it to be placed inside a JScrollPane if scrolling behavior is desired, and used directly if scrolling is not desired."

I think that means that this is what you want:

JTextArea chat = new JTextArea(" Waiting to Start Client...");
JScrollPane chatScrollPane = new JScrollPane(chat);

...

panel.setLocation(300, 0);
panel.add(chatScrollPane);
panel.add(input);

As Nicolás Carlo pointed out, you already have the JScrollPane and just need to add it instead of the JTextArea. Basically the Java UI system (and most UI systems) are a giant tree of widgets. If you don't add a widget to the tree it doesn't have an effect. In this case, the JScrollPane wasn't getting added to the tree and therefore wasn't doing anything for you.

3
MadProgrammer On

This is not an answer, but a demonstration of how a LayoutManager might be used to achieve the OP's results

So, based on your code example, I get this output...

BadLayout

I hope you note that the frame isn't big enough to hold the content, this is the major problem with null layouts, they never look the same on other systems...

And by utilising a GridBagLayout and a GridLayout and a concept known as "compound layouts", I was able to mock this...

BetterLayout

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ChatLayout {

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

    public ChatLayout() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new ChatPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class ChatPane extends JPanel {

        private JTextArea chatWindow;
        private JTextField input;
        private JLabel ipLabel;

        private JButton rockBtn;
        private JButton paperBtn;
        private JButton scissorsBtn;
        private JButton startBtn;

        public ChatPane() {

            JPanel leftPane = new JPanel(new GridBagLayout());
            JPanel rightPane = new JPanel(new GridBagLayout());

            chatWindow = new JTextArea(20, 40);
            chatWindow.setText("Waiting to start chat...");

            input = new JTextField(10);
            ipLabel = new JLabel("IP...");

            rockBtn = new JButton("Rock");
            paperBtn = new JButton("Paper");
            scissorsBtn = new JButton("Scissors");
            startBtn = new JButton("Start");

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.insets = new Insets(4, 4, 4, 4);
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.fill = GridBagConstraints.BOTH;
            gbc.weighty = 1;
            gbc.weightx = 1;
            leftPane.add(new JScrollPane(chatWindow), gbc);

            gbc.gridy++;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.weighty = 0;
            gbc.weightx = 1;
            gbc.gridheight = 1;
            leftPane.add(input, gbc);

            gbc.gridy++;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            leftPane.add(ipLabel, gbc);

            JPanel buttonsPane = new JPanel(new GridLayout(3, 1));
            buttonsPane.add(rockBtn);
            buttonsPane.add(paperBtn);
            buttonsPane.add(scissorsBtn);

            gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.anchor = GridBagConstraints.SOUTH;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.weighty = 1;            
            rightPane.add(buttonsPane, gbc);

            gbc.gridy++;
            gbc.insets = new Insets(8, 0, 0, 0);
            gbc.fill = GridBagConstraints.BOTH;
            gbc.anchor = GridBagConstraints.CENTER;
            gbc.weighty = 0;
            gbc.gridheight = 2;
            gbc.ipadx = 30;
            gbc.ipady = 30;
            rightPane.add(startBtn, gbc);

            gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.weightx = 1;
            gbc.weighty = 1;
            gbc.fill = GridBagConstraints.BOTH;
            add(leftPane, gbc);

            gbc.gridx++;
            gbc.weightx = 0;
            gbc.weighty = 1;
            add(rightPane, gbc);
        }

    }

}

Now, this is just an example. You needs might be different which would require using different layout managers or using them in different combinations...