Différents composants dans un colonnes de JTable [Résolu]

Signaler
Messages postés
40
Date d'inscription
mardi 26 mai 2009
Statut
Membre
Dernière intervention
14 août 2012
-
Darf33
Messages postés
40
Date d'inscription
mardi 26 mai 2009
Statut
Membre
Dernière intervention
14 août 2012
-
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

Messages postés
600
Date d'inscription
samedi 20 mai 2006
Statut
Membre
Dernière intervention
8 juillet 2016
8
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
Messages postés
600
Date d'inscription
samedi 20 mai 2006
Statut
Membre
Dernière intervention
8 juillet 2016
8
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?
Messages postés
40
Date d'inscription
mardi 26 mai 2009
Statut
Membre
Dernière intervention
14 août 2012

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 :
Messages postés
40
Date d'inscription
mardi 26 mai 2009
Statut
Membre
Dernière intervention
14 août 2012

Oups c'est mieux avec le lien ><
> Image du Tableau
Messages postés
600
Date d'inscription
samedi 20 mai 2006
Statut
Membre
Dernière intervention
8 juillet 2016
8
comment sais-tu quels type de composant tu dois mettre ? sur quoi te bases-tu pour mettre une combo, une checkbox, ...?
Messages postés
40
Date d'inscription
mardi 26 mai 2009
Statut
Membre
Dernière intervention
14 août 2012

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());
}
}
Messages postés
40
Date d'inscription
mardi 26 mai 2009
Statut
Membre
Dernière intervention
14 août 2012

Merci infiniment !
Il y a effectivement quelques petites modifications à effectuer mais c'est exactement sur ça que je buchais
Messages postés
600
Date d'inscription
samedi 20 mai 2006
Statut
Membre
Dernière intervention
8 juillet 2016
8
mais de rien, c'est la raison d'être de cet endroit ^^
Messages postés
40
Date d'inscription
mardi 26 mai 2009
Statut
Membre
Dernière intervention
14 août 2012

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 ?
Messages postés
600
Date d'inscription
samedi 20 mai 2006
Statut
Membre
Dernière intervention
8 juillet 2016
8
as-tu implémenté la méthode isCellEditable dans ton table model?
Messages postés
40
Date d'inscription
mardi 26 mai 2009
Statut
Membre
Dernière intervention
14 août 2012

oui j'ai dû l'implémenté afin de ne pouvoir rendre éditable que la dernière colonne.
Messages postés
600
Date d'inscription
samedi 20 mai 2006
Statut
Membre
Dernière intervention
8 juillet 2016
8
et comment lies tu ton implémentation du tableCellEditor à ta jtable?
Messages postés
40
Date d'inscription
mardi 26 mai 2009
Statut
Membre
Dernière intervention
14 août 2012

comme ça :

getColumnModel().getColumn(2).setCellEditor(new MyCellEditor());
Messages postés
600
Date d'inscription
samedi 20 mai 2006
Statut
Membre
Dernière intervention
8 juillet 2016
8
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??
Messages postés
40
Date d'inscription
mardi 26 mai 2009
Statut
Membre
Dernière intervention
14 août 2012

oui. Elles le sont avant que je les sélectionne et elles le restent après leurs dé-sélections
Messages postés
40
Date d'inscription
mardi 26 mai 2009
Statut
Membre
Dernière intervention
14 août 2012

Est-ce qu'utiliser un Listener sur mes cellules peut être une solution envisageable ou juste une perte de temps ?
Messages postés
40
Date d'inscription
mardi 26 mai 2009
Statut
Membre
Dernière intervention
14 août 2012

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;
}
}
Messages postés
40
Date d'inscription
mardi 26 mai 2009
Statut
Membre
Dernière intervention
14 août 2012

Bon problème résolu. J'ai refais mes méthodes en m'inspirant de cette exemple :multiple Component Table 2: checkbox