0
votes

I have a JScrollPane with a JPanel in it that works perfectly, except for one flaw. When I run the program, the JScrollPane is added and shows up on its parent panel just fine, however the content inside it does not show up.

If I resize the window or if I scroll on the JPanel the content shows up immediately. I have also checked and the dimensions are correct for both the JPanel and the JScrollPane. Repaint is also called so I don't think I'm missing anything there.

I did also look at this question but it didn't help: JScrollPane doesn't show scroll bars when JPanel is added

Null layouts being used are intentionally, I'm doing my own formatting instead to account for multiple size screens. Thank you ahead of time!

class FilesPanel extends JPanel
{
    public JScrollPane scroller;
    private FileHolderPanel holder;

    public FilesPanel()
    {
        //setLayout(null);
        setBackground(extraLight);

        holder = new FileHolderPanel();

        System.out.println(holder.getWidth() + " " + holder.getHeight() + " " + holder.getX() + " " + holder.getY() + " " + holder.getBounds());

        scroller = new JScrollPane();

        JViewport viewport = new JViewport();
        viewport.add(holder);
        scroller.setViewport(viewport);

        scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

        scroller.setBorder(BorderFactory.createEmptyBorder());
        scroller.setBackground(blue);
        add(scroller);
    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        scroller.setLocation(0, 0);
        scroller.setSize(filesWidth, frame.getHeight() - 40);
    }

    class FileHolderPanel extends JPanel
    {
        public FileHolderPanel()
        {
            setBackground(extraLight);
            setLayout(null);
            setVisible(true);
        }

        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
        }
    }
}
1
Take the code out of paintComponent, this is NOT how custom painting should be used, nor is it a good idea. The "main" problem, as near as I can tell is failure of the FileHolderPanel to provide appropriate sizing hints for the JScrollPane to use - MadProgrammer
viewport.add(holder); is also not required - MadProgrammer
Doing your own layout is much more involved than what you are doing. Layouts really do make things easier. - NomadMaker
Added the full code folder here: drive.google.com/drive/folders/… The class is called FilePanel - Brad Kyle
Hi Brad Kyle. On Stack Overflow, you are expected to include a minimal reproducible example to your question. You cannot expect people to go look for resources elsewhere to solve your question. Not just that, Stack Overflow is a repository of questions and answers that are supposed to help anyone facing a similar problem. Once you remove the code from your Google drive, your question would become useless. - TT.

1 Answers

2
votes

The "main" issue is the fact that FileHolderPanel has not concept of the size it might like to be, so the JScrollPane has no really of how large it needs to be or when it should display its scroll bars. This is a bit of guess work, as you've not provided a fully runnable example.

Something like the below example works fine...

Example

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class Test {

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

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

    public class ContentPane extends JPanel {

        public ContentPane() {
            setLayout(new BorderLayout());
            JScrollPane scrollPane = new JScrollPane(new FileHolderPane());
            scrollPane.setBorder(BorderFactory.createEmptyBorder());
            scrollPane.setBackground(Color.BLUE);
            add(scrollPane);
        }

    }

    public class FileHolderPane extends JPanel {

        public FileHolderPane() {
            setBackground(Color.RED);
            setLayout(new GridBagLayout());
            add(new JLabel("All your content is belong to us"));
        }

        @Override
        public Dimension getPreferredSize() {
            // This will make the panel a fixed size, so beware of that
            return new Dimension(400, 400);
        }

    }
}

If you need more control, then you'll probably need to look at the Scrollable interface, but that's another level of complexity