[JTable] mettre un JLabel et un JButton

nayaphykit
[JTable] mettre un JLabel et un JButton

Bonjour,

j'ai beau chercher je ne trouve pas la solution à mon probleme...
je debute en swing et la je lutte!

j'ai une jtable qui est remplie dynamiquement a l'aide d'une table de ma base de donnees qui contient des messages et leurs parametres.
une des colonnes correspond a la severité du message (success, warining, fatal etc). pour chaque severite une couleur est associee (vert pour success, rouge fonce pour fatal, etc). il faut que la case correspondant a la severite contienne le mot et quelle soit coloree.

au debut j'ai tenter d'utiliser une version custom du defaultcellrenderer mais meme si la fonction etait parcourue pendant l'execution, la couleur ne changeait pas.
on m'a donc conseille de mettre un jlabel dans la jtable. et la je bloque!! ca veut pas marcher :'(

un autre truc, pour certains message il y a des sous messages qui ont le meme format mais sont stockes dans un champs du message. ces message ne sont pas affiches au debut mais il faut qu'ils puissent l'etre.
on m'a demande de mettre un + en debut de colonne pour indiquer quand il y en a et pour permettre de les afficher en dessous du "pere" (le + doit se changer en - pour les cacher)
en gros mon superviseur veut ca :
msg1 param1 txt1
msg2 param2 txt2
+msg3 param3 txt3
msg4 param4 txt4

et quand on clic sur le +
msg1 param1 txt1
msg2 param2 txt2
-msg3 param3 txt3
msg3' param3' txt3'
msg3" param3" txt3"
msg4 param4 txt4

je vous mets mon code :
messageListTable = new MessageListTable(); //je met la MessageListTable (qui extends jtable) dans un jpanel

dans la classe MessageListTable, j'ai une fonction fillListTable :

public void fillListTable(String treePathSelected) 
	{ 
		ArrayList<Message> tableContentList = new ArrayList<Message>(); 
		  
                ............ 
 
			//we begin by selecting the first elements of the table 
			tableContentList = storeTableContent.getPartOfTableContent(0, storeTableContent.getSelectionLimit() ); 
			 
			this.setModel(this.getMessageListTableModel(tableContentList)); 
			this.getModel().addTableModelListener(this); 
											     
	        this.setVisible(true); 
		}		 
	}	 
 
 
public MessageListTableModel getMessageListTableModel(ArrayList<Message> tableContentList) { 
		 
		MessageListTableModel messageListTableModel = null; 
		Message Temp = new Message();	 
		// Create the messageListTableModel 
		messageListTableModel = new MessageListTableModel(); 
		 
	 
		for(int i = 0 ; i < tableContentList.size(); i++)  
		{ 
			Temp = tableContentList.get(i); 
			JButton chaineMsg = null; 
			chaineMsg = new JButton(); 
			chaineMsg.setText(" + "); 
			chaineMsg.addActionListener(new ActionListener() { 
				public void actionPerformed(ActionEvent evt) { 
					chaineMsgActionPerformed(evt); 
				} 
			}); 
			if (Temp.getchainedMsgs()==null) 
			{ 
				chaineMsg.setVisible(false); 
			} 
			else 
				chaineMsg.setVisible(true); 
			 
			String MsgId = Temp.getmsgId(); 
			String machineName = Temp.getmachineName(); 
    		String ApplicationName = Temp.getapplicationName(); 
    		String IssuedWhen = Temp.getissuedWhen(); 
    		 
    		  
    		JLabel severity = new JLabel(); 
    		severity.setText(Temp.strSeverity[Temp.getseverity()]);    		 
    		severity.setBackground(Temp.severityColors[Temp.getseverity()][0]); 
    		severity.setOpaque(true); 
    		severity.setForeground(Temp.severityColors[Temp.getseverity()][1]); 
    		 
    		String msgText = Temp.getmsgText(); 
    		String param = Temp.getparam(); 
    					 
			messageListTableModel.addRow(chaineMsg, MsgId, machineName, ApplicationName,  
					IssuedWhen, severity, msgText, param); 
			 
		} 
	 
		return messageListTableModel; 
	}

dans cette classe j'ai aussi la classe MessageListTableModel qui extends AbstractTableModel (je ne l'a met pas car je pense pas que ce soit necessaire mais si vous la voulez dites le)

lorsque je compile, le jtable est cree et a la place du button et du jlabel il y a ecrit
javax.swing.jbutton[,0,0,0x0,invalid,alignement.......] pour le jbutton et a peu pres pareil pour le jlabel

je suis disponible s'il vous faut plus de precision
merci d'avance

Naya

fredericmazue

Quote:
au debut j'ai tenter d'utiliser une version custom du defaultcellrenderer mais meme si la fonction etait parcourue pendant l'execution, la couleur ne changeait pas.
on m'a donc conseille de mettre un jlabel dans la jtable.

Celui qui t'a dit ça est un authentique plaisantin :lol:
Les cellules des JTable contiennent des JLabel par défaut :lol:

Quote:
lorsque je compile, le jtable est cree et a la place du button et du jlabel il y a ecrit
javax.swing.jbutton[,0,0,0x0,invalid,alignement.......]

Je n'ai pas lu ton code, mais je dirais que c'est des composants qu'il faut insérer dans la table et non leur rendu sous forme de String :lol:

C'est simple de personnaliser le composant d'une cellule. Il faut implémenter l'interface TableCellRenderer et dans la méthode getTableCellRendererComponent de celle-ci, il suffit d'instancier le composant que tu veux et le retourner.

Voici un code de démonstration complet, tiré d'un article que j'ai écrit il y a bien longtemps dans Programmez!, sur l'art d'avoir une JTable bien dressée ;) Tu vas y trouver tout ce dont tu as besoin :)

package customjtable;

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import javax.swing.table.*;
import java.util.*;


class Pilote {

  private String nom;
  private String prenom;
  private String ecurie;
  private int victoires;

  Pilote(String n, String p, String e, int v) {
    nom = n;
    prenom = p;
    ecurie = e;
    victoires = v;
  }

  public void setVictoires(int v) {
    victoires = v;
  }

  public Object[] getData() {
      Object[] data = {nom, prenom, ecurie, new Integer(victoires)};
      return data;
  }
}

class PiloteModel1 extends AbstractTableModel {
  public static final String[] titres = {
      "No", "Nom", "Prénom", "Ecurie", "Titres"
  };
  private Vector pilotes;

  PiloteModel1() {
    pilotes = new Vector();
    Pilote p = new Pilote("Senna", "Ayrton", "Mac laren", 3);
    pilotes.add(p);
    p = new Pilote("Alesi", "Jean", "Prost GP", 0);
    pilotes.add(p);
    p = new Pilote("Schumacher", "Mikael", "Ferrari", 6);
    pilotes.add(p);
    p = new Pilote("Schumacher", "Ralf", "Williams", 0);
    pilotes.add(p);
    p = new Pilote("Barichello", "Rubens", "Ferrari", 0);
    pilotes.add(p);
    p = new Pilote("Prost", "Alain", "Williams", 4);
    pilotes.add(p);
  }

  public Object getValueAt(int ligne, int colonne) {
    if(getColumnName(colonne).equals(titres[0]))
      return new Integer(ligne+1);
    else
      return ((Pilote)pilotes.elementAt(ligne)).getData()[colonne-1];
  }

  public void setValueAt(Object o, int ligne, int colonne) {
    ((Pilote)pilotes.elementAt(ligne)).setVictoires(Integer.parseInt(o.toString()));
  }

  public int getColumnCount() {
    return titres.length;
  }

  public int getRowCount() {
    return pilotes.size();
  }

  public String getColumnName(int colonne)
  {
      return titres[colonne];
  }

  public void ajouterPilote () {
    pilotes.add(new Pilote("Montoya", "Pablo", "Williams", 0));
    fireTableRowsInserted(getRowCount(),getRowCount());
  }

  public void retirerPilote() {
    pilotes.removeElementAt(6);
    fireTableRowsDeleted(6,6);
  }

  public boolean isCellEditable(int ligne, int colonne) {
    return (getColumnName(colonne).equals(titres[4]));
  }
}

class SortPiloteModel extends AbstractTableModel {
  private PiloteModel1 pm;
  private int colonne_a_trier;
  private Ligne[] lignes;

  public SortPiloteModel(PiloteModel1 p) {
    pm = p;
    lignes = new Ligne[pm.getRowCount()];
    int l = lignes.length;
    for(int i=0; i<l; i++) {
      lignes[i] = new Ligne();
      lignes[i].rang = i;
    }
  }

  private void trie(int c) {
    colonne_a_trier = c;
    Arrays.sort(lignes);
    fireTableDataChanged();
  }

  public Object getValueAt(int l, int c) {
    return pm.getValueAt(lignes[l].rang, c);
  }

  public boolean isCellEditable(int l, int c) {
    return pm.isCellEditable(lignes[l].rang, c);
  }

  public void setValueAt(Object o, int l, int c) {
    pm.setValueAt(o, lignes[l].rang, c);
  }

  public String getColumnName(int c) {
    return pm.getColumnName(c);
  }

  public int getColumnCount() {
    return pm.getColumnCount();
  }

  public int getRowCount() {
    return pm.getRowCount();
  }

  public void addMouseListener(final JTable t) {
    t.getTableHeader().addMouseListener(
        new MouseAdapter()
        {
          public void mouseClicked(MouseEvent e) {
            int col = t.columnAtPoint(e.getPoint());
            col = t.convertColumnIndexToModel(col);
            trie(col);
          }
        });
    }

  private class Ligne implements Comparable {
    private int rang;
    public int compareTo(Object l) {
      Ligne ligne_courante = (Ligne)l;
      Object a = pm.getValueAt(rang, colonne_a_trier);
      Object b = pm.getValueAt(ligne_courante.rang, colonne_a_trier);
      // On suppose que tous les objets sont "comparables"
      if(getColumnName(colonne_a_trier).equals(PiloteModel1.titres[4])) {
        return ((Comparable)b).compareTo(a);
      }
      else
        return ((Comparable)a).compareTo(b);
    }
  }
}

class MonTableCellRenderer implements TableCellRenderer {
  public Component getTableCellRendererComponent(JTable table,
    Object value, boolean isSelected, boolean hasFocus, int ligne, int colonne) {
    if(table.getColumnName(colonne).equals(PiloteModel1.titres[0])) {
      label.setHorizontalAlignment(SwingConstants.CENTER);
    }

    // JLable est transparent pas défaut
    label.setOpaque(true);

    if((ligne % 2) == 0)
      label.setBackground(Color.cyan);
    else
      label.setBackground(Color.pink);

    label.setText(value.toString());

    return label;
  }

  private JLabel label = new JLabel();
}

public class CustomJTable extends JFrame {
  boolean ajout;
  JScrollPane jScrollPane1 = new JScrollPane();
  PiloteModel1 pm = new PiloteModel1();
  SortPiloteModel spm = new SortPiloteModel(pm);
  JTable jTable1 = new JTable(spm);

  public CustomJTable() throws HeadlessException {
    try {
      jbInit();
      spm.addMouseListener(jTable1);
      jTable1.setDefaultRenderer(Object.class,
                                 new MonTableCellRenderer());
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }
  public static void main(String[] args) throws HeadlessException {
    CustomJTable jtd = new CustomJTable();
    jtd.setTitle("En technicolor");
    jtd.setSize(300, 200);
    jtd.setVisible(true);
  }
  private void jbInit() throws Exception {
    this.addWindowListener(new java.awt.event.WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        this_windowClosing(e);
      }
    });
    jTable1.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    this.getContentPane().add(jScrollPane1, BorderLayout.CENTER);
    jScrollPane1.getViewport().add(jTable1, null);
  }

  void this_windowClosing(WindowEvent e) {
    System.exit(0);
  }
}
nayaphykit

youpi!!!!! ca marche !!
merci beaucoup.
j'ai donc bien la couleur comme je le veux ^^

en fait quand j'avais essaye le cellrenderer je l'avais mal utilise :s

j'ai encore une tite question : est il possible de mettre un bouton dans une colonne de la jtable ?
si oui peux tu m'expliquer comment faire ?

(si c'est pas possible je ferais une finte avec les cases a cocher et les evenement clic, mais si c'est possible mon superviseur prefererais)

merci
Naya

fredericmazue

Quote:
ca marche !!

J'aurais bien voulu voir le contraire ;)

Quote:
j'ai encore une tite question : est il possible de mettre un bouton dans une colonne de la jtable ?

Oui :)

Quote:
si oui peux tu m'expliquer comment faire ?

Non... ;)
Car tu le sais déjà. :)
Je te l'ai déjà dit. Si au lieu d'instancier un JLabel dans getTableCellRendererComponent de TableCellRenderer, tu instancies un JButton, tu auras alors un JButton dans la case.

Allez un petit exemple parce que c'est toi

class MonTableCellRenderer implements TableCellRenderer { 
  public Component getTableCellRendererComponent(JTable table, 
    Object value, boolean isSelected, boolean hasFocus, int ligne, int colonne) { 
    
    button.set.... // etc, je configure mon JButton 

    return button; 
  } 

  private JButton button = new JButton("Je m'abonne à Programmez!"); 
} 
nayaphykit

Yatta !!!! lol (non je regarde pas trop Heroes :P)

ca marche tout bien tout nickel, j'ai mes boutons quand necessaire dans la 1ere colonne et mes jlabel en couleur dans la 4eme !! c'est top

merci beaucoup :D