Полоса прокрутки не прокручивается в Java Swing

#java #swing #jscrollpane

#java #swing #jscrollpane

Вопрос:

Я пытаюсь добавить область прокрутки на внутреннюю панель, и на внутренней панели отображается полоса прокрутки, но когда я добавляю метки и текстовое поле, компоненты были добавлены, но полоса прокрутки не работает.

 public class AddNewProject extends JFrame {
    private JButton btnNewButton;
    private JSpinner spinner;
    private JScrollPane scrollPane;
    private JPanel panel_1;
    
    public AddNewProject() {
        getContentPane().setLayout(null);
        
        JPanel panel = new JPanel();
        panel.setBackground(Color.PINK);
        panel.setBounds(134, 37, 583, 610);
        getContentPane().add(panel);
        panel.setLayout(null);
        
        spinner = new JSpinner();
        spinner.setModel(new SpinnerNumberModel(0, 0, 30, 1));
        spinner.setBounds(63, 51, 164, 31);
        panel.add(spinner);
        
        btnNewButton = new JButton("New button");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                int n=(int) spinner.getValue();
                JLabel jlabel[]=new JLabel[n];
                JTextField jtxt[]=new JTextField[n];
                                
                for(int i =0;i<n;i  )
                {
                    jlabel[i]=new JLabel("Label " (i 1));
                    jtxt[i]=new JTextField(32);
                    
                    panel_1.add(jlabel[i]);
                    panel_1.add(jtxt[i]);
                }
                panel_1.validate();
                panel_1.repaint();
            }
        });
        btnNewButton.setBounds(336, 54, 149, 28);
        panel.add(btnNewButton);
        
        scrollPane = new JScrollPane();     
        scrollPane.setBounds(69, 141, 434, 298);
        panel.add(scrollPane);
        
        panel_1 = new JPanel();
        
        scrollPane.setViewportView(panel_1);
        scrollPane.setPreferredSize(new Dimension(434,300));
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        
        setSize(900,800);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        
    }
    public static void main(String[] args) {
        new AddNewProject();
    }
}
  

Вывод вышеупомянутой программы

Вывод вышеупомянутой программы

Это выходной образ моей программы.

Ответ №1:

Вам нужно повторно проверить саму JScrollPane, чтобы она повторно разместила свой видовой экран и его представление, чтобы это сработало. Но вам также нужно будет настроить макет внутренней JPanel, чтобы разрешить отображение сетки элементов для правильной работы, например, присвоив ей new GridLayout(0, 1) // one column, variable # of rows .

например,

 import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.*;

@SuppressWarnings("serial")
public class AddNewProject2 extends JPanel {
    private JPanel gridPanel = new JPanel(new GridLayout(0, 1)); // 1 column grid
    private JSpinner spinner = new JSpinner(new SpinnerNumberModel(0, 0, 30, 1));
    
    
    public AddNewProject2() {
        JPanel wrapperPanel = new JPanel(new BorderLayout());
        wrapperPanel.add(gridPanel, BorderLayout.PAGE_START);
        JScrollPane scrollPane = new JScrollPane(wrapperPanel);
        scrollPane.getViewport().setPreferredSize(new Dimension(450, 500));
        
        JButton newRowBtn = new JButton("New Row");
        newRowBtn.addActionListener(e -> {
            int rows = (int) spinner.getValue();
            for (int i = 0; i < rows; i  ) {
                JLabel label = new JLabel("Label "   String.format("d", i   1));
                JTextField txtFld = new JTextField(32);
                JPanel row = new JPanel();
                row.add(label);
                row.add(txtFld);
                gridPanel.add(row);
            }
            
            scrollPane.revalidate();
        });
        
        JPanel topPanel = new JPanel();
        topPanel.add(spinner);
        topPanel.add(newRowBtn);
        
        int gap = 20;
        setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
        setLayout(new BorderLayout(gap, gap));
        
        add(topPanel, BorderLayout.PAGE_START);
        add(scrollPane);
    }
    
    
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("GUI");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            
            AddNewProject2 project2 = new AddNewProject2();
            frame.add(project2);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}
  

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

1. но почему цвет фона не устанавливается в панели сетки даже после ее перерисовки

Ответ №2:

Проблема в том, что вы везде используете пустые макеты. Полосы прокрутки появляются только тогда, когда предпочтительный размер компонента, добавленного в окно просмотра, больше размера окна просмотра. Предпочтительный размер вычисляется динамически только при использовании менеджеров компоновки. Итак, решение заключается в использовании менеджеров компоновки.

Для самых основных изменений в вашем коде вы:

  1. удалите все инструкции setBounds()
  2. удалите все инструкции setLayout (null)

Затем вы можете начать использовать менеджеры компоновки.

Начните с создания панели для верхнего:

 JPanel topPanel = new JPanel();
topPanel.add(spinner)
topPanel.add(btnNewButton);
add(topPanel, BorderLayout.PAGE_START);
  

Затем добавьте свою область прокрутки в рамку:

 add(scrollPane, BorderLayout.CENTER);
  

Теперь вам нужно использовать:

 //panel_1.validate();
panel_1.revalidate();
  

Revalidate() вызывает диспетчер компоновки, чтобы можно было вычислить новый предпочтительный размер.

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

Если вы хотите, чтобы компоненты добавлялись вертикально, вам нужно будет использовать другой менеджер компоновки в «panel_1».

Прочитайте раздел из руководства Swing по менеджерам компоновки для получения дополнительной информации и примеров.

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

1. Спасибо, что помогли мне понять концепцию