Полоса прокрутки JScrollPane не отображается?

package me.an.ugm;

import java.awt.EventQueue;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;

public class Application
{
    private JFrame frame;

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    Application window = new Application();
                    window.frame.setVisible(true);
                } catch (Exception e)
                {
                    e.printStackTrace();
                }
            }

        });
    }

    public Application()
    {
        initialize();
    }

    private void initialize()
    {
        frame = new JFrame();
        frame.setTitle("Application");
        frame.setBounds(100, 100, 401, 450);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);
        //frame.setResizable(false);
        frame.setLocationRelativeTo(null);

        JPanel panel = new JPanel();
        panel.setBounds(0, 0, 296, 710);
        panel.setLayout(null);

        JScrollPane scrollPane = new JScrollPane(panel, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        scrollPane.setBounds(0, 0, 296, 399);
        frame.getContentPane().add(scrollPane);

        for (int i = 0, j = 10; i < 20; i++, j += 35)
        {
            JButton button1 = new JButton();
            button1.setBounds(10, j, 25, 25);
            panel.add(button1);

            JComboBox<String> selectorBox = new JComboBox<>();
            selectorBox.setBounds(40, j, 200, 25);
            panel.add(selectorBox);

            JButton button2 = new JButton();
            button2.setBounds(245, j, 25, 25);
            panel.add(button2);
        }
    }
}

Я не знаю, почему полоса прокрутки не отображается. JPanel больше, чем JScrollPane, поэтому я подумал, что он должен появиться. Также, когда я пытаюсь использовать setPreferredSize для панели прокрутки вместо setBounds или setSize, тогда вообще ничего не появляется. Моя конечная цель для программы - отключить кнопку справа, чтобы добавить еще один набор кнопок (те, что в цикле), которые будут использоваться для выбора другого элемента. Я хотел, чтобы программа запускалась с 10 рядами кнопок, но я установил 20, чтобы проверить полосу прокрутки. Это проблема с отсутствием макета или я что-то напутал с панелью прокрутки?


person Denny Williams    schedule 11.12.2020    source источник
comment
Не используйте нулевой макет!!! Swing был разработан для использования с менеджерами компоновки. Панели прокрутки НЕ будут работать, если вы используете нулевой макет.   -  person camickr    schedule 11.12.2020
comment
Помните, что LayoutManagers предназначены для помощи разработчикам. Они делают много вещей за кулисами, чтобы заставить работать то, что требует больших усилий. Почему ты не хочешь их использовать?   -  person NomadMaker    schedule 11.12.2020


Ответы (1)


Проблема заключалась в использовании неправильных макетов Swing.

Вот графический интерфейс, который я создал.

Графический интерфейс приложения

Я добавил текст к кнопкам и полю со списком, чтобы графический интерфейс выглядел более реалистично. Я прокомментировал внешний вид, чтобы сосредоточиться на графическом интерфейсе. Я изменил имя класса, потому что у меня есть один тестовый пакет для всего кода, который я пишу для Stack Overflow.

Я создал кнопку JPanel в отдельном методе. Я использовал GridLayout. Это позволило мне создать 20 рядов из 3 компонентов Swing. Это также позволило мне немного разнести компоненты.

Я создал прокрутку JPanel другим отдельным методом. Ключ был в том, чтобы использовать BorderLayout для прокрутки JPanel. Я сделал прокрутку JPanel вдвое меньше кнопки JPanel, чтобы она прокручивалась. Вы можете настроить этот расчет по своему усмотрению.

Вот полный исполняемый код.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class JButtonScrollGUI {
    private JFrame frame;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
//                  UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    new JButtonScrollGUI();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        });
    }
    
    private String[] greekAlphabet;

    public JButtonScrollGUI() {
        this.greekAlphabet = new String[] { "alpha", "beta", "gamma", "epsilon", "zeta" };
        initialize();
    }

    private void initialize() {
        frame = new JFrame();
        frame.setTitle("Application");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(createScrollPanel(), BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JPanel createScrollPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        
        JPanel innerPanel = createButtonPanel();
        Dimension d = innerPanel.getPreferredSize();
        d.width += 50;
        d.height /= 2;
        panel.setPreferredSize(d);
        
        JScrollPane scrollPane = new JScrollPane(innerPanel);
        
        panel.add(scrollPane, BorderLayout.CENTER);
        return panel;
    }
    
    private JPanel createButtonPanel() {
        JPanel panel = new JPanel(new GridLayout(0, 3, 10, 10));
        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        
        for (int i = 0; i < 20; i++) {
            JButton button1 = new JButton("Previous " + i);
            panel.add(button1);

            JComboBox<String> selectorBox = new JComboBox<>(greekAlphabet);
            panel.add(selectorBox);

            JButton button2 = new JButton("Next " + i);
            button2.setPreferredSize(button1.getPreferredSize());
            panel.add(button2);
        }
        
        return panel;
    }
    
}
person Gilbert Le Blanc    schedule 11.12.2020