Différents composants dans un colonnes de JTable

Résolu
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012 - 28 juin 2012 à 10:42
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012 - 20 juil. 2012 à 11:55
Bonjour,

je chercher à mettre différents composants dans une colonne. Je doit afficher différentes données sur la colonne d'index 2 par exemple avec :
en ligne 1 une JCheckBox
en ligne 2 une JComboBox
en ligne 3 une JTextField

Après pas mal de recherche je ne trouve malheureusement pas de solution pour modifier le type de cellule de chaque ligne.

J'ai vu que la méthode getTableCellRendererComponent pouvait permettre de définir le type de composant mais que d'un seul

Vous avez une idée ? merci

18 réponses

cormandyr Messages postés 600 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 8 juillet 2016 11
28 juin 2012 à 13:29
oui ainsi que l'implémentation de setValueAt pour ton tableModel:

public class MyCellRenderer extends AbstractCellEditor implements TableCellEditor {

public MyCellRenderer () {}

@Override
public Object getCellEditorValue() {
if (_editor != null) {
if (_editor instanceof JCheckBox) {
return ((JCheckBox) _editor).isSelected();
} else if (_editor instanceof JComboBox) {
return ((JComboBox) _editor).getSelectedItem();
} else if (_editor instanceof JTextField) {
return ((JTextField) _editor).getText();
}
}
return null;
}

@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
switch( row ) {
case 0:
_editor = new JCheckBox("",Boolean.parseBoolean(value.toString()));
break;
case 1:
_editor = new JComboBox(new String[]{"None", "LSB", "MSB"});
break;
default:
_editor = new JTextField(value.toString());
break;
}
return _editor;
}

private JComponent _editor;
}



ou un truc du genre
3
cormandyr Messages postés 600 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 8 juillet 2016 11
28 juin 2012 à 11:01
Salut,

en théorie, toutes les lignes de ta table ont le meme comportement, les memes types de composants...
pourquoi désires-tu avoir des composants différents pour représenter la meme donnée?
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
28 juin 2012 à 11:16
En fait je dois afficher des options pour du traitement de variable et chaque ligne affiche des données différentes. Soit une valeur true/false, une liste déroulante ou une zone de saisie.

Voici l'image de mon tableau actuellement :
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
28 juin 2012 à 11:18
Oups c'est mieux avec le lien ><
> Image du Tableau
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cormandyr Messages postés 600 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 8 juillet 2016 11
28 juin 2012 à 11:34
comment sais-tu quels type de composant tu dois mettre ? sur quoi te bases-tu pour mettre une combo, une checkbox, ...?
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
28 juin 2012 à 11:51
Dans un premier temps je le détermine suivant la position de la cellule.

J'ai réussi à mettre les différents composants mais lorsque je veux les modifier (par exemple sélection/dé-sélection de la CheckBox, choix dans la ComboBox) ça ne marche pas. J'imagine que je doit utiliser une autre méthode pour permettre l'édition.
Voici le bout de code permettant de définir le type de composant :

private class MyCellRenderer implements TableCellRenderer {

public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int col) 
{
     if(row 0 && col 2) {
    	 JCheckBox cb = new JCheckBox();
 cb.setSelected((Boolean.valueOf((String)obj).booleanValue()));
 return cb;
     }
     if(row 1 && col 2) {
    	 comboBoxLsbMsb = new JComboBox(new String[]{"None", "LSB", "MSB"});
    	 return comboBoxLsbMsb;
     }
     if(row 2 && col 2) {
    	 JTextField tf = new JTextField();
    	 tf.setText((String)obj);
    	 return tf;
     }
     return new JTextField(obj.toString());
}
}
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
28 juin 2012 à 15:10
Merci infiniment !
Il y a effectivement quelques petites modifications à effectuer mais c'est exactement sur ça que je buchais
0
cormandyr Messages postés 600 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 8 juillet 2016 11
28 juin 2012 à 15:16
mais de rien, c'est la raison d'être de cet endroit ^^
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
29 juin 2012 à 11:04
Re-bonjour,

j'ai maintenant un petit problème d'affichage (enfin un souci d'esthétisme).

Mes cellules contenants les composants JTextField et JComboBox sont constamment en mode édition.
image.

En cherche sur le net j'ai trouvé des personnes parlant des méthodes putClientProperty()et stopCellEditing() mais sans succès.

Une idée vers quelle solution je doit m'orienter ?
0
cormandyr Messages postés 600 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 8 juillet 2016 11
29 juin 2012 à 11:29
as-tu implémenté la méthode isCellEditable dans ton table model?
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
29 juin 2012 à 13:15
oui j'ai dû l'implémenté afin de ne pouvoir rendre éditable que la dernière colonne.
0
cormandyr Messages postés 600 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 8 juillet 2016 11
29 juin 2012 à 13:59
et comment lies tu ton implémentation du tableCellEditor à ta jtable?
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
29 juin 2012 à 14:16
comme ça :

getColumnModel().getColumn(2).setCellEditor(new MyCellEditor());
0
cormandyr Messages postés 600 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 8 juillet 2016 11
29 juin 2012 à 14:45
comme ça, je dois dire que je ne vois pas, chez moi, je n'ai pas le moindre soucis...
des le départ elles sont en mode d'édition??
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
29 juin 2012 à 15:00
oui. Elles le sont avant que je les sélectionne et elles le restent après leurs dé-sélections
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
29 juin 2012 à 17:46
Est-ce qu'utiliser un Listener sur mes cellules peut être une solution envisageable ou juste une perte de temps ?
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
19 juil. 2012 à 09:02
Bon je reviens sur ce problème toujours non résolu .
J'ai trouvé des solutions comme l'ajout d'un Listener dans mon constructeur

this.addFocusListener(new FocusAdapter() {
    @Override
    public void focusLost(FocusEvent e) {
        ((JTable)e.getSource()).getSelectionModel().clearSelection();
    }
});


Ou la dé-sélection de toutes les cellules

table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(false);
    table.clearSelection();


Mais aucune des 2 ne marchent...

Si ça peut aider à comprendre mon problème voici ma classe :
public class TypeConfig extends JTable implements ActionListener, MouseListener, Table
{
/**
 * @serial Generated value {@value VarConfig#serialVersionUID} 

 */
private static final long serialVersionUID = -357661060467107577L;

/**
 * Menu which appear when right clicking the panel
 */
private ClickMenu clickMenu;
/**
 * TableModel which contain all data
 */
private TableModel tableModel;
/**
 * Editable JTable containing tableModel
 */
private JTable table;
/**
 * Parent frame
 */
private Window window;
/**
 * TypeDescription
 */
private TypeDescription typeDescription;
/**
 * Used for combo box for LsbMsb
 */
private JComboBox comboBoxInteger = new JComboBox(new String[]{"Lsb", "Msb"});
/**
 * Type of data
 */
private String type;
@Getter
public boolean isCellEditable(int row, int col) {
if (col == 2)
return true;
else return false;
}	

/**
 * Main constructor

 * Create a new table from tb and set its ClickMenu
 * 
 * @param tb_type TableModel corresponding to TypeDescription
 * @param typeDescription TypeDescription
 * @param window Main frame
 * @param type return the type of data
 */
public TypeConfig(TableModel tb_type, TypeDescription typeDescription, Window window, String type)
{
super(tb_type);
tableModel = tb_type;
this.typeDescription = typeDescription;
this.window = window;
this.type = type;


//JTable table = new JTable(tb_type);

setFillsViewportHeight(true);
                addMouseListener(this);

TableColumn col = getColumnModel().getColumn(0);
col.setMaxWidth(25);			

getColumnModel().getColumn(2).setCellRenderer(new MyCellRenderer());
getColumnModel().getColumn(2).setCellEditor(new MyCellEditor());


setAutoCreateRowSorter(true);
clickMenu = new ClickMenu(this);
}

/**
 * Modify display to have JCheckbox, JCombobox, JTextField
 */
private class MyCellRenderer implements TableCellRenderer {

public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int col) 
{
if(obj.toString().equalsIgnoreCase("true") || obj.toString().equalsIgnoreCase("false")) {
    	 JCheckBox cb = new JCheckBox();
    	 cb.setHorizontalAlignment(SwingConstants.CENTER);
    	 cb.setBackground(Color.WHITE); 

    	 if(obj instanceof String)
    		 cb.setSelected((Boolean.valueOf((String)obj).booleanValue()));
    	 else if(obj instanceof Boolean)
    		 cb.setSelected((Boolean)obj);

 return cb;
     }
     if(obj.toString().equalsIgnoreCase("Lsb") || obj.toString().equalsIgnoreCase("Msb")) {
    	 comboBoxInteger.setSelectedItem(obj);
    	 return comboBoxInteger;
     }
     if(obj == NumberFormat.getNumberInstance()) {
    	 JTextField tf = new JTextField();
    	 tf.setText((String)obj);
    	 return tf;
     }
     return new JTextField(obj.toString());
}
}
/**
 * Modify edition of JCheckbox, JCombobox, JTextField
 */		
public class MyCellEditor extends AbstractCellEditor implements TableCellEditor {

private static final long serialVersionUID = -8869990909839956264L;

private JComponent editor;


public MyCellEditor () {}

@Override
public Object getCellEditorValue() {
if (editor != null) {
if (editor instanceof JCheckBox) {
return ((JCheckBox) editor).isSelected();
} else if (editor instanceof JComboBox) {
return ((JComboBox) editor).getSelectedItem();
} else if (editor instanceof JTextField)
return ((JTextField) editor).getText();
}
return null;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
int type = 100;

if(value.toString().equalsIgnoreCase("true") || value.toString().equalsIgnoreCase("false"))
type = 0;
if(value.toString().equalsIgnoreCase("Lsb") || value.toString().equalsIgnoreCase("Msb"))
type = 1;
    if(value == NumberFormat.getNumberInstance()) 
    	type = 2;


switch( type ) {
case 0:
editor = new JCheckBox("",Boolean.parseBoolean(value.toString()));
((AbstractButton) editor).setHorizontalAlignment(SwingConstants.CENTER);
editor.setBackground(Color.WHITE); 
break;
case 1:
editor = comboBoxInteger;
break;
default:
editor = new JTextField(value.toString());
break;
}
return editor;
}
}

/**
 * Action event

 	 * For popup menu events :

 * If the user click on Add, a new row is created and added to the table 

 * Else if he click on Save, the configuration is saved 

 * Else if he click on Delete, the selected row is removed from the table 

 * 

 * @param ae The ActionEvent
 */
@Override
public void actionPerformed(ActionEvent ae) {
// Auto-generated method stub
if (ae.getSource() instanceof JMenuItem)
{
JMenuItem item = (JMenuItem)ae.getSource();
if (item.getText() == "Add")
{
if(type.equalsIgnoreCase("integer"))
{			
Object data1[] = {"Signed", "false"};
tableModel.addRow(data1);
Object data2[] = {"Significant bit", "Lsb"};
tableModel.addRow(data2);
Object data3[] = {"Value significant bit", "1"};
tableModel.addRow(data3);
}
}
else if (item.getText() == "Save")
{
typeDescription.resetDatas(tableModel);
window.queueEvent(ae, this);
}
else if (item.getText() == "Delete" && getSelectedRow() != -1)
{
int rows[] = getSelectedRows();
Arrays.sort(rows);
int i = rows.length;
while (--i >= 0)
tableModel.deleteRow(rows[i]);
}
else
window.queueEvent(ae, this);
}
}

/**
 * MouseEvent

 * Show the popup menu if right click 

 * 
 * @param me the MouseEvent
 * 
 * @see MouseEvent
 */
@Override
public void mouseClicked(MouseEvent me) {
// Auto-generated method stub
if (me.getClickCount() 1 && me.getButton() 3 && me.getSource() instanceof JTable)
clickMenu.show(me.getComponent(), me.getX(), me.getY());
}

/**
 * Not use
 */
@Override
public void mouseEntered(MouseEvent arg0) {
// Auto-generated method stub

}

/**
 * Not use
 */
@Override
public void mouseExited(MouseEvent arg0) {
// Auto-generated method stub

}

/**
 * Not use
 */
@Override
public void mousePressed(MouseEvent arg0) {
// Auto-generated method stub

}

/**
 * Not use
 */
@Override
public void mouseReleased(MouseEvent arg0) {
// Auto-generated method stub

}

@Getter
@Override
public TableModel getTableModel()
{
// Auto-generated method stub
return tableModel;
}

@Getter
@Override
public JTable getJTable()
{
// Auto-generated method stub
return this;
}
}
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
20 juil. 2012 à 11:55
Bon problème résolu. J'ai refais mes méthodes en m'inspirant de cette exemple :multiple Component Table 2: checkbox
0
Rejoignez-nous