2014-07-09 16 views
5

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.

enter image description here

2) Kein Filter: JButton geklickt -> richtiges Verhalten erwartet.

enter image description here

nun das problematische Verhalten:

1) Filterung auf: Zeile ausgewählt wird, aber bearbeiten JButton noch nicht angeklickt. enter image description here

2) Filterung auf: Edit JButton geklickt -> keine Änderung und über Exception ausgelöst (nicht die Mühe den Tooltip)

enter image description here

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?

+1

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

+0

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

+2

Sie können [Ihre eigene Frage beantworten] (http://meta.stackoverflow.com/q/17463/163188). – trashgod

Antwort

0

Für den zweiten Teil des Problems, ich beschlossen, es wie folgt:

Zum einen habe ich die

table.setCellSelectionEnabled(true); 

Nur um sicher zu stellen, dass eine bestimmte Zelle in einem JTable aktiviert ist auswählen.

Dann verwendet I

table.changeSelection(int row, int column, false, false); 

die beiden booleschen obigen Werte sind Toggle und erstrecken sich jeweils. false, false Hier wird die vorherige Auswahl gelöscht und sichergestellt, dass die neue Zelle ausgewählt wird.

Das obige Snippet wurde verwendet, um diese bestimmte Zelle in der Tabelle auszuwählen. Ich tat es so, dass wenn ich die editCellAt() -Methode benutze, die Aufnahme die aktuell ausgewählte Zelle bearbeitet.

Wenn aus irgendeinem Grund editCellAt() nicht ordnungsgemäß funktioniert, dann erhalten Sie null von der getEditorComponent(). Da keine Komponente derzeit das Problem in Ihrem Fall bearbeitet.

table.getEditorComponent() 

Dann bearbeite die Zelle zu starten ich

verwendet
table.editCellAt(int row, int column); 

Dies wurde verwendet, programmatisch Bearbeiten der Zellkomponente zu starten.

und schließlich den Cursor blinken/Fokus auf dieser bestimmten Zelle zu bekommen habe ich

table().getEditorComponent().requestFocus(); 

Hoffnung, das hilft. Es wirkt wie Charme für mich. Lass es mich wissen, wenn es nicht so ist.

Kurz gesagt, habe ich folgende Zeilen Code:

table.setCellSelectionEnabled(true); 
table.changeSelection(int row, int column, false, false); 
table.editCellAt(int row, int column); 
table().getEditorComponent().requestFocus();