-2

I want to add JPanel containers to a JScrollPane and add this scroll pane to a JFrame. But when I add multiple panels to the scroll pane this happens. The gap between the scroll pane and the top bar increases. I use BoxLayout as layout manager for all the components that I use.

  • I couldn't send the photo, because I don't have enough contribution points. – anonymJava123 Jan 30 '22 at 17:34
  • Welcome to Stack Overflow. Please take the [tour] to learn how Stack Overflow works and read [ask] on how to improve the quality of your question. Then [edit] your question to include your source code as a working [mcve], which can be compiled and tested by others. – Progman Jan 30 '22 at 17:45
  • 1
    You shouldn't use `null` as the layout manager, see other questions like https://stackoverflow.com/questions/33249871/java-setting-layout-to-null or https://stackoverflow.com/questions/6592468/why-is-it-frowned-upon-to-use-a-null-layout-in-swing – Progman Jan 30 '22 at 17:46
  • I want to have an Jlabel at the left top and two buttons next to each other at the right top end (there will be an distance between the label and the buttons) , which layout manager should I use and how can I do it ? – anonymJava123 Jan 30 '22 at 18:00
  • 2
    You can check https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html for some of the layout managers you can choose from. You can combine layout managers when necessary by using different layout managers for different containers like `JPanel`. – Progman Jan 30 '22 at 18:04
  • https://mail.google.com/mail/u/0?ui=2&ik=e866cadb3a&attid=0.1&permmsgid=msg-a:r4968109999094271281&th=17eac3635efed057&view=att&disp=safe&realattid=f_kz1l76mi0 What I want to do is here, when I add multiple Jpanels to the JscrollBar both scrollBars in horizontal and vertical should appear. I hope you can see the picture, an answer with code will be really helpful, thanks . – anonymJava123 Jan 30 '22 at 18:23
  • I am really sorry, can you see this one https://ibb.co/Vpzh2sh ? – anonymJava123 Jan 30 '22 at 18:42
  • 1
    Please no links. Instead, improve the question by showing your [mre] code. – DontKnowMuchBut Getting Better Jan 30 '22 at 19:20
  • BTW @DontKnowMuchButGettingBetter Normally I am a stickler for people posting an MRE, but in this case, where the OP has no idea how to use layouts to create the effect, I don't feel that it is very useful. If you see my point, I'm hoping you will add a vote to reopen. – Andrew Thompson Jan 30 '22 at 22:16
  • 1
  • Labels and buttons are inside the Jpanel and this Jpanel is at the top of the frame. JscrollPane is in the center of the frame. I also have problems setting the coordinates of the label and the buttons in a Jpanel like in the picture. The green ones in the Jscrollpane are Jpanels. And when the panels are not displayable in the view the scrollbar's should be created. Thanks for opening the question again. – anonymJava123 Jan 31 '22 at 06:14
  • Is there an other way to answer the question, like writing it as multiple comments ? It would be really helpful. Currently I solved my problems with the topBar but when I want to add an Jpanel to the main Jpanel in JscrollPane , there are two buttons displayed next to each other rather than one . I have used BoxLayout for the Jpanel in JscrollPane. – anonymJava123 Jan 31 '22 at 16:04
  • I have added my code. This unwanted buttons appear directly at the left side of the buttons that I want to create. They appear, when I scroll them with the mouse. I use BorderLayout as default for the frame. – anonymJava123 Jan 31 '22 at 16:29
  • I changed it again it works as expected, when I test this only. But I use this JScrollPane with an CardLayoutManager, to change the Center of the frame with buttons. Can this result to an unexpected outlook, when I use a GroupLayout for an Jpanel that was in the Center before ? So when I try to switch the center of the frame from an Jpanel to the JscrollPane ? – anonymJava123 Jan 31 '22 at 16:59
  • There are couple of classes in the package for this desired output and a main to test it. If you want I can send it to you privately with an mail ? – anonymJava123 Jan 31 '22 at 17:06

1 Answers1

1

enter image description here

Here is my take on laying out this GUI. Some notes:

  • Rather than use a BoxLayout in the JScrollPane it puts a GridLayout in the PAGE_START of a BorderLayout. This is fine for when it's OK to stretch the elements in the scroll pane to the full width of the GUI. Stick to a BoxLayout (which I rarely use) or a GridBagLayout if it's necessary to keep the elements at their preferred size.
  • This strategy of layout is basically 'divide and conquer' in that it starts with the smallest sub-divisions of the GUI (e.g. the FlowLayout for the buttons) and then adds those containers to larger containers with different layouts and constraints (e.g. adding that button panel to the LINE_END of a BorderLayout - to push I to the right of the GUI) as needed for the overall effect.
  • I'd also consider using a JList (using a panel for the renderer) in the scroll pane. It depends on the use as to whether that makes sense.
  • Note that this code is an MRE. An MRE should have everything that's needed (including imports, a class structure and the main method) for another person to compile and run the code.

import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.ActionEvent;

// ref: https://stackoverflow.com/a/70934802/418556
public class ScrollPaneTestGUI {

    int elementCount = 1;
    JPanel elementsPanel = new JPanel(new GridLayout(0,1,2,2));

    public ScrollPaneTestGUI() {
        initGUI();
    }

    private void initGUI() {
        // this will become the content pane of the frame
        JPanel gui = new JPanel(new BorderLayout(4,4));
        gui.setBorder(new EmptyBorder(4,4,4,4));

        JPanel pageStartPanel = new JPanel(new BorderLayout(2,2));
        gui.add(pageStartPanel, BorderLayout.PAGE_START);
        pageStartPanel.add(new JLabel("LINE START label"), BorderLayout.LINE_START);
        // default flow layout is good for this one
        JPanel buttonPanel = new JPanel();
        pageStartPanel.add(buttonPanel, BorderLayout.LINE_END);
        buttonPanel.add(new JButton("Does Nothing"));
        Action addToScrollAction = new AbstractAction("Add to scrollPane") {
            @Override
            public void actionPerformed(ActionEvent e) {
                elementsPanel.add(getPanelForScroll());
                elementsPanel.revalidate();
            }
        };
        JButton addToScrollButton = new JButton(addToScrollAction);
        buttonPanel.add(addToScrollButton);

        JPanel scrollPanel = new JPanel(new BorderLayout());
        scrollPanel.add(elementsPanel, BorderLayout.PAGE_START);
        gui.add(new JScrollPane(scrollPanel,
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)
        );
        for (int ii=0; ii<2; ii++) {
            elementsPanel.add(getPanelForScroll());
        }

        JFrame frame = new JFrame("ScrollPane GUI");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setContentPane(gui);
        frame.pack(); // sets the GUI to the exact size needed
        frame.setMinimumSize(frame.getSize());
        frame.setVisible(true);
    }

    private JPanel getPanelForScroll() {
        JPanel p = new JPanel();
        p.add(new JLabel("Panel " + elementCount++));
        p.setBorder(new EmptyBorder(10,200,10,200));
        p.setBackground(Color.GREEN);
        return p;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                new ScrollPaneTestGUI();
            }
        };
        SwingUtilities.invokeLater(r);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433