Pregunta

I have a JFrame with dimension 500 X 500: it contains a JComponent with size 1000 X 1000 and this JComponent is contained into a JScrollBar with scrollbar always present. The screenshot enter image description here

The code

    /**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

As showed into screenshot, the window has the scrollbar but it isn't working.

I tried to change the dimensions of JPanel and JFrame but the situation doesn't change.

I know that the scroll appears when the dimension of JComponent are greater of dimensione of JPanel container, but in this moment I see that I lose some information but I don't understand what is.

Do you have any suggest, please?

PS into screenshot I show that the scroll doesn't work, but in my desiderata the scroll has to work in vertical and horizontal senses

PS PS all my code in only one class

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
}
¿Fue útil?

Solución

Scrollpane and its scrollbars entirely rely on the size of the component in the viewport, which, by default, depends of the preferred size of that component.

Check this code which shows you a basic example of how this all works:

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();
            }
        });
    }
}

Otros consejos

Actually your JScrollPane is 1000x1000px, so if there are scroll bars, you won't see them, because your frame is 500x500. Note that the JScrollPane acts on its content, that means that it shows scrollbars if the panel you are adding to it is bigger than the JScrollPane itself, but doesn't add scrollbars if the container is smaller.

The viewable area/space is defined (in most cases) by the view's preferred size. This suggests that your problem lies with your scroll panes view and not the scroll pane or anything else you've provided us

enter image description here

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());
        }

    }

}

You can also have a look the Scrollable interface which provides additional hints back to the scroll pane...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top