Search code examples
javaswingjscrollpanejdesktoppane

JDesktopPane inside JScrollPane resize issue


I have a JDesktopPane inside a JScrollPane. Inside the JDesktopPane there are many JInternalFrames, added programmatically. I would like to have this behavior:

  • the JDesktopPane should have a fixed size (much larger than the main JFrame size)

  • the JScrollPane size should vary accordingly to the main JFrame when resized

Basically the same behavior that every image editor has (i.e. Photoshop), but with JInternalFrames in the viewport instead of an image.

At first I thought this behavior would be easy to get, but I can't get it quite right. Surely I'm missing something about layouts or something related...

Here's the related SSCCE

import javax.swing.*;
import java.awt.Dimension;
import java.awt.Rectangle;

class Main extends JFrame {

    JDesktopPane container = new JDesktopPane();

    // New frame with 2 JInternalFrames inside a JDesktopPane inside a JScrollPane
    Main(){
        super("JDesktopPane SS");
        setSize(1280, 720);

        setLayout(new ScrollPaneLayout());

        container.setBounds(new Rectangle(1920, 1080));

        JScrollPane scrollContainer = new JScrollPane(container, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        setContentPane(scrollContainer);

        container.add(createFrame());
        container.add(createFrame());
    }

    public static void main(String[] args){
        SwingUtilities.invokeLater(() -> {
            // Create new frame with 2 JInternalFrames inside a JDesktopPane inside a JScrollPane
            JFrame main_frame = new Main();

            main_frame.setVisible(true);
        });
    }

    // Create new InternalFrame with a TextPane
    private JInternalFrame createFrame(){
        JInternalFrame new_frame = new JInternalFrame("Document");
        new_frame.setResizable(true);

        JTextPane txt = new JTextPane();
        txt.setPreferredSize(new Dimension(100, 80));
        new_frame.add(txt);

        new_frame.pack();
        new_frame.setVisible(true);

        return new_frame;
    }
}

Solution

  • JScrollPane viewports don't respect size or bounds but rather preferred sizes. So

    class Main extends JFrame {
    
        private static final int DT_WIDTH = 1920;
        private static final int DT_HEIGHT = 1080;
        private JDesktopPane container = new JDesktopPane();
    
        public Main(){
            super("JDesktopPane SS");
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setSize(1280, 720);
    
            // setLayout(new ScrollPaneLayout()); // ?????
    
            // container.setBounds(new Rectangle(1920, 1080));
            container.setPreferredSize(new Dimension(DT_WIDTH, DT_HEIGHT));