JScrollPane不显示滚动

时间:2013-02-20 10:17:48

标签: java swing jscrollpane jscrollbar

我有一个尺寸 500 X 500 的JFrame:它包含一个大小 1000 X 1000 的JComponent并且此JComponent包含在JScrollBar中,滚动条始终存在。 截图 enter image description here

代码

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

3 个答案:

答案 0 :(得分:3)

Scrollpane及其滚动条完全依赖于视口中组件的大小,默认情况下,该大小取决于该组件的首选大小。

检查此代码,该代码向您展示了这一切如何运作的基本示例:

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

答案 1 :(得分:2)

实际上你的JScrollPane是1000x1000px,所以如果有滚动条,你将看不到它们,因为你的框架是500x500。请注意,JScrollPane对其内容起作用,这意味着如果要添加到其中的面板大于JScrollPane本身,它会显示滚动条,但如果容器较小,则不会添加滚动条。

答案 2 :(得分:2)

可视区域/空间由视图的首选大小定义(在大多数情况下)。这表明您的问题在于滚动窗格视图,而不是滚动窗格或您提供给我们的任何其他内容

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

    }

}

您还可以查看Scrollable界面,该界面会向滚动窗格提供其他提示......