Question

I've got some kind of a problem regarding my code and I would appreciate any insight on this.

First, here's some context (on the following code) : The primary objects, which can be selected in the left column's combo box editors, each have their own data set containing objects of the same type to be used for later comparisons and manipulations. The right column's editors (again combo boxes) update to display this data set. However, the first element in the list is supposed to stand in as the option to add a new element to said list, and when it is selected (actionEvent), the new data object is created, but as soon as the combobox is re-selected, it creates and displays another data object.

This code represents the basic structure of the part of my application that generates the problem and I have trimmed it (as much as I can) to the essential in as much of an SSCCE format as I can. Some objects are still using their french names, I can change them if you don't understand their purpose. The previous paragraph explains a lot, although if you want precisions I'll gladly proceed.

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.border.EmptyBorder;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import javax.swing.JScrollPane;


public class TestApp extends JFrame {

    private JPanel contentPane;
    private CustomTable table;
    private JComboBox<GeneralPrimaryObject> selecteurObjets = new JComboBox<GeneralPrimaryObject>();

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    TestApp frame = new TestApp();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public TestApp() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setBounds(42, 46, 350, 103);
        contentPane.add(scrollPane);

        selecteurObjets.addItem(new FirstSubClass());

        table = new CustomTable();
        table.setModel(new DefaultTableModel(
                new Object[][] {
                    {null, ""},
                    {null, null},
                    {null, null},
                    {null, null},
                    {null, null},
                },
                new String[] {
                    "Primary object", "Sublist from object"
                }
            ));
        scrollPane.setViewportView(table);
        table.getColumnModel().getColumn(1).setPreferredWidth(105);
        table.setRowHeight(15);
        TableColumn colonneObjets = table.getColumnModel().getColumn(0);
        colonneObjets.setCellEditor(new DefaultCellEditor(selecteurObjets));
        table.getModel().addTableModelListener(new TableModelListener(){
            private static final int COLONNE_OBJETS = 0;
            private GeneralPrimaryObject previousObject;
            @Override
            public void tableChanged(TableModelEvent e) {
                int row = e.getFirstRow();
                int col = e.getColumn();
                JComboBox<GeneralPrimaryObject> editor = new JComboBox<GeneralPrimaryObject>();
                GeneralPrimaryObject confirmedObject;
                Object value;
                ArrayList<GeneralPrimaryObject> objects;
                //new object standing in for the "New data set..." item
                FirstSubClass newObjectStandIn = new FirstSubClass();

                newObjectStandIn.setName("New data set...");
                previousObject = newObjectStandIn;
                TableModel modele = (TableModel)e.getSource();
                value = modele.getValueAt(row, col);
                if(col == COLONNE_OBJETS && value != null){
                    confirmedObject = (GeneralPrimaryObject)value;
                    objects = confirmedObject.getData();
                    for(GeneralPrimaryObject o : objects){
                        System.out.println("Fuck");
                        editor.addItem(o);
                    }
                    editor.addItem(newObjectStandIn);
                    editor.addItemListener(new ItemListener(){

                        @Override
                        public void itemStateChanged(ItemEvent e) {
                            if(e.getStateChange() == ItemEvent.SELECTED){

                            }
                        }

                    });

                    editor.addActionListener(new ActionListener(){

                        @Override
                        public void actionPerformed(ActionEvent e) {

                            JComboBox<GeneralPrimaryObject> source = (JComboBox<GeneralPrimaryObject>) e.getSource();

                            GeneralPrimaryObject object = null, objetSelectionne = (GeneralPrimaryObject)source.getSelectedItem();
                            String nom = "Data set " + (source.getItemCount());
                            previousObject.equals(objetSelectionne);




                            if(source.getSelectedIndex() == 0){
                                    switch(objetSelectionne.getType()){
                                    case FIRSTSUB:
                                        object = new FirstSubClass();
                                        object.setName(nom);
                                        break;
                                    case SECONDSUB:
                                        object = new SecondSubClass();
                                        object.setName(nom);
                                        break;
                                    default:
                                        break;

                                    }



                            }
                            if(object != null){
                                System.out.println("Flag1");
                                source.addItem(object);
                                source.setSelectedItem(object);

                            }
                        }

                    });
                    table.addEditor(editor, row);
                }

            }

        });
    }
    private class CustomTable extends JTable{
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private ArrayList<TableCellEditor> editors = new ArrayList<TableCellEditor>(8);

        public CustomTable(){
            super();
            editors.ensureCapacity(8);
            for (int i = 0; i < 8; i++) {
                editors.add(null);
            }
        }

        /*@Override
        public TableCellRenderer getCellRenderer(int row, int column){
            if(row == 1 && editeurs.size() > row && editeurs.get(row) != null) {
                return editeurs.get(column).;
            }
            return super.getCellRenderer(row, column);
        }
        */

        @Override
        public TableCellEditor getCellEditor(int row, int column){

                int modelColumn = convertColumnIndexToModel( column );

                if (modelColumn == 1 && row < 8){
                    return editors.get(row);
                }else{
                    return super.getCellEditor(row, column);
                }
        }

        public void addEditor(JComboBox<GeneralPrimaryObject> newEditor, int row){
            editors.set(row, new DefaultCellEditor(newEditor));

            this.repaint();
        }
    }
    private abstract class GeneralPrimaryObject{
        protected String name;
        protected ObjectType type;
        private ArrayList<GeneralPrimaryObject> data = new ArrayList<GeneralPrimaryObject>();

        private GeneralPrimaryObject(){

        }

        public abstract String getName();
        public abstract void setName(String name);
        public abstract ObjectType getType();

        public ArrayList<GeneralPrimaryObject> getData(){
            return data;
        }

        public String toString(){
            return this.name;
        }
    }
    private class FirstSubClass extends GeneralPrimaryObject{
        public FirstSubClass(){
            super();
            setName("SubclassObject");
            this.type = ObjectType.FIRSTSUB;
        }
        @Override
        public String getName() {
            return this.name;
        }
        @Override
         public void setName(String name) {

            this.name = name;
        }
        @Override
        public ObjectType getType() {

            return this.type;
        }

    }
    private class SecondSubClass extends GeneralPrimaryObject{
        public SecondSubClass(){
            super();
            setName("OtherSubclassObject");
            this.type = ObjectType.SECONDSUB;
        }
        @Override
        public String getName() {
            return this.name;
        }
        @Override
         public void setName(String name) {

            this.name = name;
        }
        @Override
        public ObjectType getType() {

            return this.type;
        }

    }
    private enum ObjectType{
        FIRSTSUB, SECONDSUB;
    }
}

I've been playing around with both ItemListeners and ActionListeners and can't seem to figure out what the problem is. It may be simple, but I've been on this problem for quite some time and I think this means I need to get a fresh pair of eyes on this, or else I'll be searching for quite some time.

Oh, and this question : Why is itemStateChanged on JComboBox is called twice when changed? doesn't seem to solve the problem (maybe I'm wrong).

Anyways, thanks for any replies!

Was it helpful?

Solution

the first element in the list is supposed to stand in as the option to add a new element to said list, and when it is selected (actionEvent),

Not sure I understand the problem, but I would suggest you should not be using an ActionListener (or ItemListener on the combo box.

Instead I would try adding a TableModelListener to the TableModel. When the "New Data Set..." is selected the model will be updated. So in the TableModelListener you can create the next data set and add the data set to the editor.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top