Ich habe hier ein sehr einfaches Problem.Fokus einstellen UND Cursor auf bestimmte JTable-Zelle blinkend
Wenn der Benutzer auf eine Schaltfläche "Bearbeiten" klickt, nachdem er eine Zeile in meinem JTable
ausgewählt hat, überprüft die Software, ob diese Zeile bearbeitet werden darf.
Wenn ja, möchte ich den Fokus in die erste Zelle dieser Reihe mit einem blinkenden Cursor setzen, so dass der Benutzer direkt beginnen kann, in die Zelle zu tippen.
Ich kann erfolgreich einstellen, wenn die Zeile editierbar ist dank der isEditable() Methode und ich benutze table.editCellAt(selectedRow, 0)
um die Bearbeitung zu starten.
jedoch
1) kein blinkender Cursor wird in dieser Zelle erscheint
2) Der Benutzer kann die Zelle eingeben sofort (er hat immer noch die Zelle zu verdoppeln klicken)
Irgendwelche Vorschläge, wie dies zu erreichen ist?
//////////////////// UPDATE //////////////////////
Obwohl MadProgrammers Kommentar das Problem löst, löst es nur einen Teil davon, aber das liegt daran, dass ich nicht präzise genug war.
der Tat, wenn ich die Schritte ausführen, beschreibt er mit einem „klassischen JTable“, das heißt:
table.editCellAt(selectedRow, 0);
table.setSurrendersFocusOnKeystroke(true);
table.getEditorComponent().requestFocus();
ich den blinkenden Cursor und die Fähigkeit, sofort zu geben.
Aber der Teil, der fehlte, ist, dass ich dem Benutzer 2 Optionen gebe.
1) Er kann entweder direkt eine Zeile in der Tabelle von Hand auswählen und dafür ist die Lösung in Ordnung.
2) Aber ich biete dem Benutzer auch die Möglichkeit, ein JTextField zu verwenden, um die Zeile, die er sucht, leichter zu finden. Dazu verwende ich einen TableRowSorter mit einem regexFilter, um die angezeigten Zeilen zu filtern. Und wenn ich die Lösung von MadProgrammer dort (mit Filterung) versuche, bekomme ich eine java.lang.NullPointerException und es findet keine weitere Bearbeitung statt. Hier
ist die Ausnahme:
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)
Hier ist die Linie, wodurch die Ausnahme:
table.getEditorComponent().requestFocus();
Hier ist das tatsächliche Verhalten der Software:
1) kein Filter: row ist ausgewählt, aber Edit JButton ist noch nicht angeklickt.
2) Kein Filter: JButton geklickt -> richtiges Verhalten erwartet.
nun das problematische Verhalten:
1) Filterung auf: Zeile ausgewählt wird, aber bearbeiten JButton noch nicht angeklickt.
2) Filterung auf: Edit JButton geklickt -> keine Änderung und über Exception ausgelöst (nicht die Mühe den Tooltip)
Hier ist der relevante Teil des JDialog ist:
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
Und hier ist der relevante Teil des 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
Vorschläge jemand?
Zwei Dinge. Versuchen Sie, [SurrendersFocusOnKeystroke] (http://docs.oracle.com/JavaSE/7/docs/api/javax/Swing/JTable.html # getSurrendersFocusOnKeystroke()) Eigentum des 'JTable' und vergewissern Sie sich, dass der Editor – MadProgrammer
Perfekte MadProgrammer konzentrieren tatsächlich hat, das funktioniert! Für den Fall, jemand anderes der Besonderheiten muss, ich in der Lage gewesen, dies mit dem folgenden Code zu erreichen: 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() request (.); Vielen Dank !! – Zek101
Sie können [Ihre eigene Frage beantworten] (http://meta.stackoverflow.com/q/17463/163188). – trashgod