Изменение размера JScrollpane с содержимым переменного размера - PullRequest
12 голосов
/ 10 февраля 2011

Содержимое моего изменяемого размера JScrollPane имеет минимальную ширину.Если JScrollPane меньше этой ширины, должны появиться горизонтальные полосы прокрутки.Если эта ширина больше этой ширины, содержимое области просмотра должно расширяться, чтобы заполнить всю область просмотра.

Похоже на простую концепцию, и у меня есть кое-что, что работает, но похоже на хак:

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);
        System.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, 0, getMinimumSize().width-1, getMinimumSize().height-1);
            g.setColor(Color.BLUE);
            g.drawRect(0, 0, getPreferredSize().width-1, getPreferredSize().height-1);
        }

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

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

Изменение размера диалогового окна вызывает ComponentListener, который явно устанавливает предпочтительный размер представления области просмотра, вызывая проверку компонента.Однако изменение размера вызывает дрожание полос прокрутки.Есть ли более чистый способ сделать это?

РЕДАКТИРОВАТЬ: благодаря camickr для ссылки ScrollablePanel, я изменил свой класс JPanel для реализации Scrollable и динамически изменить возвращаемое значение для getScrollableTracksViewportWidth().

Когда область просмотра велика, я возвращаю true для getScrollableTracksViewportWidth(), сообщая JScrollPane заполнить представление моим компонентом.Когда область просмотра мала, я возвращаю false, поэтому появляются полосы прокрутки.

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);
        System.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(), 10, 20);
            g.drawRect(0, 0, getMinimumSize().width-1, getMinimumSize().height-1);
            g.setColor(Color.BLUE);
            g.drawRect(0, 0, getPreferredSize().width-1, getPreferredSize().height-1);
            g.drawString("Preferred/Minimum Size", 10, getPreferredSize().height/2);
            g.setColor(Color.GREEN);
            g.drawLine(0, 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 orientation, final int direction) {
            return visibleRect.width;
        }

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

        public boolean getScrollableTracksViewportHeight() {
            return true;
        }

    }
}

1 Ответ

7 голосов
/ 10 февраля 2011

Не уверен, но вы можете использовать прокручиваемую панель .Вы можете настроить изменение размера компонента (попробуйте использовать STRETCH).Код работает с предпочтительным размером компонента, а не с минимальным, поэтому он может быть не совсем тем, что вы хотите.

...