Почему, о, почему, моя область прокрутки никуда не прокручивается?

#java #swing #jscrollpane #grid-layout

#java #качать #jscrollpane #сетка-макет

Вопрос:

Я не могу понять, почему в этом коде не отображаются полосы прокрутки. Я полный новичок в Swing, поэтому области прокрутки очень запутанны, и я не понимаю некоторые решения, которые я видел в Интернете. Раздражает то, что этот код ненадолго сработал, но я уничтожил успешную часть, прежде чем создать ее резервную копию при попытке добавить компонент. Буду признателен за любую помощь!

 import javax.swing.*;
import java.awt.*;

public class Test extends JFrame
{
    private JPanel leftPanel;
    private JButton myButton;
    private JPanel scrollPanel;
    private JScrollPane scrollPane;
    
    public static void main(String[] args)
    {
        System.setProperty("swing.defaultlaf", "com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
        javax.swing.SwingUtilities.invokeLater(new Runnable()
        {
            public void run() {
                new Test();
            }
        });
    }
    
    /**
     * Constructor for objects of class Backup
     */
    public Test()
    {
        this.setTitle("testy");
        this.setSize(new Dimension(1280,622));
        
        leftPanel = new JPanel();
        leftPanel.setBackground(new Color(255,0,0));
        leftPanel.setBounds(0, 100, 640, 558);
        leftPanel.setEnabled(true);
        this.add(leftPanel);
        
        scrollPanel = new JPanel(null);
        scrollPanel.setBackground(new Color(100,100,100));
        scrollPanel.setPreferredSize(new Dimension(640, 550));
        scrollPanel.setEnabled(true);
        
        JScrollPane scrollPane = new JScrollPane(scrollPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
        JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setBounds(0, 0, 642, 550);
        scrollPane.setEnabled(true);
        leftPanel.add(scrollPane);
        
        for (int i = 1; i < 30; i  ) 
        {
            scrollPanel.setLayout(new GridLayout(30, 1, 0, 1));
            myButton = new JButton("AAAAAAAAAAAAAAAAAAAAA "   i);
            myButton.setPreferredSize(new Dimension(630, 70));
            scrollPanel.add(myButton);
        }
        
        this.setBackground(new Color(0,0,0));
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.pack();
        this.setVisible(true);
}
}
 

Я думаю, что с тех пор я значительно улучшил ее благодаря camickr
Вот текущая версия:

    import javax.swing.*;
   import java.awt.*;

    public class Test extends JFrame
    {
    private JPanel leftPanel;
    private JButton myButton;
    private JPanel scrollPanel;
    private JScrollPane scrollPane;

    public static void main(String[] args)
    {
    System.setProperty("swing.defaultlaf", 
    "com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    javax.swing.SwingUtilities.invokeLater(new Runnable()
    {
        public void run() {
            new Test();
        }
    });
    }


    public Test()
    {
    this.setTitle("testy");
    this.setSize(new Dimension(1280,622));
    
    leftPanel = new JPanel();
    leftPanel.setBackground(new Color(255,0,0));
    leftPanel.setBounds(0, 100, 640, 558);
    this.add(leftPanel);
    
    scrollPanel = new JPanel();
    scrollPanel.setLayout(new GridLayout(70, 1, 0, 1));
    //scrollPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 
    20));
    scrollPanel.setBackground(new Color(100,100,100));
    //scrollPanel.setPreferredSize(new Dimension(640, 550));
    
    //JScrollPane scrollPane = new JScrollPane(scrollPanel);
    JScrollPane scrollPane = new JScrollPane(scrollPanel, 
    JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
    JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    //scrollPane.setLayout(new GridLayout(30, 1, 0, 1));
    //scrollPane.setBounds(0, 0, 642, 550);
    scrollPane.setEnabled(true);
    //scrollPanel.add(scrollPane);
    
    leftPanel.add(scrollPanel);

    for (int i = 1; i < 71; i  ) 
    {
        myButton = new JButton("AAAAAAAAAAAAAAAAAAAAA "   i);
        //myButton.setPreferredSize(new Dimension(640, 80));
        scrollPanel.add(myButton);
    }
    
    this.setBackground(new Color(0,0,0));
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.pack();
    this.setVisible(true);
    }}
 

Ответ №1:

  1. Не используйте нулевой макет.
  2. Не используйте setBounds() .
  3. Не используйте setPreferredSize() .

Каждый компонент Swing отвечает за определение своего собственного предпочтительного размера. Затем диспетчер компоновки установит размер / расположение каждого компонента, добавленного на панель, и затем (динамически) вычислит предпочтительный размер панели. Полосы прокрутки появятся, когда предпочтительный размер панели будет больше размера области прокрутки.

     scrollPanel = new JPanel(null);
    scrollPanel.setBackground(new Color(100,100,100));
    // scrollPanel.setPreferredSize(new Dimension(640, 550)); // delete
    //scrollPanel.setEnabled(true); // not needed
    ...

    for (int i = 1; i < 30; i  ) 
    {
        //scrollPanel.setLayout(new GridLayout(30, 1, 0, 1)); // set layout when panel created.
        //myButton.setPreferredSize(new Dimension(630, 70)); // not needed.
 
  1. Менеджер компоновки должен быть установлен вне цикла при создании панели. Оно НЕ должно быть нулевым.
  2. Не вводите жесткий код предпочтительного размера. Она не будет динамически настраиваться по мере добавления компонентов.
  3. Компоненты Swing включены по умолчанию, чтобы setEnabled не требовался.
  4. Не используйте «Левую панель». Просто добавьте область прокрутки непосредственно во фрейм. Это позволит динамически изменять размер области прокрутки по мере изменения размера фрейма. Тогда полосы прокрутки появятся по требованию.
  5. Не устанавливайте размер preferreid кнопки. Размер будет определяться на основе текста и шрифта кнопки.

Комментарии:

1. Хорошо, я отключил диспетчер компоновки, удалил все элементы, связанные с размером (кроме левой панели), не думаю, что смогу вырезать левую панель, поскольку я вырезал этот фрагмент из фрейма с правой и верхней панелями, я удалил макет с установленным значением и нулевым макетом. Кнопки, похоже, масштабируются все меньше, хотя и без создания области прокрутки. По какой-то причине добавление области прокрутки непосредственно в левую панель ничего не отображает, и, несмотря на добавление сотен кнопок, которые в настоящее время продолжаются за кадром, я никогда не смогу перейти к ним.

2. @Tomato, в пункте 4 я специально указал 1) не используйте «Левую панель» и 2) добавьте область прокрутки непосредственно в фрейм.