JScrollPanel не показывает прокрутку

У меня есть JFrame с размером 500 X 500: он содержит JComponent с размером 1000 X 1000 и этот JComponent содержится в JScrollBar с всегда присутствующей полосой прокрутки. Скриншот введите здесь описание изображения

Код

    /**component */
    public class LinesComponent extends JPanel 

    ....

    /***other class: CommandPanel contains the LinesComponents*/
    public class CommandPanel extends JPanel{
    ....

        private LinesComponent panel;

            /*JScrollPanel*/

            private void buildScrollPanel(Container container) {
                JScrollPane scroll = new JScrollPane(panel);
                scroll.setSize(1000,1000);
                scroll.setBorder(new LineBorder(Color.BLACK));
                scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
                scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
                container.add(scroll);
            }

        /**JFrame*/
            private void buildFrame(String title) {
                this.testFrame = new JFrame(title);
                this.testFrame.setLayout(new FlowLayout());
                this.testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                this.testFrame.setLocationRelativeTo(null);
                this.testFrame.setSize(500,500);
                this.testFrame.setBackground(EnumColor.BACKGROUND_PANEL.getValue());
            }

//end CommandPanel

Как показано на скриншоте, в окне есть полоса прокрутки, но она не работает.

Я попытался изменить размеры JPanel и JFrame, но ситуация не изменилась.

Я знаю, что прокрутка появляется, когда размер JComponent больше размера контейнера JPanel, но в этот момент я вижу, что теряю некоторую информацию, но я не понимаю что.

У вас есть предложения, пожалуйста?

PS на скриншоте я показываю, что прокрутка не работает, но в моем desiderata прокрутка должна работать в вертикальном и горизонтальном направлениях

PS PS весь мой код только в одном классе

package testDebug;

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.LayoutManager;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.LineBorder;

public class AllClasses {

    public static void main(String[] a){
        CommandPanel commandPanel=new CommandPanel("test", new ArrayList<MyPoint>());
    }
}



class LinesComponent extends JPanel{


    private static final long serialVersionUID = 1L;
    private final LinkedList<Line> lines = new LinkedList<Line>();


    private static class Line {
        final int x1;//x del primo punto
        final int y1;//y del primo punto
        final int x2;//x del secondo punto
        final int y2;//y del secondo punto
        final Color color;
        final int pressure;

        public Line(int x1, int y1, int x2, int y2, Color color) {
            this.x1 = x1;
            this.y1 = y1;
            this.x2 = x2;
            this.y2 = y2;
            this.color = color;
            this.pressure=3;
        }

        public Line(int x1, int y1, int x2, int y2, int newPressure, Color color) {
            this.x1 = x1;
            this.y1 = y1;
            this.x2 = x2;
            this.y2 = y2;
            this.pressure=newPressure;
            this.color = color;
        }
    }//Line

    public LinesComponent(){
        setBorder(new LineBorder(Color.BLACK));
        setBackground(Color.WHITE);
        setPreferredSize(new Dimension(400, 400));
    }



    public void clearLines() {
        this.lines.clear();
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (Line line : this.lines) {
            g.setColor(line.color);
            g.fillOval(line.x1,line.y1, line.pressure, line.pressure);
        }
    }
    public void addPoint(MyPoint p, Color randomColor) {
        //call addLine(double x, double y, double xtilt, double ytilt,  Color randomColor);
    }

    private void addLine(double x, double y, double xtilt, double ytilt,    Color randomColor) {
        this.lines.add(new Line((int) x, (int) y, (int) xtilt, (int) ytilt, randomColor));
        repaint();
    }

    }
enum EnumButton {

    DECREASE_X("-"),
    INCREASE_X("+"),
    DECREASE_Y("-"),
    INCREASE_Y("+"),
    DECREASE_ZOOM("-"),
    INCREASE_ZOOM("+");


    private JButton button;

    public JButton button(){
        return this.button;
    }

    private EnumButton(String s){
        this.button=new JButton(s);
    }

    public void addActionListener(ActionListener a){
        this.button().addActionListener(a);
    }
}

class CommandPanel extends JPanel {

    private static final long serialVersionUID = 1L;

    private static final String INITIAL_POSITION="0";
    private JFrame testFrame = null;
    private LinesComponent panelSignature;
    private JTextField positionX=new JTextField(5);
    private JTextField positionY=new JTextField(5);




    public CommandPanel(String title, List<MyPoint> newPoints) {
        super();
        positionX.setText(INITIAL_POSITION);
        positionY.setText(INITIAL_POSITION);
        buildFrame(title);
        Container container = testFrame.getContentPane();
        this.panelSignature=initPanel();

        buildScrollPanel(container);
        paintLine(newPoints);

        allignButtons();
        defineFrame();
    }

    private void buildScrollPanel(Container container) {
        JScrollPane scroll = new JScrollPane(panelSignature);
        scroll.setSize(300,300);
        scroll.setBorder(new LineBorder(Color.BLACK));
        scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
        scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        container.add(scroll);
    }

    private void defineFrame() {
        this.testFrame.pack();
        this.testFrame.setVisible(true);
    }

    private void paintLine(List<MyPoint> points) {
        Iterator<MyPoint> iterator = points.iterator();
        while (iterator.hasNext()) {
            MyPoint point = iterator.next();
            this.panelSignature.addPoint(point,Color.BLUE);
        }
    }//disegnaLinea


    private void allignButtons() {
        JPanel buttonPanel = new JPanel(new FlowLayout());
        sectionHorizontalMovement(buttonPanel);
        sectionVerticalMovement(buttonPanel);
        sectionZoom(buttonPanel);
        this.testFrame.add(buttonPanel);
    }

    private void sectionZoom(JPanel buttonPanel) {
        buttonPanel.add(EnumLabel.ZOOM.label());
        buttonPanel.add(EnumButton.INCREASE_ZOOM.button());
        buttonPanel.add(EnumButton.DECREASE_ZOOM.button());
        buttonPanel.add(EnumLabel.ZOOM_DIRECTION.label());
        buttonPanel.add(EnumLabel.EMPTY.label());

    }//sezioneZoom

    private void sectionVerticalMovement(JPanel pannelloPulsanti) {
        pannelloPulsanti.add(EnumLabel.MOVE_UP_DOWN.label());
        pannelloPulsanti.add(EnumButton.INCREASE_Y.button());
        pannelloPulsanti.add(EnumButton.DECREASE_Y.button());
        pannelloPulsanti.add(EnumLabel.Y_DIRECTION.label());
        pannelloPulsanti.add(EnumLabel.MAX_Y_ALLOWED.label());
    }//sezioneSpostamentoVerticale

    private void sectionHorizontalMovement(JPanel pannelloPulsanti) {
        pannelloPulsanti.add(EnumLabel.MOVE_RIGHT_LEFT.label());
        pannelloPulsanti.add(EnumButton.INCREASE_X.button());
        pannelloPulsanti.add(EnumButton.DECREASE_X.button());
        pannelloPulsanti.add(EnumLabel.X_DIRECTION.label());
        pannelloPulsanti.add(EnumLabel.MAX_X_ALLOWED.label());
    }//sezioneSpostamentoOrizzontale

    public LinesComponent initPanel() {
        LinesComponent linesComponent= new LinesComponent();
        linesComponent.setBorder(new LineBorder(Color.GRAY));
        return linesComponent;
    }

    private void buildFrame(String titolo) {
        this.testFrame = new JFrame(titolo);
        this.testFrame.setLayout(new FlowLayout());
        this.testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.testFrame.setLocationRelativeTo(null);
        this.testFrame.setSize(700,700);
        this.testFrame.setBackground(Color.WHITE);
    }
}
enum EnumLayout {

    FRAME(new FlowLayout()), BUTTON_PANEL(new GridLayout(3, 5));

    private LayoutManager value;

    private EnumLayout(LayoutManager manager){
        this.value=manager;
    }

    public LayoutManager layout() {
        return value;
    }

}

enum EnumLabel {
    MOVE_RIGHT_LEFT("Sposta in orizzontale"),
    MOVE_UP_DOWN("Sposta in verticale"),
    ZOOM("Zoom"), EMPTY(""),
    MAX_X_ALLOWED("LARGHEZZA: 600"), MAX_Y_ALLOWED("ALTEZZA: 600"),
    X_DIRECTION("0"), Y_DIRECTION("0"), ZOOM_DIRECTION("1")
    ;

    private JLabel label;

    private EnumLabel(String lab){
        this.label=new JLabel(lab);
    } 

    public  JLabel label (){
        return this.label;
    }
}
class MyPoint {
    // class with the data: useless for position of panel
}

person alepuzio    schedule 20.02.2013    source источник
comment
Ваш код неполный, чтобы мы могли ответить на этот вопрос. Попробуйте опубликовать SSCCE. Что такое container? Каково содержание LinesComponent? Планировка, размер, расположение и т. д. — все зависит друг от друга. Кстати, вызов setSize()/setLocation()/setBounds() бесполезен, если вы используете LayoutManager (что вам следует!)   -  person Guillaume Polet    schedule 20.02.2013
comment
Извините, старался вставить максимально полезный код, чтобы не утомлять вас. Заинтересованный код требует некоторого класса: куда я могу вставить весь свой код (связанный с этой проблемой), чтобы вы могли его увидеть?   -  person alepuzio    schedule 20.02.2013
comment
Размер видимой области определяется предпочтительным размером представления (в области прокрутки). Нам нужно увидеть LinesComponents, чтобы знать, что происходит...   -  person MadProgrammer    schedule 20.02.2013
comment
@alepuzio нет проблем, но поймите, что у нас должно быть достаточно информации, чтобы правильно помочь вам.   -  person Guillaume Polet    schedule 20.02.2013
comment
@Guillame Добавлен весь код в один единственный класс   -  person alepuzio    schedule 20.02.2013


Ответы (3)


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

Проверьте этот код, который показывает вам базовый пример того, как все это работает:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class TestScrollPane {

    public static class CustomComponent extends JPanel {

        private static final int RADIUS = 20;
        private int x = 0;
        private int y = 0;

        private double speed = 18;
        private double dx;
        private double dy;

        public CustomComponent() {
            dx = speed;
            dy = speed;
            Timer t = new Timer(20, new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    x += dx;
                    y += dy;
                    if (x + RADIUS > getWidth()) {
                        x = getWidth() - RADIUS;
                        dx = -speed;
                    } else if (x < 0) {
                        x = 0;
                        dx = speed;
                    }
                    if (y + RADIUS > getHeight()) {
                        y = getHeight() - RADIUS;
                        dy = -speed;
                    } else if (y < 0) {
                        y = 0;
                        dy = speed;
                    }
                    repaint();
                }
            });
            t.start();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.RED);
            g.fillOval(x, y, RADIUS, RADIUS);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(600, 600);
        }
    }

    protected void initUI() {
        JFrame window = new JFrame(TestScrollPane.class.getSimpleName());
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JScrollPane scroll = new JScrollPane(new CustomComponent(), JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        window.add(scroll);
        window.setSize(600, 500);
        window.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestScrollPane().initUI();
            }
        });
    }
}
person Guillaume Polet    schedule 20.02.2013

На самом деле ваш JScrollPane имеет размер 1000x1000px, поэтому, если есть полосы прокрутки, вы их не увидите, потому что размер вашего кадра 500x500. Обратите внимание, что JScrollPane действует на свое содержимое, это означает, что он показывает полосы прокрутки, если добавляемая к нему панель больше, чем сам JScrollPane, но не добавляет полосы прокрутки, если контейнер меньше.

person BackSlash    schedule 20.02.2013
comment
Если он не установил макет null, панель прокрутки вряд ли будет иметь размер 1000x1000. - person Guillaume Polet; 20.02.2013
comment
Я пытался поменять размеры (JScrollpane: 500x500, JPanel: 1000X1000), но у меня такая же ситуация (прокрутка не появляется) - person alepuzio; 20.02.2013
comment
Можете ли вы использовать только JScrollPane вместо панели в JScrollPane? - person BackSlash; 20.02.2013

Видимая область/пространство определяется (в большинстве случаев) предпочтительным размером представления. Это говорит о том, что ваша проблема связана с вашим представлением панелей прокрутки, а не с панелью прокрутки или чем-то еще, что вы нам предоставили.

введите здесь описание изображения

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

public class TestScrollPane02 {

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

    public TestScrollPane02() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(new LargePane()));
                frame.setSize(200, 200);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class LargePane extends JPanel {

        public LargePane() {
            setLayout(new GridBagLayout());
            add(new JLabel("I'm a large panel"));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.RED);
            g.drawLine(0, 0, getWidth(), getHeight());
            g.drawLine(getWidth(), 0, 0, getHeight());
        }

    }

}

Вы также можете просмотреть Scrollable. интерфейс, который предоставляет дополнительные подсказки обратно на панель прокрутки...

person MadProgrammer    schedule 20.02.2013