Java – JScrollPane resizes with variable size content

The contents of my resizable JScrollPane have a minimum width If the JScrollPane is less than this width, a horizontal scroll bar should be displayed If it is greater than this width, the viewport contents should be expanded to fill the entire viewport

It looks like a simple concept. I have some work, but it feels like a hacker:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

public class SSBTest {
    public static void main(String[] args) {
        SwingUtilities.invokelater(new Runnable() {
            public void run() {
                final Component view = new MyView();
                final JScrollPane jScrollPane = new JScrollPane(view);
                jScrollPane.addComponentListener(new ComponentAdapter() {
                    @Override
                    public void componentResized(final ComponentEvent e) {
                        final Dimension minimumSize = view.getMinimumSize();
                        final int width = Math.max(minimumSize.width,jScrollPane.getViewport().getWidth());
                        view.setPreferredSize(new Dimension(width,minimumSize.height));
                    }
                });
                showInDialog(jScrollPane);
            }
        });
    }

    private static void showInDialog(final JScrollPane jScrollPane) {
        final JDialog dialog = new JOptionPane(jScrollPane).createDialog("JScrollPane Resize Test");
        dialog.setResizable(true);
        dialog.setModal(true);
        dialog.setVisible(true);
        Sy@R_502_2354@.exit(0);
    }

    private static final class MyView extends JPanel {
        @Override
        protected void paintComponent(final Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.RED);
            g.drawString("Dimensions are " + getSize(),10,20);
            g.drawRect(0,getMinimumSize().width-1,getMinimumSize().height-1);
            g.setColor(Color.BLUE);
            g.drawRect(0,getPreferredSize().width-1,getPreferredSize().height-1);
        }

        @Override
        public Dimension getMinimumSize() {
            return new Dimension(200,200);
        }

        @Override
        public Dimension getPreferredSize() {
            return super.getPreferredSize();
        }
    }
}

Resizing the dialog box triggers componentlistener, which explicitly sets the preferred size of the viewport view and triggers component validation However, resizing causes the scroll bar to shake Is there a cleaner way to do this?

Editor: thanks to camickr's scrollablepanel link, I modified my JPanel class to implement scrollable and dynamically changed the return value of getscrollabletracksviewportwidth()

When the viewport is large, I return true to getscrollabletracksviewportwidth(), telling JScrollPane to fill the view with my components When the viewport is small, I return false, so the scroll bar appears

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

public class SSBTest {
    public static void main(String[] args) {
        SwingUtilities.invokelater(new Runnable() {
            public void run() {
                final Component view = new MyView();
                final JScrollPane jScrollPane = new JScrollPane(view);
                showInDialog(jScrollPane);
            }
        });
    }

    private static void showInDialog(final JScrollPane jScrollPane) {
        final JDialog dialog = new JOptionPane(jScrollPane).createDialog("JScrollPane Resize Test");
        dialog.setResizable(true);
        dialog.setModal(true);
        dialog.setVisible(true);
        Sy@R_502_2354@.exit(0);
    }

    private static final class MyView extends JPanel implements Scrollable {
        @Override
        protected void paintComponent(final Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.RED);
            g.drawString("MyView: " + getWidth() + "x" + getHeight(),getPreferredSize().height-1);
            g.drawString("Preferred/Minimum Size",getPreferredSize().height/2);
            g.setColor(Color.GREEN);
            g.drawLine(0,getWidth(),getHeight());
        }

        @Override
        public Dimension getMinimumSize() {
            return new Dimension(200,200);
        }

        @Override
        public Dimension getPreferredSize() {
            return getMinimumSize();
        }

        public Dimension getPreferredScrollableViewportSize() {
            return getPreferredSize();
        }

        public int getScrollableUnitIncrement(final Rectangle visibleRect,final int orientation,final int direction) {
            return 10;
        }

        public int getScrollableBlockIncrement(final Rectangle visibleRect,final int direction) {
            return visibleRect.width;
        }

        public boolean getScrollableTracksViewportWidth() {
            final Container viewport = getParent();
            return viewport.getWidth() > getMinimumSize().width;
        }

        public boolean getScrollableTracksViewportHeight() {
            return true;
        }

    }
}

Solution

Not sure, but you may be able to use scrollable panel You can configure component resizing (try using stretch) The code applies to the preferred size of the component, not the minimum size, so it may not fully meet your requirements

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>