-2

Here's the code I have for my GUI

public class gui extends JFrame{

JFrame mainF;
JPanel listPanel;
JTextArea jtArea;
ButtonGroup buttons;
ButtonGroup restoreButtons;
JRadioButton createButton;
JRadioButton saveButton;
JRadioButton deleteButton;
JRadioButton redo;
JRadioButton undo;

gui() {

    this.mainF = new JFrame();
    mainF.getContentPane().setBackground(Color.gray);
    mainF.setLayout(null); 
    mainF.setSize(800, 800);

    createButton = new JRadioButton("Create note");
    createButton.setBounds(10, 150, 150, 50);

    saveButton = new JRadioButton("Save note");
    saveButton.setBounds(10, 250, 150, 50);
    saveButton.setEnabled(false);




    redo = new JRadioButton("Redo");
    redo.setBounds(10, 400, 150, 50);
    redo.setEnabled(false);

    undo = new JRadioButton("Undo");
    undo.setBounds(10, 350, 150, 50);
    undo.setEnabled(false);

    deleteButton = new JRadioButton("Delete note");
    deleteButton.setBounds(10, 500, 150, 50);
    deleteButton.setEnabled(false);

    this.jtArea = new JTextArea();
    int centerX = (mainF.getWidth() - 200) / 2;
    int centerY = (mainF.getHeight() - 500) / 2;
    jtArea.setBounds(centerX, centerY, 200, 500);
    jtArea.setBackground(Color.white);
    jtArea.setEnabled(false);

    JScrollPane scrollPane = new JScrollPane(jtArea);
    scrollPane.setBounds(centerX, centerY, 200, 500); 
    jtArea.setLineWrap(true); 
    jtArea.setWrapStyleWord(true); 
    jtArea.setEnabled(false);


    this.listPanel = new JPanel(new GridLayout(0, 1));
    JScrollPane listScrollPane = new JScrollPane(listPanel);
    listScrollPane.setBounds(centerX + 285, centerY, 200, 500);
    listScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

    
    buttons = new ButtonGroup();
    buttons.add(createButton);
    buttons.add(saveButton);
    buttons.add(deleteButton);
    buttons.add(undo);
    buttons.add(redo);


    mainF.add(jtArea);
    mainF.add(createButton);
    mainF.add(saveButton);
    mainF.add(deleteButton);
    mainF.add(redo);
    mainF.add(undo);
    mainF.add(listScrollPane);
    mainF.setVisible(true); 
    mainF.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

I'm still unfamiliar with GUI components so this is very new to me. It shows a scroll bar on the right side, but I can't scroll through it when it's full. My entire code is supposed to add buttons to that listPanel and if it gets full then I can scroll through them but that doesn't seem to be the case.

12
  • 3
    mainF.setLayout(null); is a bad idea - Laying Out Components Within a Container Commented Dec 9, 2023 at 23:05
  • 1
    jtArea.setBounds(centerX, centerY, 200, 500); this isn't helping you either. You're fixing the size of the JTextArea so that it cannot expand if need be. Commented Dec 9, 2023 at 23:06
  • 1
    do you mean scrolling of listPanel? In posted code, it is empty, so there is nothing to scroll! You posted a lot of (irrelevant?) code but somehow the post is missing almost all code regarding listPanel (assuming that is the one not scorlling) - if I add enough buttons to it, I can scroll normally.
    – user85421
    Commented Dec 9, 2023 at 23:27
  • 4
    1) There is absolutely no reason to manually set the location of components. Swing was designed be used with layout managers. In fact, scrolling won't work when you use a null layout. 2) See: user85421's comment about not having any components on the panel. If there are no components there is not reason to scroll. 3) Swing components can only have a single parent. Your text area won't scroll either. First you add the text area to a scroll pane. But then you remove the text area from the scroll pane when you add it to the frame. You need to add the scroll pane to the frame, not the text area.
    – camickr
    Commented Dec 9, 2023 at 23:38
  • 2
    “…but I want to be able to manually set the location of all my components.” How many pixels do you think your JRadioButton’s font will need on other computers? Characters in a “12 point” font are not 12 pixels high; they are ¹²⁄₇₂ inch high, and the number of pixels needed depends on the dot pitch of the monitor. And you can’t even be certain other users will have the same system font at all. If all this sounds complicated… well, that’s why you need to let Swing components compute their own preferred sizes, and you need to use a layout manager so those sizes are respected.
    – VGR
    Commented Dec 9, 2023 at 23:44

1 Answer 1

1

mainF.setLayout(null); is your first mistake.

public class gui extends JFrame {
    JFrame mainF;

is your second. Which JFrame are you actually using?! As a general rule avoid extending from top level containers like JFrame, you're not adding any additional functionally to the class and JFrame is a complex compound component, best to just avoid it.

JScrollPane scrollPane = new JScrollPane(jtArea);
//...
mainF.add(jtArea);

is your third mistake (credit to camickr) - you're applying the JTextArea to the JScrollPane, which is correct, but then adding the JTextArea to the JFrame, which will first remove it from the JScrollPane ... and now the JScrollPane isn't even been displayed. You should be adding the scrollPane to the frame, not the JTextArea.

Remember, you're not stuck to using a single layout manager, you can make use of multiple layout managers through a process of "compound layouts", for example...

enter image description here

Please note - the above screen shot shows preloaded text, which is not present in the example code

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;

public class Main {

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

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new GUI());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class GUI extends JPanel {

        private JTextArea jtArea;
        private ButtonGroup buttons;
        private JRadioButton createButton;
        private JRadioButton saveButton;
        private JRadioButton deleteButton;
        private JRadioButton redo;
        private JRadioButton undo;
        private JPanel listPanel;

        GUI() {
            setBorder(new EmptyBorder(8, 8, 8, 8));
            JPanel actionsPane = new JPanel(new GridLayout(0, 1));

            // Not sure why you'd use radio buttons for this, but your problem
            createButton = new JRadioButton("Create note");

            saveButton = new JRadioButton("Save note");
            saveButton.setEnabled(false);

            redo = new JRadioButton("Redo");
            redo.setEnabled(false);

            undo = new JRadioButton("Undo");
            undo.setEnabled(false);

            deleteButton = new JRadioButton("Delete note");
            deleteButton.setEnabled(false);

            buttons = new ButtonGroup();
            buttons.add(createButton);
            buttons.add(saveButton);
            buttons.add(deleteButton);
            buttons.add(undo);
            buttons.add(redo);

            actionsPane.add(createButton);
            actionsPane.add(saveButton);
            actionsPane.add(redo);
            actionsPane.add(undo);
            actionsPane.add(deleteButton);

            this.jtArea = new JTextArea();
            // This provides a sizing hint for how wide the text area should be
            jtArea.setColumns(80);

            jtArea.setLineWrap(true);
            jtArea.setWrapStyleWord(true);
            //jtArea.setEnabled(false);

            // Just as a FYI, I'd probably consider using a JList for this
            this.listPanel = new JPanel(new GridLayout(0, 1));
            for (int index = 0; index < 100; index++) {
                listPanel.add(new JLabel("Note " + (index + 1)));
            }

            JScrollPane scrollPane = new JScrollPane(jtArea);
            JScrollPane listScrollPane = new JScrollPane(listPanel);

            setLayout(new GridBagLayout());

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.insets = new Insets(4, 4, 4, 4);
            gbc.anchor = GridBagConstraints.NORTH;

            add(actionsPane, gbc);

            gbc.gridx = 1;
            gbc.weightx = 0.5;
            gbc.weighty = 1;
            gbc.fill = GridBagConstraints.BOTH;

            add(scrollPane, gbc);
            gbc.gridx = 2;
            // If there is nothing in the listPanel, this will collapse to a 
            // 0 width, which is why I'd recommend using JList instead
            add(listScrollPane, gbc);
        }
    }
}

I would recommend taking a look at: