Custom JTable/JComboBox component opvullen

Status
Niet open voor verdere reacties.

Virusbeatboxing

Gebruiker
Lid geworden
11 nov 2011
Berichten
41
Beste,

ik heb in mijn programma nood aan component waarbij men, net zoals bij een JTable, rijen kan toevoegen. Deze component bestaat uit 2 kolommen. Wat er zo speciaal is aan deze component is dat deze in elke cel een JComboBox moet hebben. Daarom ontwikkelde ik zo een component op basis van TableCellRenderers.

Ik maak ten eerste een JTable met een DefaultTableModel:

Code:
model = new DefaultTableModel();
table = new JTable(model);
table.setRowHeight(23);
table.setRowSelectionAllowed(true);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

// Add some columns
model.addColumn("Recipient", new Object[] {});
model.addColumn("Role", new Object[] {});

Vervolgens voeg ik aan elke kolom mijn custom made CellRenderer en CellEditor toe:
Code:
TableColumn recipientsColumn = table.getColumnModel().getColumn(0);
recipientsColumn.setCellEditor(new MyComboBoxEditor(recipients));
recipientsColumn.setCellRenderer(new MyComboBoxRenderer(recipients));

TableColumn rolesColumn = table.getColumnModel().getColumn(1);
rolesColumn.setCellEditor(new MyComboBoxEditor(roles));
rolesColumn.setCellRenderer(new MyComboBoxRenderer(roles));

Hier is de code van deze Renderer en Editor:
Code:
public class MyComboBoxRenderer extends JComboBox implements TableCellRenderer {
		public MyComboBoxRenderer(Object[] items) {
			super(items);
		}

		public Component getTableCellRendererComponent(JTable table,
				Object value, boolean isSelected, boolean hasFocus, int row,
				int column) {
			if (isSelected && hasFocus) {
				if (value != null) {
					if (value instanceof User) {
						User u = (User) value;
						model.setValueAt(roles[u.getRoleID() - 1], row,column + 1);
					}
				}
				super.setBackground(table.getSelectionBackground());
			} else {
				setForeground(table.getForeground());
				setBackground(table.getBackground());
			}

			// Select the current value
			setSelectedItem(value);
			return this;
		}
	}
	public class MyComboBoxEditor extends DefaultCellEditor {
		public MyComboBoxEditor(Object[] items) {
			super(new MyComboBoxRenderer(items));
		}
	}

U vraagt zich waarschijnlijk af wat mijn probleem is? Wel het zit zo. Een gebruiker kan een x-aantal rijen aan deze component toevoegen. Elke rij bevat een JComboBox en de waarden in deze JComboBox zijn ook de juiste. De gebruiker kan zonder enige problemen zijn keuze maken.
Vervolgens kan hij ook deze waarden opslaan in de database.

Later moeten deze waarden uit de database gehaald worden waarmee de component moeten opgevuld worden. Het enige probleem is nu, hoe vul ik de JComboBoxen in deze component op? Ik heb reeds alles geprobeerd.

Ik probeerde reeds om door elke cell te loopen in deze component en van elke cell de renderer en editor op te vragen, te parsen naar een JComboBoxModel en vervolgens de .setSelectedItem() hiervan op te roepen. Zie de code: (geen 100% clean code maar is gewoon om te testen)
Code:
MyComboBoxRenderer mcbr = null;
		int teller = 0;
		for(int row = 0; row < model.getRowCount(); row++)
		{
			for(int column = 0; column < model.getColumnCount(); column++)
			{
				mcbr = (MyComboBoxRenderer) table.getCellRenderer(row, column);
				if(column == 0)
					mcbr.getModel().setSelectedItem(rolesList.get(teller));
				if(column == 1)
					mcbr.getModel().setSelectedItem(rolesList.get(teller+1));
			}
			teller+=2;
		}

Alles zonder enige succes! JComboBoxen blijven leeg.

Kan iemand mij een suggestie geven? Alvast HARTELIJK bedankt!
 
Bekijk volgende code eens zal niet werken als je andere files niet van path zie header download
Het lijkt weinig spectaculaire maar het doet meer of je zou vermoeden
Code:
/**
* @author Lieven Roegiers
* @copyright 2011
* @from JAVA_mylibs			 http://code.google.com/p/javamylibs/
* @version java 1.4+
*/
public class OptionsTableModel extends AbstractTableModel {
	private static final long serialVersionUID = 1L;
	private static ResourceBundle translations;
	private Vector keys = new Vector();
    private Vector values = new Vector();
    private Vector datatype = new Vector();
	private Projectsettings settingstest;
    private static final String columnNames[] = {"key", "Value","type" };
    public int getColumnCount() {
      return columnNames.length;
    }
    /**
     * @param settings
     */
    public OptionsTableModel(Projectsettings settings) {
		settingstest = settings;
    	setdata(settingstest.gethashtable());
	}
    /**
     * @param settings
     * @param translationsPropertieFileName
     */
    public OptionsTableModel(Projectsettings settings,String translationsPropertieFileName) {
    	translations = ResourceBundle.getBundle(translationsPropertieFileName);
		settingstest = settings;
		setdatatranslated(settingstest.gethashtable());
	}
    /*
     *  (non-Javadoc)
     * @see javax.swing.table.AbstractTableModel#getColumnName(int)
     */
    public String getColumnName(int column) {
      return columnNames[column];
    }
    /* (non-Javadoc)
     * @see javax.swing.table.TableModel#getRowCount()
     */
    public int getRowCount() {
      return keys.size();
    }
    /* (non-Javadoc)
     * @see javax.swing.table.TableModel#getValueAt(int, int)
     */
    public Object getValueAt(int row, int column) {
      Object returnValue=null;
      log(Level.ALL, "<ERROR: getValueAt>ArrayIndexOutOfBoundsException Projectsettings properties emty"+row+column );
      try {
	      if (column == 0) {
	        returnValue = keys.elementAt(row);
	      } else if (column == 1) {
	        returnValue = values.elementAt(row);
	      } else if (column == 2) {
	    	  if (Statics.DEBUG){
	    		  returnValue = datatype.elementAt(row);
	    	  }
		  }
      }catch(ArrayIndexOutOfBoundsException ae){
    	  log(Level.ALL, "<ERROR: getValueAt>ArrayIndexOutOfBoundsException Projectsettings properties emty");
      }catch(Exception e){
    	  log(Level.FINEST, "<ERROR: getValueAt> <FINEST>"+e+"</FINEST>");
      }
      return returnValue;
    }
    /**
     * 
     */
    private void init(){
    	keys.removeAllElements();
    	values.removeAllElements();
    	datatype.removeAllElements();
    }
    /* (non-Javadoc)
     * @see javax.swing.table.AbstractTableModel#getColumnClass(int)
     */
    public Class getColumnClass(int c) {
    	if(Statics.FOLLOW){log(Level.WARNING, "colom:"+c);};
        return getValueAt(0, c).getClass();
    }
    public boolean isCellEditable(int row, int col) {
        //Note that the data/cell address is constant,
        //no matter where the cell appears onscreen.
        if (col != 1) {
            return false;
        } else {
            return true;
        }
    }
    public void setValueAt(Object value, int row, int col) {
        if (Statics.DEBUG){log(Level.FINE, "<SET VALUE> <POS:"+row+","+col+"|TO:"+value+"//"+value.getClass()+">");}
        try{
            values.set(row, value);
            String key = (String)keys.get(row);
            settingstest.setProperty(key, value.toString());
            fireTableCellUpdated(row, col);

            //fireTableCellUpdated(row, col);
        }catch(Exception e){
        	log(Level.ALL, "<ERROR: SET VALUEAT> <POS:"+row+","+col+"|KEY:"+keys.get(row).toString()+"TO:"+value+"//"+value.getClass()+">");
        	printDebugData();
        	log(Level.FINEST, "<ERROR: setValueAt> <FINEST>"+e+"</FINEST>");
        }
        if (Statics.DEBUG) {log(Level.FINE,"<NEW VALUE>");printDebugData();}
    }
	private static  void log(Level level, String msg ){
	    String tag ="<>>>>*"+Statics.LIBNAME+"-"+Statics.COPYRIGHTBY+"*<<<<>StreamManipulator";
	    Logger.getLogger(OptionsTableModel.class.getName()).log(level, tag + msg);
	}
    private void printDebugData() {
        int numRows = getRowCount();
        int numCols = getColumnCount();
        log(Level.FINEST,"-<start>-");
        for (int i=0; i < numRows; i++) {
            log(Level.FINEST,"    row " + i + ":");
            for (int j=0; j < numCols; j++) {
                log(Level.FINEST," + data[i][j]");
            }  
        }
        log(Level.FINEST,"-<end>-");
    }
    private synchronized void setdata(Hashtable<Object, Object> table) {
        Set set = table.entrySet();
        Iterator it = set.iterator();
        init();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            keys.addElement( entry.getKey());
            Object val =entry.getValue();
            values.addElement(val);
            datatype.addElement(val.getClass().getName());
       }
       fireTableDataChanged();
    }
    private synchronized void setdatatranslated(Hashtable<Object, Object> table) {
        Set set = table.entrySet();
        Iterator it = set.iterator();
        init();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            keys.addElement(translations.getString((String)entry.getKey()));
            Object val =entry.getValue();
            values.addElement(val);
            datatype.addElement(val.getClass().getName());
       }
       fireTableDataChanged();
    }
}
 
Status
Niet open voor verdere reacties.

Nieuwste berichten

Terug
Bovenaan Onderaan