Как только пользователь фокусирует поле (щелкая его или перемещая фокус с помощью Tab), курсор перемещается.
Хотя курсор невидим, он сдвигает текст влево, что проблематично для небольших полей, поскольку текст может быть частично скрыт. Это небольшая, но досадная ошибка.
Как изменить такое поведение? Может быть, есть какие-то хитрые свойства, о которых я не знаю? Я хочу, чтобы текст оставался там, где он есть.
Имейте в виду, что поле должно оставаться фокусируемым и доступным для перемещения, поскольку навигация между полями формы с помощью Tab является частью нашей ожидаемой функциональности. Хотя поле в приведенной ниже демонстрации нельзя редактировать вручную, его можно редактировать косвенно. В реальном приложении пользователь может нажать Enter и выбрать одну из доступных опций, отображаемых в модальном диалоговом окне.
MRE:
Код: Выделить всё
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.text.DefaultFormatterFactory;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionEvent;
public class TextFieldDemo {
static JFormattedTextField textField;
static JButton button;
public static void main(String[] args) {
Container mainPanel = createMainPanel();
JFrame frame = new JFrame("Text field demo");
frame.setContentPane(mainPanel);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static Container createMainPanel() {
JPanel panel = new JPanel();
/* there should be at least one focusable component before the text field
so that the latter doesn't grab focus right away */
panel.add(createButton());
panel.add(createNameLabel());
panel.add(createNameField());
return panel;
}
private static JButton createButton() {
button = new JButton();
button.setText("Insert");
button.addActionListener(TextFieldDemo::onButtonClick);
button.setBorder(createButtonBorder()); // smaller
return button;
}
private static void onButtonClick(ActionEvent e) {
Object value = isEmpty() ? "Alex" : null; // in the real app, it's a domain object
String text = isEmpty() ? "Clear" : "Insert";
textField.setValue(value);
button.setText(text);
}
private static boolean isEmpty() {
return textField.getText().isEmpty();
}
private static CompoundBorder createButtonBorder() {
Border outer = BorderFactory.createLineBorder(Color.BLACK);
Border inner = BorderFactory.createEmptyBorder(2, 2, 2, 2);
return BorderFactory.createCompoundBorder(outer, inner);
}
private static Component createNameLabel() {
return new JLabel("Name");
}
private static Component createNameField() {
textField = new JFormattedTextField();
textField.setFormatterFactory(createFormatterFactory()); // setting a formatter factory is important
textField.setColumns(2); // let's limit the width
// so that the field displays the beginning, not the end of the string, if it's long
textField.addPropertyChangeListener("value", e -> textField.setCaretPosition(0));
textField.setEditable(false);
return textField;
}
private static DefaultFormatterFactory createFormatterFactory() {
DefaultFormatterFactory formatterFactory = new DefaultFormatterFactory();
formatterFactory.setDefaultFormatter(createFormatter());
return formatterFactory;
}
private static JFormattedTextField.AbstractFormatter createFormatter() {
return new JFormattedTextField.AbstractFormatter() {
@Override
public Object stringToValue(String text) {
return text;
}
@Override
public String valueToString(Object value) {
return value == null ? null : value.toString();
}
};
}
}

После нажатия на поле («А» скрыто):

Java 8.
Подробнее здесь: https://stackoverflow.com/questions/798 ... uring-text
Мобильная версия