JCombobox,对象仅在第二次单击时发生更改(ItemListener)

时间:2019-04-28 10:47:29

标签: java swing jcombobox itemlistener

我在使用JCombobox的监听器时遇到了一些问题。 我有JCombobox和两个CercleItemOption,它们是JLabel和从CercleSelection延伸的对象JPanel的组合。 CercleSelection绘制具有特定颜色的圆圈。

所以我正在使用ItemListener支持该活动。我的目标是在框架上打印与所选项目相对应的彩色圆圈。

import javax.swing.*;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import java.awt.*;

public class PanneauSelection extends JPanel {

    private GridBagConstraints grid = new GridBagConstraints();

    public PanneauSelection(){
        super();
        init();
        setVisible(true);
    }

    private void init() {

        LineBorder lb;
        CompoundBorder cb;

        setLayout(new GridBagLayout());
        EmptyBorder eb = new EmptyBorder(5,10,5,10);

        grid.fill = GridBagConstraints.BOTH;
        grid.insets = new Insets(3,3,3,3);

        JLabel[] appLabel = {
                new JLabel("<html>Racc. <br/>Bac/conduite</html>", SwingConstants.CENTER),
                new JLabel("Vanne", SwingConstants.CENTER),
                new JLabel("Pompe", SwingConstants.CENTER),
                new JLabel("Turbine", SwingConstants.CENTER),
        };

        CercleSelection[] appCircle = {
                new CercleSelection(new Color(222, 146, 15)),
                new CercleSelection(Color.BLUE),
                new CercleSelection(new Color(67, 160, 53)),
                new CercleSelection(Color.RED),
        };

        DefaultListCellRenderer dlcr = new DefaultListCellRenderer();
        dlcr.setHorizontalAlignment(DefaultListCellRenderer.CENTER);

        JComboBox<CercleItemOption> optionList = new JComboBox<>();
        optionList.addItem(new CercleItemOption(new JLabel("Coude"), new CercleSelection(Color.cyan)));
        optionList.addItem(new CercleItemOption(new JLabel("Chgt de section"), new CercleSelection(Color.PINK)));
        optionList.setRenderer(dlcr);


        for(int i=0; i<appLabel.length; i++){
            grid.gridy = i;

            //First column
            grid.gridx = 0;
            lb = new LineBorder(appCircle[i].getCouleur(), 2, true);
            cb = new CompoundBorder(lb,eb);
            appLabel[i].setBorder(cb);
            add(appLabel[i], grid);

            //Second column
            grid.gridx = 1;
            appCircle[i].setBorder(eb);
            add(appCircle[i], grid);
        }

        grid.gridy = 4;
        grid.gridx = 0;
        add(optionList, grid);

        grid.gridx = 1;
        add(((CercleItemOption)optionList.getSelectedItem()).getCercle(), grid);

        optionList.addItemListener(itemEvent -> {
            setVisible(false);
            grid.gridx = 1;
            grid.gridy = 4;
            CercleItemOption cs = (CercleItemOption) itemEvent.getItem();
            add(cs.getCercle(), grid);
            revalidate();
            repaint();
            setVisible(true);
        });


        this.setBorder(new EmptyBorder(0,20,0,0));
    }


    public static void main(String[] args){
        JFrame f = new JFrame();
        f.add(new PanneauSelection());
        f.pack();
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);

    }

}

我期望像:
“ coude”-> [圆圈]青色
“ chgt de section”-> [圆圈]粉色

在我的代码中,ItemListener的第一次调用不会更改颜色,而第二次调用只会更改颜色。最后,第二次点击,我有:
“ coude”-> [圆圈]粉色
“ chgt de section”-> [圆圈]青色

CercleItemOption

    import javax.swing.*;

    public class CercleItemOption {
        private JLabel label;
        private CercleSelection cercle;

        public CercleItemOption(JLabel l, CercleSelection c){
            label = l;
            cercle = c;
        }

        @Override
        public String toString(){
            return label.getText();
        }

        public JLabel getLabel() {
            return label;
        }

        public CercleSelection getCercle() {
            return cercle;
        }
    }

CercleSelection

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

public class CercleSelection extends JPanel {

    public final static int TAILLE = 11;

    Color couleur;

    public CercleSelection(Color c){
        super();
        couleur = c;
        setSize(TAILLE,TAILLE);
        setVisible(true);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(couleur);
        //Draw in the middle
        g.fillOval(TAILLE/2,TAILLE/2,TAILLE,TAILLE);
    }

    public Color getCouleur() {
        return couleur;
    }

}

预先感谢您的帮助

1 个答案:

答案 0 :(得分:0)

对于遇到相同问题的人,解决方案是删除现有组件,然后将其替换为新组件。

要获取实际组件,我添加了一个新变量。

PanneauSelection类:

private CercleItemOption cercleSelectionne;

init()方法:


private void init(){

     //...

     grid.gridy = 4;
     grid.gridx = 0;
     add(optionList, grid);
     grid.gridx = 1;
     cercleSelectionne = ((CercleItemOption) optionList.getSelectedItem());
     add(cercleSelectionne.getCercle(), grid);

     optionList.addItemListener(itemEvent -> {
                remove(cercleSelectionne.getCercle());
                grid.gridx = 1;
                grid.gridy = 4;
                cercleSelectionne = (CercleItemOption) itemEvent.getItem();
                add(cercleSelectionne.getCercle(), grid);
                revalidate();
                repaint();
     });

}