#java #swing #jtextfield #focuslistener
#java #swing #jtextfield #focuslistener
Вопрос:
Я хочу, чтобы каждое из нескольких текстовых полей на панели было выровнено по центру и имело прослушиватель фокуса, который выделит все поле при достижении фокуса.
txtSelection = new JTextField("", 9);
txtInclusion = new JTextField("", 9);
txtExclusion = new JTextField("", 9);
...
Я знаю, как сделать это один за другим:
txtSelection.setHorizontalAlignment(JTextField.CENTER);
txtSelection.addFocusListener(new FocusAdapter() {
public void focusGained(FocusEvent e) {
txtSelection.select(0, 9);
}
});
Но я бы предпочел не повторять эту структуру для всех текстовых полей.
Я попробовал это (и пару вариантов), но код, похоже, ничего не делает:
pnlConditions = new JPanel();
pnlConditions.setLayout(new GridBagLayout());
for(final Component c : pnlConditions.getComponents()) // compiler insisted on 'final'
{
((JTextField)c).setHorizontalAlignment(JTextField.CENTER);
if(c instanceof JTextField)
{
c.addFocusListener
(new FocusAdapter()
{
@Override public void focusGained(FocusEvent e)
{
((JTextField)c).select(0,9); // compiler suggested cast to JTextComponent; no difference
}
}
);
}
}
Все поле не выделено; выравнивание по левому краю (по умолчанию). Я предполагаю, что мои первые намеки на то, что это не сработает, — это то, что компилятор настаивает на том, что это c
должно быть final
в for
и для предположения, что приведение должно было быть JTextComponent
в операторе with select
; но он не сделал этого предложения в операторе with setHorizontal...
.
Я уверен, что это можно сделать; но как?
Вот весь метод, содержащий приведенные выше фрагменты:
static void makePnlConditions(){
JLabel lblSelections = new JLabel("Select ONLY combos with ALL of:");
JLabel lblInclusions = new JLabel("DE-select combo NOT containing one or more of:");
JLabel lblExclusions = new JLabel("DE-select combo containing ANY of:");
txtSelection = new JTextField("", 9);
txtInclusion = new JTextField("", 9);
txtExclusion = new JTextField("", 9);
pnlConditions = new JPanel();
pnlConditions.setLayout(new GridBagLayout());
for(final Component c : pnlConditions.getComponents())
{
((JTextField)c).setHorizontalAlignment(JTextField.CENTER);
if(c instanceof JTextField)
{
c.addFocusListener
(new FocusAdapter()
{
@Override public void focusGained(FocusEvent e)
{
((JTextField)c).select(0,9);
}
}
);
}
}
pnlConditions.add(lblSelections);
pnlConditions.add(txtSelection);
pnlConditions.add(lblInclusions);
pnlConditions.add(txtInclusion);
pnlConditions.add(lblExclusions);
pnlConditions.add(txtExclusion);
}
Ответ №1:
Сначала добавьте компоненты в JPanel
противном pnlConditions.getComponents()
случае вернет пустой массив, и прослушиватель не будет добавлен JTextField
.
Если вы хотите выделить весь текст, используйте метод JTextComponent#selectAll() .
Пример кода:
JPanel pnlConditions = new JPanel();
pnlConditions.setLayout(new GridBagLayout());
pnlConditions.add(lblSelections);
pnlConditions.add(txtSelection);
pnlConditions.add(lblInclusions);
pnlConditions.add(txtInclusion);
pnlConditions.add(lblExclusions);
pnlConditions.add(txtExclusion);
for (final Component c : pnlConditions.getComponents()) {
if (c instanceof JTextField) {
((JTextField) c).setHorizontalAlignment(JTextField.CENTER);
...
}
}
Я хочу, чтобы каждое из нескольких текстовых полей на панели имело выравнивание по центру и имело прослушиватель фокуса, который будет выбирать все поле при достижении фокуса.
Создайте пользовательский класс, который расширяется JTextField
, предоставляет всю реализацию по умолчанию и использует его везде в вашем приложении, чтобы сделать его централизованным.
Пример кода:
class MyJTextField extends JTextField {
// Initialization block that is called for all the constructors
{
this.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
selectAll();
}
});
this.setHorizontalAlignment(JTextField.CENTER);
}
public MyJTextField() {}
public MyJTextField(String text) {super(text);}
public MyJTextField(int columns) {super(columns);}
public MyJTextField(String text, int columns) {super(text, columns);}
}
Комментарии:
1. @Braj — спасибо! Мое очевидное заблуждение о том, что поле должно быть заполнено перед добавлением на панель, помешало мне сделать то, что вы сделали очевидным: переместить цикл ниже всех добавлений. Это все, что потребовалось. Я также ценю, что вы мне советуете
selectAll
; Я тоже пропустил это, хотяselect(0,9)
выполняет работу, хотя и не эффективно.2. @Braj —К вашему СВЕДЕНИЮ — я создал метод
centerAndSelect(JPanel p)
для выполнения задач, о которых я спрашивал. Я вызываю его из двух разных мест в этой программе и буду использовать его (и, вероятно, расширять его) с этого момента, я думаю! (Я только что понял, что есть вторая часть вашего ответа о расширении JTextField… нужно это изучить.) … (Только что сделал! КРУТО!)3. Да, есть много способов его обобщения. 1.) Создайте отдельный метод для перемещения общего кода 2.) Создайте пользовательский класс, как предложено. Выберите любое, которое проще в соответствии с вашим текущим дизайном и кодированием приложения.