0

我需要清除我的JPanel. 这个JPanel调用mainPane有一个GridLayout包含JScrollPane's, and theseJScrollPane s contain customJPanel s that overridepaintComponent()`。

无论我尝试什么——将列表设置为空,用新对象替换旧实例——只要我调整窗口框架的大小,paintComponent()就会调用视图的 get 并在其中绘制视图mainPane

public void createContentPane() 
    {
        gridLay = new GridLayout(GRID_ROWS, GRID_COLUMNS);

        graphicViewList = new ArrayList<View>();
        for (int i = 0; i < graphicViewList.size(); i++) {
            View v = graphicViewList.get(i);
            v = null;
        }
        mainPane = new JPanel();

        clearGrid();
        mainPane.removeAll();
        mainPane.validate();
        graphicViewList.clear();
        imageModel.deleteObservers();
        mainPane.setLayout(gridLay);
        this.getContentPane().remove(mainPane);
        this.getContentPane().add(mainPane, BorderLayout.CENTER);
        mainPane.revalidate();
        mainPane.repaint();

    }

    public void createViews()
    {
        int idx = 0;
        graphicViewList.clear();

        while(idx < NUM_PERSPECTIVE) //iterator?
        {
            if(idx == 0)
            {
                graphicViewList.add(new ThumbnailView(this, imageModel));
                mainPane.add(new JScrollPane(graphicViewList.get(idx)));
                idx++;
                continue;
            }
            graphicViewList.add(new ImageView(this, imageModel));
            mainPane.add(new JScrollPane(graphicViewList.get(idx)));
            idx++;
        }

        for (int i = 0; i < graphicViewList.size(); i++)
            graphicViewList.get(i).removeFocus();

        this.getContentPane().add(mainPane, BorderLayout.CENTER);
    }

    private void clearGrid()
    {
        for (int i = 0; i < mainPane.getComponentCount(); i++) {
            JScrollPane sP =(JScrollPane) mainPane.getComponent(i);
            sP = null;

        }
    }

createContentPane()我知道是矫枉过正,我只是绝望。所以基本上第一个函数和第二个函数在 GUI 构造函数中被调用。当我调用以createContentPane()替换旧 UI(具有相同的结构,只是不同的内容)时,只要我调整容器的大小,它的内容就会重新绘制。唯一的区别是,在第二次createContentPane()调用时,resize draw 在布局上绘制,元素不再在里面。

我认为这createContentPane()会清空所有内容并删除我可能拥有的所有引用,但paintComponent()仍然可以使用视图绘制滚动条。

4

2 回答 2

2

在 clearGrid() 中,您需要调用remove(Component comp)(在您的情况下为 sp)或removeAll();

于 2011-12-15T01:12:05.790 回答
2

在您的 clearGrid 方法中,您不会从面板中删除任何内容;您只是获得对 mainPane 内部内容的引用,然后将该引用设置为 null。相反,您需要实际调用mainPane.remove(sP);每个滚动窗格。

此外,您可以尝试调用mainPane.removeAll();. 请注意,如文档中所述,您必须在之后重新验证面板。

Container.removeAll


这是 Andrew Thompson 之前提到的 SSCCE。以后在提问时尝试这样做,这样人们就可以运行它并帮助修复它。

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

public class PanelClearerExample {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                PanelClearerExample app = new PanelClearerExample();
                app.startUp();
            }
        });
    }

    private final String CLEAR_COMMAND = "Clear";
    private final String REBUILD_COMMAND = "Rebuild";
    private JFrame controlFrame;
    private int displayCount = 0;
    private JFrame displayFrame;
    private JPanel displayPanel = new JPanel();

    private void startUp() {
        displayFrame = new JFrame("Display");
        displayFrame.setSize(300, 300);
        displayFrame.setLocation(300, 0);
        displayFrame.add(buildDisplay(), BorderLayout.CENTER);

        controlFrame = new JFrame("Control");
        controlFrame.setSize(200, 100);
        controlFrame.add(buildControl(), BorderLayout.CENTER);
        controlFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        displayFrame.setVisible(true);
        controlFrame.setVisible(true);
    }

    private Component buildDisplay() {
        populateDisplay();
        return displayPanel;
    }

    private void populateDisplay() {
        displayCount++;
        displayPanel.setLayout(new GridLayout(2, 2));
        String text = "Display " + displayCount;
        for (int i = 0; i < 4; i++) {
            displayPanel.add(new JLabel(text, JLabel.CENTER));
        }
    }

    private Component buildControl() {
        JPanel p = new JPanel(new BorderLayout());
        final JButton button = new JButton(CLEAR_COMMAND);
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                if (CLEAR_COMMAND.equals(ae.getActionCommand())) {
                    clearDisplay();
                    button.setText(REBUILD_COMMAND);
                    button.setActionCommand(REBUILD_COMMAND);

                } else {
                    repopulateDisplay();
                    button.setText(CLEAR_COMMAND);
                    button.setActionCommand(CLEAR_COMMAND);
                }
            }
        });
        p.add(button);

        return p;
    }

    private void clearDisplay() {
        displayPanel.removeAll();
        displayPanel.repaint();
    }

    private void repopulateDisplay() {
        populateDisplay();
        displayPanel.revalidate();
    }
}
于 2011-12-15T01:12:27.507 回答