Способ получения индекса измененного объекта в ArrayList?

У меня есть веб-приложение, которое использует dataTables в функциях JSF и Primefaces, чтобы оно могло выполнять некоторые дополнительные динамические функции. В dataTable у меня есть строки, содержащие редактируемые данные. Моя конечная цель состоит в том, чтобы пользователи могли редактировать эти данные, нажимать кнопку сохранения, и операторы обновления будут выполняться для замены того, что присутствует в базе данных. Проблема в том, что в настоящее время я не знаю, как обнаруживать изменения в объектах в списке массивов.

Я сделал пример, чтобы посмотреть, сможет ли кто-нибудь решить мою дилемму. Слушайте, у меня есть код, который создает dataTable, а в dataTable есть объекты из ArrayList, каждый объект содержит три разные строки. Объекты доступны для редактирования в datatable. Мне нужно иметь возможность как минимум получить индекс ArrayList объекта, редактируемого на странице. При этом я мог бы сформировать новый список редактируемых объектов и написать метод, который выполняет пакетное обновление только редактируемых объектов (объект в моем сценарии эквивалентен строке данных в базе данных). Мой предыдущий метод заключался в переборе всего ArrayList и обновлении всех объектов (строк), но по мере того, как список становится большим, это становится очень дорогим. Прямо сейчас у меня есть метод Primefaces onCellEdit, который сообщает мне предыдущее значение и значение, на которое оно было изменено, но нет способа точно определить, изменился ли объект. Любая помощь будет оценена по достоинству. Приведенный ниже код настроен таким образом, что его можно копировать, вставлять и выполнять.

Редактировать: В моей ситуации мне не нужно обновлять ArrayList. Это делается автоматически с использованием входных данных на страницах, а также геттера и сеттера для bean-компонента. Что мне нужно сделать, так это узнать, какие объекты (строки) редактируются, чтобы я мог отодвинуть их в сторону и выполнить обновление базы данных, где я обновляю только то, что отредактировано. ArrayList является зеркалом того, что находится в базе данных, но цель здесь состоит в том, чтобы обновить базу данных, чтобы отразить отредактированный ArrayList, без должен выполнить итерацию по всему списку.

Продукт.java

public class Prod{

private String value1;

private String value2;

private String value3;

public String getValue1() {
    return value1;
}

public void setValue1(String value1) {
    this.value1 = value1;
}

public String getValue2() {
    return value2;
}

public void setValue2(String value2) {
    this.value2 = value2;
}

public String getValue3() {
    return value3;
}

public void setValue3(String value3) {
    this.value3 = value3;
}

}

Listen.java

import java.io.IOException;
import java.util.ArrayList;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

import org.primefaces.event.CellEditEvent;

import com.product.inventory.beans.Prod;



@ManagedBean(name = "listen")

@SessionScoped
public class Listen{

 private ArrayList<Prod> products;

 boolean firstEdit = true;


public Listen(){

}

public ArrayList<Prod> setup(){


    ArrayList<Prod> result = new ArrayList<>();     

    int numObject = 100;

    int iterations = 0;


    while( iterations < numObject){

        Prod prod = new Prod();

        prod.setValue1("A" + iterations);
        prod.setValue2("B" + iterations);
        prod.setValue3("C" + iterations);

     result.add(prod);

     iterations = iterations + 1;
    }

    return result;

}

public void onCellEdit(CellEditEvent event) {

  Object oldValue = event.getOldValue();
    Object newValue = event.getNewValue();

    if (newValue != null && !newValue.equals(oldValue)) {
        FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, 
"Cell Changed", "Old: " + oldValue + ", New:" + newValue);
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

if (isFirstEdit()){

    FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, new 
FacesMessage(FacesMessage.SEVERITY_INFO,
                "Note",  "To confirm changes, please select 'Save Changes' 
or they will not be saved.") );

        this.setFirstEdit(false);

}

}

public void goTest(){

    System.out.println("Initializing...");

    this.products = setup();

    ExternalContext ec = FacesContext.getCurrentInstance()
            .getExternalContext();

    try {

         ec.redirect(ec.getRequestContextPath()
                    + "/test.xhtml");

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    System.out.println("Table Structure Made");

}

public boolean isFirstEdit() {
    return firstEdit;
}

public void setFirstEdit(boolean firstEdit) {
    this.firstEdit = firstEdit;
}

public ArrayList<Prod> getProducts() {
    return products;
}

public void setProducts(ArrayList<Prod> products) {
    this.products = products;
}

}

test.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns = "http://www.w3.org/1999/xhtml"
xmlns:ui = "http://java.sun.com/jsf/facelets"
xmlns:h = "http://java.sun.com/jsf/html"
xmlns:f = "http://java.sun.com/jsf/core"
xmlns:p = "http://primefaces.org/ui">


<h:head>

</h:head>
<h:body>

<h:form id = "form" method = "post">

<p:growl id = "msgs" showDetail = "true" sticky = "false">
    </p:growl>
    <div >

        <p:dataTable id = "products" var = "prod" value = "#{listen.products}"
             scrollable = "true" scrollHeight = "900" 
             editable = "true" editMode = "cell" widgetVar= "prodCell">

            <p:ajax event = "cellEdit" listener = "#{listen.onCellEdit}" 
            update = ":form:msgs"/>

            <p:column filterBy = "#{prod.value1}" filterMatchMode = "contains" 
            style = "width: 300px;" headerText = "Name">

                <p:cellEditor>

                    <f:facet name = "output"><h:outputText value = "# 
                    {prod.value1}" /></f:facet>

                    <f:facet name = "input"><p:inputTextarea rows = "2" value = "# 
                    {prod.value1}" style = "width: 96%"/></f:facet>
                </p:cellEditor>

            </p:column>

            <p:column style = "width: 140px;" headerText = "Vendor">

                <p:cellEditor >

                    <f:facet name = "output"><h:outputText value = "# 
                    {prod.value2}" /></f:facet>

                    <f:facet name = "input">
                        <h:selectOneMenu value = "#{prod.value2}" 
                        style = "width:100%">
                            <f:selectItem itemValue = "Y" itemLabel = "Yes"/>
                            <f:selectItem itemValue = "N" itemLabel = "No"/>
                        </h:selectOneMenu>

                    </f:facet>

                </p:cellEditor>

            </p:column>


            <p:column style = "width: 275px;" headerText = "Version Release">

                <p:cellEditor>  
                    <f:facet name = "output"><h:outputText value = "# 
                    {prod.value3}" /></f:facet>

                    <f:facet name = "input"><p:inputTextarea rows = "1" value = "# 
                    {prod.value3}" style = "width: 96%"/></f:facet>

                </p:cellEditor>
            </p:column> 

            <f:facet name = "footer">
            <div align = "left">
            <p:commandButton value = "post" action = "#{tables.showChange}" 
            ajax = "false"></p:commandButton>
            </div>
            </f:facet>


        </p:dataTable>

    </div>

     <p:contextMenu for = "products" widgetVar = "pMenu">   
    <p:menuitem value = "Edit Cell" icon = "pi pi-search" 
     onclick = "PF('prodCell').showCellEditor();return false;"/>  
    <p:menuitem value = "Hide Menu" icon = "pi pi-times" 
     onclick = "PF('pMenu').hide()"/>  
</p:contextMenu> 

</h:form>

Индекс.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns = "http://www.w3.org/1999/xhtml"
xmlns:ui = "http://java.sun.com/jsf/facelets"
xmlns:h = "http://java.sun.com/jsf/html"
xmlns:f = "http://java.sun.com/jsf/core"
xmlns:p = "http://primefaces.org/ui">


<h:head>

</h:head>
<h:body>

<h:form method = "post">

<h:commandButton value = "Contact Spreadsheet" ajax = "false" 
action = "#{listen.goTest}" ></h:commandButton>
</h:form>
</h:body>
</html>

Возможно, я нашел способ решить мою проблему, но используя логику. Никаких наблюдаемых или прослушивающих методов. Если у кого-то есть возможное решение, дайте мне знать!

John W 23.01.2019 17:12

Это именно то, для чего предназначен лист PFE: Primefaces.org/showcase-ext/sections/sheet/basicUsage.jsf, когда вы редактируете каждую ячейку, он точно отслеживает, какие строки были отредактированы, поэтому вы можете точно знать, что было изменено, и просто обновить эти записи и зафиксировать их.

Melloware 23.01.2019 17:45

Спасибо, Мелловер. Я не знал, что это существует. Вопрос по листу. Когда метод sheet.getUpdates() выполняется в управляемом компоненте, содержит ли результирующий список все измененные объекты строк?

John W 23.01.2019 19:29

Да, лист.getUpdates содержит все строки, которые были изменены с момента последнего вызова sheet.commitUpdates(); Таким образом, вы можете контролировать, когда сбрасывать обновления.

Melloware 24.01.2019 13:07

Большое спасибо за это. Я бы принял это как ответ, если бы вы разместили его как один.

John W 24.01.2019 15:31

Хорошо, я разместил как решение, большое спасибо!

Melloware 25.01.2019 13:19
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
6
120
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Решение, которое вам нужно, — это компонент Лист расширений PrimeFaces для поведения, которое вы ищете.

Лист удовлетворяет потребность, которую не удовлетворяет таблица данных PrimeFaces с редактированием в ячейке. Он может обрабатывать большой объем данных с редактированием отдельных ячеек без отправки всего листа. Знакомая навигация по электронным таблицам с помощью клавиш TAB и SHIFT+TAB, а также привычные возможности работы с электронными таблицами.

Особенности включают в себя:

  • Быстрое редактирование и проверка в ячейке
  • Выбор диапазона копирования/вставки, включая копирование/вставку и заливку
  • Сортировка
  • Фильтрация
  • Фиксированные столбцы и строки
  • Изменяемый размер столбцов и строк
  • Подвижные столбцы и строки
  • Обновления и проверка Ajax

На основе Handsontable от Handsoncode.

Другие вопросы по теме