Je tente actuellement de mettre en œuvre un JPopupMenu dans mon JTable qui permet le déblocage d'une cellule pour le montage en utilisantTableModel setCellEditable et réglage automatique de la valeur à false
@Override
public void actionPerformed(ActionEvent e){
if(e.getActionCommand() == "Unlock"){
pTableModel.setCellEditable(this.getSelectedRow(), this.getSelectedColumn(), true);
}
}
Cette méthode est associée dans le TableModel
public void setCellEditable(int row, int col, boolean value) {
editableCells[row][col] = value;
this.fireTableCellUpdated(row, col); // I don't think I actually need this
//because nothing in the cell has changed yet?
}
isCellEditable()
retourne alors la valeur de la matrice editableCells [] []. mais où dans mon code devrais-je changer la cellule à inédite lorsque le focus est perdu?
Sur une note légèrement liée, je voudrais également que la cellule gagne immédiatement le focus. J'ai lu à propos de getEditorComponent().requestFocus()
- mais cela ne semble pas tout à fait correct car rien n'est édité à ce moment-là, la cellule est seulement sélectionnée (et en utilisant cette méthode jette une nullpointerexception qui semblerait soutenir mon processus de pensée).
Quelqu'un peut-il me diriger dans la bonne direction s'il vous plaît? Je ne peux pas voir où je vais mal. Merci
** Edit: Pour verrouiller la cellule lorsque le focus est perdu, j'ai essayé d'ajouter une CellRenderer personnalisée avec une focusListener:
private class CustomCellRenderer extends DefaultTableCellRenderer{
public CustomCellRenderer(){
addFocusListener(new FocusAdapter(){
@Override
public void focusLost(FocusEvent e) {
pTableModel.setCellEditable(getSelectedRow(), getSelectedColumn(), false);
}
});
}
}
mais cela n'a pas semblé fonctionner non plus, mais je suis sans doute la mise en œuvre incorrectement (même si je l'ai vérifié que le moteur de rendu a été ajouté)
SSCCE
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
public class CellTest {
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
createAndShowGUI();
}
});
}
private static void createAndShowGUI(){
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyPanel panel = new MyPanel();
f.add(panel);
f.pack();
f.setVisible(true);
}
}
class MyPanel extends JPanel implements ActionListener{
private JTable table;
private MyTableModel model;
private JScrollPane sp;
private List<Person> people;
MyPanel(){
people = new ArrayList<>();
people.add(new Person("Will", 1));
model = new MyTableModel(people);
table = new JTable(model);
table.addMouseListener(new MouseAdapter(){
@Override
public void mousePressed(MouseEvent e){
maybeShowPopup(e);
}
@Override
public void mouseReleased(MouseEvent e){
maybeShowPopup(e);
}
});
table.setFillsViewportHeight(true);
sp = new JScrollPane(table);
this.add(sp);
}
@Override
public void actionPerformed(ActionEvent e){
if(e.getActionCommand().equals("Unlock")) {
model.setCellEditable(table.getSelectedRow(),table.getSelectedColumn(),true);
}
}
private JPopupMenu createPopupMenu(){
JPopupMenu pop = new JPopupMenu();
JMenuItem item = new JMenuItem("Unlock");
item.addActionListener(this);
pop.add(item);
return pop;
}
private void maybeShowPopup(MouseEvent e){
int currentRow = table.rowAtPoint(e.getPoint());
if(currentRow >= 0 && currentRow < table.getRowCount())
table.setRowSelectionInterval(currentRow, currentRow);
else
table.clearSelection();
if(table.getSelectedRow() < 0) return;
if(e.isPopupTrigger() && e.getComponent() instanceof JTable){
JPopupMenu pop = createPopupMenu();
pop.show(e.getComponent(), e.getX(), e.getY());
}
}
}
Et la TableModel et la classe de données:
class MyTableModel extends AbstractTableModel{
private List<Person> data;
private String[] colNames = new String[]{"Name","Age"};
private boolean[][] editableCells;
public MyTableModel(List<Person> data){
this.data = data;
this.editableCells = new boolean[this.getRowCount()][this.getColumnCount()];
}
@Override
public int getRowCount() { return data.size(); }
@Override
public int getColumnCount() { return colNames.length; }
@Override
public Object getValueAt(int row, int col){
Person p = data.get(row);
switch(col){
case 0 : return p.getName();
case 1 : return p.getAge();
}
return null;
}
@Override
public boolean isCellEditable(int row, int col){
return editableCells[row][col];
}
public void setCellEditable(int row, int col, boolean value){
editableCells[row][col] = value;
}
@Override
public void setValueAt(Object value, int row, int col){
Person p = data.get(row);
switch(col){
case 0 : p.setName((String)value);break;
case 1 : p.setAge((int)value);break;
}
this.setCellEditable(row, col, false);
this.fireTableCellUpdated(row, col);
}
public void setData(List<Person> data){
this.data = data;
this.fireTableDataChanged();
}
}
class Person {
private String name;
private int age;
public Person(String name, int age){
this.name = name;
this.age = age;
}
public void setName(String name){ this.name = name;}
public String getName(){ return name; }
public void setAge(int age){ this.age = age;}
public int getAge(){ return age; }
}
Toutes mes excuses pour la longueur - je ne savais pas comment faire plus court, sans peut-être recréer mal ce que je voulais réaliser. Il y a une erreur dans ce code en ce que pour faire un clic droit et "Déverrouiller", vous devez avoir déjà cliqué sur une ligne, sinon il s'agira d'une exception arrayIndexOutOfBounds. Je n'ai pas encore trouvé la cause exacte.
Mais fondamentalement, lorsque vous faites un clic droit, puis sélectionnez déverrouiller, j'aimerais que le curseur apparaisse dans la cellule. Au moment où vous cliquez sur déverrouiller, puis double-cliquez sur la cellule.
Un moteur de rendu n'est pas un composant réel. Il est juste utilisé pour peindre une image d'un composant. Il ne sera jamais mis au point. N'utilisez pas "==" pour comparer des chaînes. Utilisez la méthode 'equals (...)'. Publier un [mcve] approprié qui démontre le problème. – camickr
Désolé, ce n'est pas si minime, mais j'ai posté un exemple complet avec une description de ce que j'essaie d'atteindre. – NickW