Один ключевой слушатель для большого количества JTextField

Мой английский очень плохой, поэтому я ничего не смог найти в Google, у меня есть JFrame с JPanel, который содержит много JTextField. Когда я создавал функцию «сохранить файл», мне приходилось ставить KeyListener для каждого JTextField. Есть ли более эффективный способ сделать это?

РЕДАКТИРОВАТЬ: проверить, были ли изменены какие-либо поля с момента последнего сохранения


person Germán    schedule 27.09.2014    source источник
comment
Зачем вам нужен KeyListener в JTextField для сохранения файла? Я думаю, у вас есть кнопка, которая запускает событие, и это все, что вам нужно.   -  person Dici    schedule 28.09.2014
comment
Вы почти никогда не должны добавлять KeyListener к текстовому компоненту, такому как JTextField. Вероятно, есть лучший способ сделать это, например, с помощью привязки клавиш. И на самом деле это потенциальное решение. Какое нажатие клавиши вы пытаетесь перехватить?   -  person Hovercraft Full Of Eels    schedule 28.09.2014
comment
"EDIT: is to test if any of the fields have been modified since last save" -- в этом случае используйте DocumentListener.   -  person Hovercraft Full Of Eels    schedule 28.09.2014
comment
@Dici это так, но нужно проверить, не были ли изменены какие-либо поля с момента последнего сохранения.   -  person Germán    schedule 28.09.2014


Ответы (1)


Касательно,

РЕДАКТИРОВАТЬ: проверить, были ли изменены какие-либо поля с момента последнего сохранения

Затем используйте DocumentListener. Таким образом, вы могли бы прослушивать изменения, происходящие помимо нажатия клавиш, например, при вырезании и вставке, и по-прежнему реагировать на них.

Ты спрашиваешь:

это выглядит круто, но есть ли способ добавить его в JPanel или мне нужно добавить его во все поля?

Вам нужно будет добавить прослушиватель в документ каждого поля, но если вы поместите поля в список или массив, это будет легко сделать с помощью простого цикла for. Например, запустите следующий код. Всякий раз, когда нажимается кнопка сохранения или когда она активируется нажатием alt-s, она отключается. Он автоматически включается при любых изменениях в документах, хранящихся в любом JTextField.

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

public class DocListenerEg extends JPanel {
   private static final int FIELD_COUNT = 10;
   private static final int COLUMNS = 8;
   private JButton saveButton = new JButton(new SaveAction("Save", KeyEvent.VK_S));
   private List<JTextField> fieldList = new ArrayList<>();

   public DocListenerEg() {
      MyDocListener docListener = new MyDocListener();
      add(saveButton);
      for (int i = 0; i < FIELD_COUNT; i++) {
         JTextField field = new JTextField(COLUMNS);
         add(field);
         fieldList.add(field);

         field.getDocument().addDocumentListener(docListener);
      }
   }

   public void documentChange() {
      saveButton.setEnabled(true);
   }

   private class MyDocListener implements DocumentListener {
      private boolean changed = false;

      @Override
      public void changedUpdate(DocumentEvent dEvt) {
         documentChange();
      }

      @Override
      public void insertUpdate(DocumentEvent dEvt) {
         documentChange();
      }

      @Override
      public void removeUpdate(DocumentEvent dEvt) {
         documentChange();
      }

   }

   private class SaveAction extends AbstractAction {

      public SaveAction(String name, int mnemonic) {
         super(name);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent evt) {
         // TODO: save the data
         ((AbstractButton) evt.getSource()).setEnabled(false);
      }

   }

   private static void createAndShowGui() {
      DocListenerEg mainPanel = new DocListenerEg();

      JFrame frame = new JFrame("DocListenerEg");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}
person Hovercraft Full Of Eels    schedule 27.09.2014
comment
это выглядит круто, но есть ли способ добавить его в JPanel или мне нужно добавить его во все поля? - person Germán; 28.09.2014