用JPanel构造JScrollPane时滚动条消失

Scrollbars disappear when constructing JScrollPane with JPanel

我想做的是加载一个图片到一个JScrollPane中,周围是其他组件,当window小于图片时,它应该被滚动条包围,这样你就可以看到整个滚动图片。

我通过使用我自己的 class ImagePanel 构建一个 JScrollPane 来做到这一点,它扩展了绘制图像的 JPanel。图像已正确加载和显示,但滚动条消失了。我是否误解了 JComponents 的某些部分或出了什么问题?

public class ImagePanel extends JPanel {
    private BufferedImage img;
    public ImagePanel () {

    }
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(img, 0, 0, this);
    }
    public void setImage(BufferedImage img) {
        this.img = img;
    }
}


public class MainGUI extends JPanel {
    private ImagePanel imgP;
    private JScrollPane pane;
    public MainGUI () {
        setLayout(new GridBagLayout());

        //Create local components
        //JComponents
        JButton hideButton = new JButton("Hide");
        JButton hidecategoryButton = new JButton ("Hide Category");
        JButton removeButton = new JButton("Remove");
        JButton searchButton = new JButton("Search");
        JButton whatishereButton = new JButton("What is here?");

        JComboBox<String> placeComboBox;

        JLabel categoriesLabel = new JLabel("Categories");
        JLabel newLabel = new JLabel("New: ");

        JTextArea categoriesArea = new JTextArea();

        JTextField searchField = new JTextField(10);

        //Other
        String[] placeTypes = {"Named Place", "Described Place"};


        //Initialize and add behaviour
        searchButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                String s = searchField.getText();

            }

        });
        categoriesArea.setEditable(false);
        placeComboBox = new JComboBox<>(placeTypes);

        searchField.setToolTipText("Search...");
        searchField.setMinimumSize(new Dimension(5, 1));

        //Just fileloading test
        BufferedImage bi2 = null;
        try {
            bi2 = ImageIO.read(new File("dafoe.jpg"));
        }
        catch (Exception ex) {

        }
        imgP = new ImagePanel();
        imgP.setImage(bi2);
        pane = new JScrollPane(imgP);

        //Add to panel
        GridBagConstraints gc;

        //Top row
        JPanel toprowPanel = new JPanel();
        toprowPanel.add(newLabel);
        toprowPanel.add(placeComboBox);
        toprowPanel.add(searchField);
        toprowPanel.add(searchButton);
        toprowPanel.add(hideButton);
        toprowPanel.add(removeButton);
        toprowPanel.add(whatishereButton);

        gc = new GridBagConstraints();
        gc.gridx = 0;
        gc.gridy = 0;
        gc.weightx = 1;
        //gc.gridwidth = 6;
        add(toprowPanel, gc);

        //Hide category
        gc = new GridBagConstraints();
        gc.anchor = GridBagConstraints.NORTH; 
        gc.gridx = 7;
        gc.gridy = 3;
        gc.weightx = 0;
        gc.weighty = 0;
        add(hidecategoryButton, gc);

        //Category Label
        gc = new GridBagConstraints();
        gc.anchor = GridBagConstraints.BELOW_BASELINE;
        gc.gridx = 7;
        gc.gridy = 1;
        gc.weightx = 0;
        gc.weighty = 0;
        add(categoriesLabel, gc);       


        //categoriesarea
        gc = new GridBagConstraints();
        gc.anchor = GridBagConstraints.BASELINE_TRAILING;
        gc.fill = GridBagConstraints.BOTH;
        gc.gridx = 7;
        gc.gridy = 2;
        gc.ipadx = 5;
        gc.ipady = 70;
        gc.weightx = 0;
        gc.weighty = 0;
        add(categoriesArea, gc);

        //Image
        gc = getImageConstraints();

        add(pane,  gc);
    }

    public void updateImage(BufferedImage bi) {
        imgP.setImage(bi);
        //imgP.repaint();

        pane.repaint();
    }
    private GridBagConstraints getImageConstraints() {
        GridBagConstraints gc = new GridBagConstraints();
        gc.fill = GridBagConstraints.BOTH;
        gc.gridheight = 3;
        gc.gridwidth = 1;
        gc.gridx = 0;
        gc.gridy = 1;
        gc.weightx = 1;
        gc.weighty = 1;
        return gc;
    }
}

布局为GridBagLayout时不能使用滚动条。您必须使用 BorderLayout 或 FlowLayout

Link jtable 示例(类似于图像):

http://myquestionjava.blogspot.com/2016/04/jscrollbars-and-jtable-in-java.html

my own class ImagePanel, which extends JPanel, which paints the image. The image is loaded and displayed correctly, but the scrollbars disappear.

当添加到滚动窗格的组件的首选大小大于滚动窗格的大小时,滚动条将自动出现。

您的自定义组件的首选大小为 (0, 0),因此永远不会出现滚动条。

您需要将 ImagePanel class 的 getPreferredSize() 覆盖为 return 图片的大小。

或者更简单的方法是使用带有 ImageIcon 的 JLabel 并将标签添加到滚动窗格。 JLabel 已经正确实现了 getPreferredSize() 方法。