Ho un problema molto semplice qui.Impostazione della messa a fuoco E del cursore lampeggiante sulla cella JTable specifica
Quando l'utente fa clic su un pulsante "Modifica" dopo aver selezionato una riga nel mio JTable
, il software controlla se questa riga può essere modificata.
Se lo è, vorrei mettere l'attenzione nella prima cella di quella riga con un cursore lampeggiante in modo che l'utente può avviare direttamente digitando nella cella.
Posso impostare correttamente se la riga è modificabile grazie al metodo isEditable() e io uso table.editCellAt(selectedRow, 0)
per iniziare la modifica.
Tuttavia
1) No cursore lampeggiante sta comparendo in quella cella
2) L'utente non può digitare nella cella subito (che deve ancora doppio clic sulla cella)
Qualche suggerimento su come ottenere questo?
//////////////////// UPDATE //////////////////////
Anche se il commento di MadProgrammer risolve il problema, risolve solo una parte di esso, ma è perché non sono stato abbastanza preciso.
In effetti, quando eseguo le misure che descrive con un "classico JTable", vale a dire:
table.editCellAt(selectedRow, 0);
table.setSurrendersFocusOnKeystroke(true);
table.getEditorComponent().requestFocus();
ottengo il cursore lampeggiante e la capacità di digitare subito.
Tuttavia, la parte che mancava è che io do 2 opzioni per l'utente.
1) Può sia selezionare direttamente una riga nella tabella a mano e per questo la soluzione è soddisfacente.
2) Ma ho anche offrire all'utente la possibilità di utilizzare un JTextField per trovare la riga che sta cercando più facilmente. Per questo uso un TableRowSorter con un regexFilter per filtrare le righe visualizzate. E quando provo la soluzione di MadProgrammer (con il filtro attivato) ottengo una java.lang.NullPointerException e non si verificano ulteriori modifiche.
Ecco eccezione:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at dialogs.DialogEditCouleurs.actionPerformed(DialogEditCouleurs.java:229)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.WaitDispatchSupport$2.run(Unknown Source)
at java.awt.WaitDispatchSupport$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.awt.WaitDispatchSupport.enter(Unknown Source)
at java.awt.Dialog.show(Unknown Source)
at java.awt.Component.show(Unknown Source)
at java.awt.Component.setVisible(Unknown Source)
at java.awt.Window.setVisible(Unknown Source)
at java.awt.Dialog.setVisible(Unknown Source)
at dialogs.DialogEditCouleurs.<init>(DialogEditCouleurs.java:123)
at panels.PanelPropertiesEdit.actionPerformed(PanelPropertiesEdit.java:940)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Qui è la linea che causa l'eccezione:
table.getEditorComponent().requestFocus();
Qui è il comportamento reale del software:
1) Nessun filtro: row è selezionato, ma Modifica JButton non è ancora stato cliccato.
2) Nessun filtro: JButton si fa clic su -> previsto comportamento corretto.
Ora il comportamento problematico:
1) e filtri: riga è selezionata, ma Modifica JButton non ancora cliccato.
2) e filtri: Modifica JButton cliccato -> nessun cambiamento e l'eccezione sollevata sopra (non preoccupatevi il tooltip)
Ecco la parte rilevante del JDialog:
public class DialogEditColors extends JDialog implements ActionListener, KeyListener
{
final WebNotificationPopup notificationPopup = new WebNotificationPopup();
final TableRowSorter<TableModel> sorter;
private JTable tableau = null;
private EditTableModel model = null;
private JPanel panelBoutons = null;
private WebTextField txtFieldSearch = null;
private JLabel lblTitle = null;
private JButton btnAdd = null, btnDelete = null, btnEdit = null;
private JButton btnAnnuler = null, btnSaveCouleur = null;
private JScrollPane scroller = null;
private ColorDao colorDao = new ColorDao(Share.connection);
public DialogEditColors()
{
super();
setSize(439, 313);
setTitle(" Edition couleurs");
getContentPane().setLayout(null);
setModal(true);
setResizable(false);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setLocationRelativeTo(null);
btnSaveCouleur = new JButton("Enregistrer");
btnSaveCouleur.setBounds(317, 247, 89, 26);
btnSaveCouleur.addActionListener(this);
btnAnnuler = new JButton("Annuler");
btnAnnuler.setBounds(214, 247, 89, 26);
btnAnnuler.addActionListener(this);
btnAdd = new JButton("");
btnAdd.setBounds(new Rectangle(10, 8, 33, 26));
btnAdd.addActionListener(this);
btnDelete = new JButton("");
btnDelete.setBounds(new Rectangle(53, 8, 33, 26));
btnDelete.addActionListener(this);
btnEdit = new JButton("");
btnEdit.setBounds(new Rectangle(96, 8, 33, 26));
btnEdit.addActionListener(this);
panelBoutons = new JPanel();
panelBoutons.setBorder(new LineBorder(Color.GRAY));
panelBoutons.setBounds(27, 11, 378, 43);
panelBoutons.setLayout(null);
txtFieldSearch = new WebTextField("", 10);
txtFieldSearch.setBounds(193, 9, 175, 24);
panelBoutons.add(txtFieldSearch);
txtFieldSearch.setTrailingComponent(new WebImage(IconUtil.createIcon("/images/search.png").getImage()));
txtFieldSearch.addKeyListener(this);
Object[][] data = new Object[colorDao.findAll().size()][2];
String[] title = { "Couleur", "Description" };
int i = 0;
for (Couleur coul : colorsDao.findAll())
{
data[i][0] = coul.getNom();
data[i][1] = coul.getDescription();
i++;
}
model = new EditTableModel(data, title);
tableau = new JTable(model)
{//COLORING THE BACKGROUND IN ALTERNATE COLORS
public Component prepareRenderer(TableCellRenderer renderer, int row, int column)
{
Component returnComp = super.prepareRenderer(renderer, row, column);
Color alternateColor = new Color(242, 242, 242);
Color whiteColor = Color.WHITE;
if (!returnComp.getBackground().equals(getSelectionBackground()))
{
Color bg = (row % 2 == 0 ? alternateColor : whiteColor);
returnComp.setBackground(bg);
bg = null;
}
return returnComp;
};
};
tableau.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
tableau.setCellSelectionEnabled(true);
sorter = new TableRowSorter<TableModel>(model);
tableau.setRowSorter(sorter);
sorter.addRowSorterListener(tableau);
scroller = new JScrollPane(tableau);
scroller.setBounds(27, 65, 378, 171);
addComponents();
setVisible(true);
}//END OF CONSTRUCTOR
private void addComponents()
{
getContentPane().add(scroller);
getContentPane().add(btnSaveCouleur);
getContentPane().add(btnAnnuler);
panelBoutons.add(btnAdd);
panelBoutons.add(btnDelete);
panelBoutons.add(btnEdit);
getContentPane().add(panelBoutons);
}//END OF METHOD
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == btnEdit)
{
int selectedRow = 0;
if (tableau.getSelectedRowCount() != 0) //THERE IS A CHOSEN COLOR IN JTABLE
{
String selectedColor = (tableau.getValueAt(tableau.getSelectedRow(), tableau.getSelectedColumn()))
.toString();
//WE'RE TESTING IF THE COLOR IS READONLY
if (colorDao.findByName(selectedColor).get(0).getReadOnly() == true)
{//IF THE COLOR IS READONLY
notificationPopup.setIcon(NotificationIcon.error);
notificationPopup.setContent("This item is readonly : impossible to edit it !");
NotificationManager.showNotification(notificationPopup);
}
else
{////THE COLOR IS NOT READONLY --> EDITING IS ALLOWED
//1) NOTIFY THE MODEL THAT EDITING IS ALLOWED
model.setEditingValidated(true);
//2) TEST WETHER FILTER IS ACTIVE OR NOT TO SEE IF INDEX CONVERSION IS NEEDED
if (txtFieldSearch.getText() == "")
{//NO FILTER
selectedRow = tableau.getSelectedRow();
}
else
{//FILTER IS ACTIVE
int modelIndex = tableau.convertRowIndexToModel(tableau.getSelectedRow());
selectedRow = modelIndex;
}
model.setEditingValidatedRowNb(selectedRow);
tableau.editCellAt(selectedRow, 0);
tableau.setSurrendersFocusOnKeystroke(true);
tableau.getEditorComponent().requestFocus();
}
}
else
{ //NO CHOSEN COLOR
notificationPopup.setIcon(NotificationIcon.error);
notificationPopup.setContent("No chosen color !");
NotificationManager.showNotification(notificationPopup);
}
}
else if (e.getSource() == btnAnnuler)
{//WE LEAVE THE DIALOG WITHOUT DOING ANYTHING
Share.chosenColor = null;
this.dispose();
}
}//END OF METHOD
public void keyReleased(KeyEvent e)
{
if (e.getSource() == txtFieldSearch)
{
String text = txtFieldSearch.getText();
if (text.length() == 0)
{
sorter.setRowFilter(null);
}
else
{
sorter.setRowFilter(RowFilter.regexFilter("(?i)" + text));
}
((AbstractTableModel) tableau.getModel()).fireTableDataChanged();
}
}//END OF METHOD
}//END OF CLASS
E qui è la parte rilevante del TableModel:
public class EditTableModel extends AbstractTableModel implements Serializable
{
protected Vector dataVector;
protected Vector columnIdentifiers;
protected boolean isEditingValidated = false;
protected int editingValidatedRowNb = 0;
public boolean isCellEditable(int row, int column)
{
//IF EDITING IS NOT VALIDATED NOTHING IS EDITABLE/RETURN FALSE
if (!isEditingValidated)
{
return false;
}
//ELSE A FURTHER TEST IS NEEDED TO DECIDE
else
{
//IF THE CURRENT ROW IS THE ROW FOR WHICH EDITING IS VALIDATED RETURN TRUE
if (row == editingValidatedRowNb)
{
return true;
}
//ELSE THE ROW IS ANOTHER ROW SO RETURN FALSE
else
{
return false;
}
}
}//END OF METHOD
}//END OF CLASS
suggerimenti qualcuno?
due cose. Prova a impostare ['SurrendersFocusOnKeystroke'] (http://docs.oracle.com/javase/7/docs/api/javax/swing/JTable.html # getSurrendersFocusOnKeystroke()) proprietà del 'JTable' e assicurarsi che l'editor abbia effettivamente lo stato attivo – MadProgrammer
Perfect MadProgrammer, questo funziona! Nel caso in cui qualcun altro necessiti delle specifiche, sono riuscito a ottenere ciò con il seguente codice: table.editCellAt (selectedRow, 0); \t \t \t \t \t \t \t \t \t table.setSurrendersFocusOnKeystroke (true); \t \t \t \t \t \t \t \t \t table.getEditorComponent() requestFocus().; Grazie mille !! – Zek101
È possibile [rispondere alla propria domanda] (http://meta.stackoverflow.com/q/17463/163188). – trashgod