Какой из этих различных методов обновления я должен вызвать, чтобы компоненты отображались после добавления в JPanel? - PullRequest
1 голос
/ 05 августа 2020

В этом простом коде, если я нажму кнопку несколько раз, несколько JCheckBox будут добавлены в JPanel. Однако дисплей не обновляется, если сразу после add("TEST") я не вызываю либо revalidate() (просто invalidate() не работает), либо updateFrame(). Кроме того, если я использую revalidate(), JCheckBoxes появляются, но размер JPanel не изменяется. Мне также известен метод repaint(), но я не уверен, как использовать его или другие методы.

Какова взаимосвязь между этими методами обновления компонентов, чтобы я мог достичь желаемого минимума (появятся JCheckBoxes и изменится размер панели JPanel)?

Как я могу упростить код?

public class UserInterface2 {

    private final JFrame frame;
    private JButton button;
    private JPanel panel;
    
    public UserInterface2() {
        
        frame = new JFrame("Test App");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.getContentPane().setLayout(new BorderLayout());
        
        createButton();
        panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
        
        frame.getContentPane().add(button, BorderLayout.WEST);
        frame.getContentPane().add(panel, BorderLayout.CENTER);
    }
    
    private void updateFrame() {
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
    
    private void createButton() {
        button = new JButton("Text");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                add("TEST");
                panel.revalidate();
                //updateFrame();
            }
        });
    }
    
    public void show() {
        updateFrame();
    }

    private void add(String text) {
        panel.add(new JCheckBox(text));
    }
    
    public static void main(String [] args) {
        SwingUtilities.invokeLater(() -> new UserInterface2().show());
    }
}

1 Ответ

1 голос
/ 06 августа 2020
• 1000
  1. Поместите JPanel внутрь JScrollPane, что позволит изменять размер JPanel по мере добавления компонентов (и вызывается revalidate()) или
  2. Вызов pack() в закрывающем окне верхнего уровня , здесь JFrame, после добавления компонентов в JPanel, который изменит размер всего GUI.

Также рассмотрите

  • предоставление JPanel GridLayout (0, 1) ...
  • ... встраивание его в позицию BorderLayout.PAGE_START другого BorderLayout с использованием JPanel ...
  • ... затем добавление этой JPanel в панель прокрутки или в позиция BorderLayout.CENTER в contentPane JFrame. Это приведет к сжатию добавленных компонентов в верхнюю часть панели JPanel.

Например:

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

public class UserInterface3 {
    private JPanel mainPanel = new JPanel(new BorderLayout());
    private JPanel panel = new JPanel(new GridLayout(0, 1));
    
    public UserInterface3() {
        JPanel wrapperPanel = new JPanel(new BorderLayout());
        wrapperPanel.add(panel, BorderLayout.PAGE_START);       
        JScrollPane scrollPane = new JScrollPane(wrapperPanel);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        scrollPane.getViewport().setPreferredSize(new Dimension(300, 300));
        
        JButton addCheckBoxBtn = new JButton("Add CheckBox");
        addCheckBoxBtn.addActionListener(e -> addCheckBox());
        addCheckBoxBtn.setMnemonic(KeyEvent.VK_A);
        JPanel btnPanel = new JPanel();
        btnPanel.add(addCheckBoxBtn);       
        
        
        mainPanel.add(scrollPane);
        mainPanel.add(btnPanel, BorderLayout.PAGE_END);     
    }
    
    private void addCheckBox() {
        panel.add(new JCheckBox("Test"));
        mainPanel.revalidate();
    }

    public JPanel getMainPanel() {
        return mainPanel;
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("GUI");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            UserInterface3 ui3 = new UserInterface3();
            frame.add(ui3.getMainPanel());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}
...