Как суммировать массивы текстовых полей на лету в Java

1

У меня есть текстовые поля, которые я хотел бы отображать в общей сложности несколько других текстовых полей "на лету". Я никогда не пользовался Listeners раньше, но после некоторых исследований я обнаружил, что DocumentListeners - это, вероятно, то, что я ищу. Я потратил время на изучение связанных вопросов, таких как это и это, а также прочитал java-документы, но по-прежнему чувствую себя неловко в своем понимании и как я буду выполнять то, что мне нужно сделать, главным образом потому, что я использую массивы 1D и 2D.

Я хочу записать 3 разных типа времени (прямое время, сверхурочное время и двойное сверхурочное время), которое работало 10 работников в каждый день недели, а также общее количество.

Для этого я создал следующие переменные:

private static final int NUMBER_OF_PERSONNEL = 10;
private static final int DAYS_OF_THE_WEEK = 7;

private JTextField OT2Field[][] = new JTextField[DAYS_OF_THE_WEEK][NUMBER_OF_PERSONNEL];
private JTextField OT1Field[][] = new JTextField[DAYS_OF_THE_WEEK][NUMBER_OF_PERSONNEL];
private JTextField STField[][] = new JTextField[DAYS_OF_THE_WEEK][NUMBER_OF_PERSONNEL];

private JTextField totalOT2Field[] = new JTextField [NUMBER_OF_PERSONNEL];
private JTextField totalOT1Field[] = new JTextField [NUMBER_OF_PERSONNEL];
private JTextField totalSTField[] = new JTextField [NUMBER_OF_PERSONNEL];

Таким образом, OT2Field [0] [0] через OT2Field [6] [0] будет = totalOT2Field [0]

Мне нужен DocumentListener для каждого типа времени работы? Или я могу иметь один DocumentListener и обрабатывать различные типы и их данные в методах обновления? Если последнее возможно, то лучший способ это сделать? Помните, помните, что я новичок в Listeners.

Теги:
listener
documentlistener

1 ответ

1
Лучший ответ

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

В приведенной ниже реализации я только предположил, что OT представляется как десятичное число.

public class OvertimeSumListener implements DocumentListener {
    private JTextField[] otFields;
    private JTextField total;

    public OvertimeSumListener(JTextField[] otFields, JTextField total) {
        this.otFields = otFields;
        this.total = total;
    }

    public void calculateTotal() {
        double sum = 0;
        for (JTextField otField : otFields) {
            String text = otField.getText();
            try {
                sum += Double.parseDouble(text);
            } catch (NumberFormatException e) {
                // not a number - ignore
            }
        }
        total.setText(String.format("%.2f", sum));
    }

    public void insertUpdate(DocumentEvent e) {
        calculateTotal();
    }

    public void removeUpdate(DocumentEvent e) {
        calculateTotal();
    }

    public void changedUpdate(DocumentEvent e) {
        calculateTotal();
    }
}

При инициализации слушателей и привязывании их к вашим текстовым полям проще, если вы переверните свои 2D-массивы с [DAYS_OF_THE_WEEK][NUMBER_OF_PERSONNEL] на [NUMBER_OF_PERSONNEL][DAYS_OF_THE_WEEK], например:

private JTextField OT2Field[][] = new JTextField[NUMBER_OF_PERSONNEL][DAYS_OF_THE_WEEK];
private JTextField OT1Field[][] = new JTextField[NUMBER_OF_PERSONNEL][DAYS_OF_THE_WEEK];
private JTextField STField[][] = new JTextField[NUMBER_OF_PERSONNEL][DAYS_OF_THE_WEEK];

Наконец, некоторые методы для инициализации и привязки слушателей к текстовым полям:

private void initializeAllTimeFields() {
    for (int i = 0; i < NUMBER_OF_PERSONNEL; i++) {
        totalOT1Field[i] = initializeTimeFields(OT1Field[i]);
        totalOT2Field[i] = initializeTimeFields(OT2Field[i]);
        totalSTField[i] = initializeTimeFields(STField[i]);
    }
}

private JTextField initializeTimeFields(JTextField[] timeFields) {
    JTextField totalField = new JTextField();
    totalField.setEditable(false);
    OvertimeSumListener listener = new OvertimeSumListener(timeFields, totalField);
    for (int i = 0; i < timeFields.length; i++) {
        timeFields[i] = new JTextField();
        timeFields[i].getDocument().addDocumentListener(listener);
    }
    return totalField;
}

Редактировать (по запросу, см. Комментарии): Прохождение кода инициализации

Примечание. Я переименовал методы инициализации, чтобы упростить различие между ними в объяснении.

Общая идея кода инициализации - инициализировать все поля, которые принадлежат одному и тому же методу; т.е. поля OT и соответствующее полное поле. Наблюдение здесь состоит в том, что сводка должна быть отдельной для каждого человека и для каждого из полей времени (OT1, OT2, ST). Таким образом, поля, которые принадлежат друг другу, представляют собой одномерный массив временных полей и одно полное поле; что именно было включено в OvertimeSumListener.

Метод initializeAllTimeFields представляет собой простой цикл над персоналом, который трижды вызывает метод initializeTimeFields (по одному для каждого типа времени) для инициализации полей этого типа для этого человека.

Обратите внимание, что поля времени определяются как массив массивов. Таким образом, тип OT1Field - JTextField[][]. В цикле тип OT1Field[i] - JTextField[], т. OT1Field[i] Внутренний массив. Поскольку так легко получить внутренний массив, код значительно упрощается, если внутренний массив имеет измерение "дни недели", а внешний имеет "кадровое" измерение; что послужило поводом для перелистывания массивов.

Первый метод initializeAllTimeFields - простая итерация персонала. Для каждой итерации (т.е. каждого из персонала) второй метод вызывается для каждого из трех типов времени.

Второй метод initializeTimeFields принимает массив "дней недели" для одного человека и один тип времени. Значения массива инициализируются новыми объектами JTextField и возвращается новый объект JTextField для общего количества. Он также создает новый OvertimeSumListener и добавляет его к каждому из элементов массива (но не к итогу).

Подпись этого метода была разработана для упрощения кода. Поскольку массивы в java передаются как ссылки на объекты, содержимое исходного массива будет изменено, когда изменения будут внесены в массив одномерного измерения в initializeTimeFields. Кроме того, новый объект для полного поля создается и инициализируется в этом методе, и итоговый итоговый объект возвращается, так что этому элементу может быть присвоен правильный элемент массива полного массива.

  • 0
    спасибо за ваш ответ, извините за задержку, но вы знаете ... выходные дни Святого Паттиса. Я проводил время, изучая ваш ответ и играя с вашим предложением в моей программе. что меня смутило, так это то, как возможно иметь "totalOT1Field [i] = initializeOTTextFields (OT1Field [i]);" в initializeOTTextFields (), когда OT1Field является 2D-массивом. Вы просто делали обобщения для иллюстрации и идеи? или это принято в Java, если это так, вы могли бы разбить его на дальнейшие объяснения? еще раз, спасибо за отличный ответ.
  • 0
    @solleks: это не просто иллюстрация идеи, это рабочий код (я тестировал его до публикации). Я обновлю ответ с некоторыми дополнительными объяснениями того, как это работает. Я также написал некоторый дополнительный код для отображения текстовых полей, чтобы я мог протестировать код, но решил опустить его в ответе, так как он был не в теме вопроса.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню