Обобщите несколько текстовых полей для выделения всего текста при достижении фокуса

#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.) Создайте пользовательский класс, как предложено. Выберите любое, которое проще в соответствии с вашим текущим дизайном и кодированием приложения.