0

我有一个尺寸为500 X 500的 JFrame :它包含一个尺寸为1000 X 1000的 JComponent,并且此 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

如屏幕截图所示,窗口有滚动条,但它不工作。

我试图改变JPanelJFrame的尺寸,但情况并没有改变。

我知道当JComponent的尺寸大于JPanel容器的尺寸时会出现滚动,但是此刻我看到我丢失了一些信息,但我不明白是什么。

请问您有什么建议吗?

PS进入屏幕截图我显示滚动不起作用,但在我的需求中,滚动必须在垂直和水平意义上工作

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
}
4

3 回答 3

3

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();
            }
        });
    }
}
于 2013-02-20T10:49:41.170 回答
2

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

在此处输入图像描述

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界面,该界面提供了返回到滚动窗格的其他提示...

于 2013-02-20T10:40:05.713 回答
2

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

于 2013-02-20T10:21:03.910 回答