JCombobox, объект изменен только при втором клике (ItemListener) - PullRequest
0 голосов
/ 28 апреля 2019

У меня возникла проблема с использованием слушателя 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 голосов
/ 30 апреля 2019

Для тех, у кого такая же проблема, было решение удалить существующий компонент и заменить его новым.

Чтобы получить фактический компонент, я добавляю новую переменную.

Класс 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();
     });

}
...