Domanda

Sto utilizzando un paio di JFormattedTextFields nel mio programma. Per qualche ragione, quando i guadagni dei campi di testo si concentrano solo dopo un clic sul campo di testo, la posizione del cursore salta sempre a sinistra (posizione 0). Vorrei che il punto di inserimento per finire nella posizione cliccato dall'utente. Quindi, se scatto tra due cifre, il cursore dovrebbe finire tra questi due cifre.

Così ho implementato un focusListener che otterrebbe l'ubicazione click e impostare la posizione del cursore lì.

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) {}

    });

Ho provato un certo numero di cose per ottenere il suo per lavorare. Ho provato con la parola finale, che funziona, ma solo per un singolo campo di testo.

set

Ho usato / ottenere metodi all'interno l'ascoltatore attenzione per assegnare l'oggetto corrente, ma non sono sicuro di come fare questo "sicuro" (ad esempio, hanno bisogno di essere sincronizzati?).

Forse c'è qualcosa che mi manca?

È stato utile?

Soluzione

È necessario utilizzare un MouseListener:

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);

Altri suggerimenti

Questo avviene effettivamente in AbstractFormatter.install(JFormattedTextField), che viene chiamata quando i guadagni di campo concentrarsi.

Non sono sicuro che il motivo per cui è stato progettato in questo modo, ma è possibile ignorare questo comportamento (a patto che il formattatore non cambia la lunghezza della stringa nel campo.)

Esempio (supponendo che il valore del campo è un 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());
    }
}

Si noti che questa non è la stessa come il formattatore predefinito Integer. Il formattatore predefinito utilizza un DecimalFormat che separa gruppi di cifre, ad esempio "1,000,000". Questo rende il compito più difficile come cambia la lunghezza della stringa.

Miglioramento sulla soluzione di finnw un po 'che penso. Esempio:

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);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top