Frage

Ich bin ein paar JFormattedTextFields in meinem Programm verwenden. Aus irgendeinem Grund, wenn die Textfeld gewinnt nach einem Klick auf das Textfeld den Fokus, springt der Cursor-Position immer auf der linken Seite (Position 0). Ich mag die caret an dem durch den Benutzer angeklickt, um am Ende. Also, wenn ich zwischen zwei Ziffern klicken, sollte die Einfügemarke nach oben in zwischen diesen beiden Ziffern enden.

So implementiert ich einen Focuslistener, die die Klickposition erhalten würde und die Position der Einfügemarke dort eingestellt.

FocusListener focusListener = new FocusListener(){


    public void focusGained(FocusEvent evt) {

        JFormettedTextField jftf = (JFormattedTextField) evt.getSource();

        //This is where the caret needs to be.
        int dot = jftf.getCaret().getDot(); 

        SwingUtilities.invokeLater( new Runnable() {

        public void run() {
'the textField that has focus'.setCaretPosition('Some how get the evt or dot');              
              }
           });
        }

    public void focusLost (FocusEvent evt) {}

    });

Ich habe eine Reihe von Dingen versucht, seine Arbeit zu bekommen. Ich habe versucht, das letzte Schlüsselwort, das aber nur für ein einziges Textfeld funktioniert.

Ich habe verwendet set / get-Methoden in den Fokus Hörer das aktuelle Objekt zuweisen, aber ich bin nicht sicher, wie man diese „sicher“ (zum Beispiel müssen sie synchronisiert werden?).

Vielleicht gibt es etwas, was ich bin fehlt?

War es hilfreich?

Lösung

Sie benötigen einen Mouselistener verwenden:

MouseListener ml = new MouseAdapter()
{
    public void mousePressed(final MouseEvent e)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                JTextField tf = (JTextField)e.getSource();
                int offset = tf.viewToModel(e.getPoint());
                tf.setCaretPosition(offset);
            }
        });
    }
};

formattedTextField.addMouseListener(ml);

Andere Tipps

Dies geschieht eigentlich in AbstractFormatter.install(JFormattedTextField), die, wenn sie konzentrieren sich die Feldgewinne genannt wird.

Ich bin mir nicht sicher, warum es so gestaltet ist, aber Sie können dieses Verhalten außer Kraft setzen (solange Ihr Formatierer nicht die Länge der Zeichenfolge im Feld ändert.)

Beispiel (unter der Annahme, den Feldwert ist ein int):

class IntFormatter extends AbstractFormatter {
    @Override
    public void install(final JFormattedTextField ftf) {
        int prevLen = ftf.getDocument().getLength();
        int savedCaretPos = ftf.getCaretPosition();
        super.install(ftf);
        if (ftf.getDocument().getLength() == prevLen) {
            ftf.setCaretPosition(savedCaretPos);
        }
    }

    public Object stringToValue(String text) throws ParseException {
        return Integer.parseInt(text);
    }

    public String valueToString(Object value) throws ParseException {
        return Integer.toString(((Number) value).intValue());
    }
}

Beachten Sie, dass diese als Standard Integer Formatierer ist nicht das Gleiche. Die Standard-Formatierer verwenden eine DecimalFormat, die Gruppen von Ziffern trennt, z.B. "1,000,000". Das macht die Aufgabe schwieriger, da sie die Länge der Zeichenfolge ändern.

Verbesserte auf finnw-Lösung ein wenig denke ich. Beispiel:

public static void main(String[] args) {
    NumberFormat format = NumberFormat.getInstance();
    NumberFormatter formatter = new NumberFormatter(format) {
        @Override
        public void install(JFormattedTextField pField) {
            final JFormattedTextField oldField = getFormattedTextField();
            final int oldLength = pField.getDocument().getLength();
            final int oldPosition = pField.getCaretPosition();

            super.install(pField);

            if (oldField == pField && oldLength == pField.getDocument().getLength()) {
                pField.setCaretPosition(oldPosition);
            }
        }
    };
    JFormattedTextField field = new JFormattedTextField(formatter);
    field.setValue(1234567890);

    JOptionPane.showMessageDialog(null, field);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top