2016-03-21 12 views
1

in der textPaneKeyTyped(java.awt.event.keyEvent evt) Methode Ich habe einen Code geschrieben, um Klammern automatisch zu schließen, wenn die erste getippt wird. Ich habe für einige Codes des Schließbügel zu entfernen, wenn der Benutzer es in TextPane geben, aber es tut nichtsWie die automatisch hinzugefügte schließende Klammer korrekt entfernt wird, wenn sie getippt wird

Dies ist ein funktionierendes Beispiel:

package test; 

import java.awt.event.ActionEvent; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.AbstractAction; 
import javax.swing.Action; 
import javax.swing.JTextPane; 
import javax.swing.KeyStroke; 
import javax.swing.text.BadLocationException; 


public class NewJFrame extends javax.swing.JFrame { 

    /** Creates new form NewJFrame */ 
    public NewJFrame() { 
     initComponents(); 
    } 

    /** This method is called from within the constructor to 
    * initialize the form. 
    * WARNING: Do NOT modify this code. The content of this method is 
    * always regenerated by the Form Editor. 
    */ 
    @SuppressWarnings("unchecked") 
    // <editor-fold defaultstate="collapsed" desc="Generated Code"> 
    private void initComponents() { 

     jPanel1 = new javax.swing.JPanel(); 
     jScrollPane1 = new javax.swing.JScrollPane(); 
     textPanel = new javax.swing.JTextPane(); 

     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

     textPanel.addKeyListener(new java.awt.event.KeyAdapter() { 
      public void keyTyped(java.awt.event.KeyEvent evt) { 
       textPanelKeyTyped(evt); 
      } 
     }); 
     jScrollPane1.setViewportView(textPanel); 

     javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); 
     jPanel1.setLayout(jPanel1Layout); 
     jPanel1Layout.setHorizontalGroup(
      jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(jPanel1Layout.createSequentialGroup() 
       .addContainerGap() 
       .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE) 
       .addContainerGap()) 
     ); 
     jPanel1Layout.setVerticalGroup(
      jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(jPanel1Layout.createSequentialGroup() 
       .addGap(19, 19, 19) 
       .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 254, javax.swing.GroupLayout.PREFERRED_SIZE) 
       .addContainerGap(27, Short.MAX_VALUE)) 
     ); 

     getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER); 

     pack(); 
    }// </editor-fold> 

private void textPanelKeyTyped(java.awt.event.KeyEvent evt) { 
// TODO add your handling code here: 
    Action action1 = new AbstractAction() { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      textModel = (JTextPane) e.getSource(); 
      try { 
       int position2 = textModel.getCaretPosition(); 
       textModel.getDocument().remove(position2, 1); 
       textModel.getDocument().insertString(position2, ")", null); 

      } catch (Exception e1) {} 
     } 

}; 
    Action action = new AbstractAction() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       int position = textModel.getCaretPosition(); 
       textModel.replaceSelection("()"); 
       textModel.setCaretPosition(position+1); 
      } 

    }; 

    String key = "typed ("; 
    String key1 = "typed)"; 
    textPanel.getInputMap().put(KeyStroke.getKeyStroke(key), key); 
    textPanel.getInputMap().put(KeyStroke.getKeyStroke(key1), key1); 
    textPanel.getActionMap().put(key, action); 
    textPanel.getActionMap().put(key1, action1); 


} 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String args[]) { 
     /* Set the Nimbus look and feel */ 
     //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> 
     /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. 
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */ 
     try { 
      for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 
       if ("Nimbus".equals(info.getName())) { 
        javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
        break; 
       } 
      } 
     } catch (ClassNotFoundException ex) { 
      java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (InstantiationException ex) { 
      java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (IllegalAccessException ex) { 
      java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (javax.swing.UnsupportedLookAndFeelException ex) { 
      java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } 
     //</editor-fold> 

     /* Create and display the form */ 
     java.awt.EventQueue.invokeLater(new Runnable() { 

      public void run() { 
       new NewJFrame().setVisible(true); 
      } 
     }); 
    } 
    // Variables declaration - do not modify 
    private javax.swing.JPanel jPanel1; 
    private javax.swing.JScrollPane jScrollPane1; 
    private javax.swing.JTextPane textPanel; 
    // End of variables declaration 
} 

Der Code für das automatische Schließen des Bügels funktioniert .. Das Problem ist für die Ersetzung der schließenden Klammer: es druckt ')' gerade, wenn vorher ein '('. Wenn ich in der Lage wäre, das ')' jederzeit zu drucken, wie sollte ich meinen Code bearbeiten ? Danke.

+0

Könnten Sie den Wert 'pos' anzuzeigen, wenn Sie das Entfernen tun – Berger

+0

in der ersten Zeile des TextPane, ja im zweite Zeile erscheint nur, wenn ich die Klammer 2 mal schließe, so: '(' ')' ')'. Wenn Sie die zweite schließende Klammer eingeben, wird angezeigt. In der dritten Zeile, wenn ich 3 mal tippe ... – Pino

+0

Könnten Sie auch ein einfaches kompilierbares und ausführbares Beispiel posten? Ich glaube nicht, dass 'private void textPaneprivate void textModelKeyTyped (java.awt.event.KeyEvent evt)' eine gültige Methodensignatur ist. – Berger

Antwort

4

Es ist nie eine gute Idee, die Verwendung eines KeyStroke zu blockieren. Sie wissen nie, wann das ")" möglicherweise manuell eingegeben werden muss. Wen kümmert es, wenn der Benutzer das ")" eingibt? Wenn es nicht syntaktisch korrekt ist, erhalten sie eventuell einen Kompilierungsfehler. Der kluge Benutzer wird erkennen, dass dann nur noch "(" und "") eingegeben werden müssen.

Wenn es jedoch eine Situation gibt, in der Sie die Eingabe eines bestimmten Zeichens verhindern möchten, verwenden Sie Key Bindings KEINE KeyListener.

Zum Beispiel:

KeyStroke ignore = KeyStroke.getKeyStroke(')'); 
textPane.getInputMap().put(ignore, "none"); 

Weitere Informationen zu Key Bindings lesen Sie die Swig Tutorial. Ich habe dir einen Link in einer deiner vorherigen Fragen gegeben. Halten Sie den Tutorial-Link für die Grundlagen griffbereit. Sie finden einen Abschnitt auf How to Use Key Bindings, wenn Sie das Inhaltsverzeichnis ("trail") für das Lernprogramm betrachten.

auch für Ihre „(“ Aktion können Sie nur verwenden:?.

textPane.replaceSelection("()"); 
+0

Zunächst einmal vielen Dank für Ihre nützlichen Tipps! Ich habe meine Frage mit dem neuen Code bearbeitet, aber es scheint, dass es immer noch einen Fehler gibt: Das ')' wird nur gedruckt, wenn '(' vorher '.' – Pino

+0

'the') 'wird nur gedruckt, wenn' ('vorher') Das war Ihre Anforderung, Sie wollten automatisch "()" einfügen und verhindern, dass der Benutzer ")" eingibt. Ich schlug vor, es sei keine gute Voraussetzung, und Sie sollten sich nicht einmal darum sorgen, dass der Benutzer ")" eintippt. Alles, was Sie brauchen, ist die benutzerdefinierte Aktion für die "(" Taste zum Einfügen "()". In jedem Fall haben Sie noch einen KeyListener. Ich habe keine Ahnung warum. Ich habe ausdrücklich angegeben, dass Sie ** keinen KeyListener ** verwenden sollten. – camickr

+0

Sie haben auch nicht auf meinen Vorschlag zur Verwendung der replaceSelection() -Methode gehört.Ihr Code verändert die Art, wie Texteingaben funktionieren.Normalerweise, wenn ein Text ausgewählt ist und Sie ein Zeichen eingeben, ersetzt das eingegebene Zeichen den ausgewählten Text , Sie wissen, haben speziellen Code, der den ausgewählten Text nicht ersetzt, wenn Sie "(" eingeben. Dies ist eine Inkonsistenz. – camickr