Java Swing重绘问题

时间:2013-11-21 23:10:59

标签: java swing jpanel repaint

我正在尝试重新绘制面板,但它无法正常工作。基本上我的面板接受一个ArrayList,然后对于ArrayList中的每个元素,它将其打印出来。当我单击一个按钮时,它会删除ArrayList的相应元素,然后调用整个面板重新绘制自己。我希望在重新绘制后显示相同的面板,但没有那个政治家,但点击按钮什么都不做。它确实影响了这个消息,虽然很明显政治家被从名单中删除但是没有从JPanel中删除。

class fakeMPTable extends JPanel //table using Grid Layout
        {
            public void refresh()
            {
                revalidate();
                repaint();
            }

            public fakeMPTable()
            {
                setLayout(new GridBagLayout());
                GridBagConstraints c = new GridBagConstraints();
                c.fill = GridBagConstraints.HORIZONTAL;

                for (int i=0; i<politicians.size();i++)
                {
                    final int j=i;
                    JLabel politician = new JLabel(politicians.get(j));
                    JButton delete = new JButton();
                    delete.addActionListener(new 
                            ActionListener()
                    {
                        public void actionPerformed(ActionEvent e)
                        {
                            int selectedOption = JOptionPane.showConfirmDialog(null, 
                                    "Are you sure you want to delete \'" + politicians.get(j)+"\'?",
                                    "Warning", 
                                    JOptionPane.YES_NO_OPTION); 
                            if (selectedOption==0)
                            {
                                politicians.remove(j);
                                refresh();
                            }
                        }
                    }
                    c.gridy++;
                    add(delete, c);
                    add(politician,c);
             }

2 个答案:

答案 0 :(得分:3)

您需要更改JPanel本身的结构,否则您要求revalidate()但没有任何变化。

您应该将用于添加条目和按钮的代码部分分解到JPanel,以便您可以在开头调用它,然后在ActionListener中首先删除元素:

this.removeAll();
this.addEntriesAccordingtoList();
this.revalidate();

答案 1 :(得分:1)

基本上,您不会删除与精选政治家相关联的组件。

您有几种可能的解决方案。

你可以

为标签和按钮创建单独的List,其中每个项目与politicians列表中的相同项目匹配。

这意味着当您访问n政治家时,您可以使用相同的索引访问相关的标签和按钮...

class FakeMPTable extends JPanel //table using Grid Layout
{

    private List<String> politicians;
    private List<JLabel> labels;
    private List<JButton> buttons;

    public void refresh() {
        revalidate();
        repaint();
    }

    public FakeMPTable() {

        politicians = new ArrayList<>(25);
        for (int index = 0; index < 26; index++) {
            politicians.add(Character.toString((char) ('A' + index)));
        }

        labels = new ArrayList<>(25);
        buttons = new ArrayList<>(25);

        setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;

        for (int i = 0; i < politicians.size(); i++) {
            final int j = i;
            JLabel politician = new JLabel(politicians.get(j));
            JButton delete = new JButton();
            labels.add(politician);
            buttons.add(delete);
            delete.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    int selectedOption = JOptionPane.showConfirmDialog(null,
                            "Are you sure you want to delete \'" + politicians.get(j) + "\'?",
                            "Warning",
                            JOptionPane.YES_NO_OPTION);
                    if (selectedOption == 0) {
                        politicians.remove(j);
                        remove(labels.remove(j));
                        remove(buttons.remove(j));
                        refresh();
                    }
                }
            });
            c.gridy++;
            add(delete, c);
            add(politician, c);
        }
    }
}

这有一个问题,即列表很容易变得不同,这意味着索引不再匹配......

你可以

将每个按钮和标签映射到政治家......

class FakeMPTable extends JPanel //table using Grid Layout
{

    private List<String> politicians;
    private Map<String, JLabel> labels;
    private Map<String, JButton> buttons;

    public void refresh() {
        revalidate();
        repaint();
    }

    public FakeMPTable() {

        politicians = new ArrayList<>(25);
        for (int index = 0; index < 26; index++) {
            politicians.add(Character.toString((char) ('A' + index)));
        }

        labels = new HashMap<>(25);
        buttons = new HashMap<>(25);

        setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;

        for (int i = 0; i < politicians.size(); i++) {
            final int j = i;
            JLabel politician = new JLabel(politicians.get(j));
            JButton delete = new JButton();
            labels.put(politicians.get(j), politician);
            buttons.put(politicians.get(j), delete);
            delete.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    int selectedOption = JOptionPane.showConfirmDialog(null,
                            "Are you sure you want to delete \'" + politicians.get(j) + "\'?",
                            "Warning",
                            JOptionPane.YES_NO_OPTION);
                    if (selectedOption == 0) {
                        String key = politicians.remove(j);
                        remove(labels.remove(key));
                        remove(buttons.remove(key));
                        refresh();
                    }
                }
            });
            c.gridy++;
            add(delete, c);
            add(politician, c);
        }
    }
}

这是一个稍微好一点的解决方案,因为它将政治家名称直接映射到按钮和标签,使得列表更难以变得不同。