将当前JPanel分配给新的JPanel实例但不刷新

时间:2016-04-05 02:46:44

标签: java swing user-interface jpanel repaint

我已经对JPanel进行了细分,以提供一个通用的JPanel容器,其中包含从JComboBox中选择的过滤器的选项。

当JComboBox从一个过滤器更改为另一个过滤器时,我有一个switch语句,用于检查现在选择哪个过滤器并重新分配"选项" JPanel到与该过滤器关联的选项类的新实例:

public void setFilterOptions(String choice){
    switch(choice){
        case "Gaussian": options = new GaussianFilterOptions();break;
        case "Sobel": options = new SobelFilterOptions();System.out.println("?");break;
    }
}

问题在于JPanel"选项"调用setFilterOptions后,GUI中不会刷新。默认情况下设置为默认显示的过滤器会在启动时出现,即使我切换JComboBox选项也会保留。我尝试过重新绘制,重新验证和验证"选项"以及包含"选项的JPanel"以及包含整个应用程序的JFrame。

我在每种情况下都添加了打印语句,以验证它们在组合框切换时是否正常工作而没有掉线,所以我确定这不是问题。

2 个答案:

答案 0 :(得分:4)

你把变量与对象混淆了。您可能最初放置了一个JPanel对象,其中的选项被引用到您的GUI中,但是理解,您没有将options变量放入GUI ,而是(并且再次) JPanel对象它将引用到GUI中。

如果稍后您更改了options变量引用的JPanel,则 对GUI 没有影响,因为它仍然保留相同的原始JPanel 它之前持有的对象。如果要更改显示的JPanel,则必须通过在GUI中交换JPanel来直接执行此操作。最好使用CardLayout来完成。

如,

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class SwapPanels extends JPanel {
    private static final String GAUSSIAN = "Gaussian";
    private static final String SOBEL = "Sobel";
    private static final String[] FILTER_OPTIONS = {GAUSSIAN, SOBEL};
    private CardLayout cardLayout = new CardLayout();
    private JPanel cardHolderPanel = new JPanel(cardLayout);
    private JPanel gaussianPanel = new JPanel();
    private JPanel sobelPanel = new JPanel();
    private JComboBox<String> filterCombo = new JComboBox<>(FILTER_OPTIONS);

    public SwapPanels() {
        JPanel comboPanel = new JPanel();
        comboPanel.add(filterCombo);
        filterCombo.addActionListener(new ComboListener());

        gaussianPanel.add(new JLabel("Gaussian Filtering Done Here"));
        sobelPanel.add(new JLabel("Sobel Filtering Done Here"));
        cardHolderPanel.add(gaussianPanel, GAUSSIAN);
        cardHolderPanel.add(sobelPanel, SOBEL);
        int gap = 50;
        cardHolderPanel.setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));

        setLayout(new BorderLayout());
        add(cardHolderPanel, BorderLayout.CENTER);
        add(comboPanel, BorderLayout.PAGE_END);
    }

    private class ComboListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            String key = (String) filterCombo.getSelectedItem();
            cardLayout.show(cardHolderPanel, key);
        }
    }

    private static void createAndShowGui() {
        SwapPanels mainPanel = new SwapPanels();

        JFrame frame = new JFrame("SwapPanels");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

答案 1 :(得分:0)

你也可以这样做,而不是开关

public void setFilterOptions(String choice){
    options = (choice.equals("Gaussian"))? new GaussianFilterOptions():
                                           new SobelFilterOptions();  
    }
}