Table 组件使用指南之二:基于Table的CRUD

本文介绍如何使用ADF框架实现基于Form的增删改查功能,包括弹出窗口实现增加和修改功能、双击弹出修改窗口、删除功能及ManagedBean完整代码。
运行环境:JDeveloper 11.1.2.1.0 + Oracle Database 10g Express Edition 10.2.0.1。

1. 采用弹出窗口的方式来实现增加和修改功能
个人比较喜欢这种方式,感觉比较自然。
(1)页面效果

(2)增加功能
在当前行的上一行增加一条记录。

(3)修改功能
修改当前行记录。

(4)删除功能
删除当前行,删除前有提示。


2. 增加和修改功能实现说明
(1)点击增加或修改按钮都是弹出一个窗口,即popup组件
<af:commandButton text="CreateInsert" id="cbInsert">
    <af:showPopupBehavior popupId="::popupEditOrInsert" triggerType="action" align="endAfter"/>
</af:commandButton>
<af:commandButton text="Edit" id="cbEdit">
    <af:showPopupBehavior popupId="::popupEditOrInsert" triggerType="action" align="endAfter"/>
</af:commandButton>

说明:在按钮上添加了showPopupBehavior操作后,将屏蔽按钮上的action或actionListener事件,也就是说不会再触发action或actionListener事件。
如果想要触发并执行完按钮上的action或actionListener方法,然后再弹出popup窗口,只能在action或actionListener方法中用代码弹出popup窗口。比如:
FacesContext facesContext = FacesContext.getCurrentInstance();
ExtendedRenderKitService service =
Service.getRenderKitService(facesContext, ExtendedRenderKitService.class);
service.addScript(facesContext, "AdfPage.PAGE.findComponent('popupDelete').show();");

(2)popup组件的代码
重要的属性说明如下:
contentDelivery="lazyUncached",因为每次弹出的内容都不同,因此不要Cache。
popupFetchListener,是popup组件窗口弹出时调用的方法。
popupCanceledListener,是关闭popup组件窗口时调用的方法,比如点击右上角的X关闭窗口。
dialogListener,负责监听用户点击了OK/Cancel按钮。
Form中绑定的Data Control和Table中绑定的Data Control一样。
                    
<af:popup id="popupEditOrInsert" contentDelivery="lazyUncached" childCreation="deferred"
      autoCancel="disabled"
      popupFetchListener="#{backingBeanScope.myBackingBean.editOrInsertPopupFetchListener}"
      popupCanceledListener="#{backingBeanScope.myBackingBean.editOrInsertPopupCancelListener}">
 <af:dialog id="dialogEditOrInsert" title="Edit or Insert" type="okCancel"
            dialogListener="#{backingBeanScope.myBackingBean.editOrInsertDialogListener}">
     <f:facet name="buttonBar"/>
     <af:panelFormLayout id="pfl1">
         <af:inputText value="#{bindings.JobId.inputValue}" label="#{bindings.JobId.hints.label}"
                       required="#{bindings.JobId.hints.mandatory}"
                       columns="#{bindings.JobId.hints.displayWidth}"
                       maximumLength="#{bindings.JobId.hints.precision}"
                       shortDesc="#{bindings.JobId.hints.tooltip}" id="it1">
             <f:validator binding="#{bindings.JobId.validator}"/>
         </af:inputText>
        ......
     </af:panelFormLayout>                    
 </af:dialog>
</af:popup>

(3)还有很重要的一点是,为panelCollection设置partialTriggers,指向popup组件id和dialog组件id。
这样无论是确定还是取消操作,都会局部刷新panelCollection,进而刷新Table。
<af:panelCollection id="pc1" partialTriggers="::popupEditOrInsert ::dialogEditOrInsert">

3. 双击某行,弹出修改窗口
双击弹出修改窗口,是一个比较常见的功能,在这里我使用af:clientListener + af:serverListener 方式实现。
(1)clientListener
<af:clientListener method="doubleClickOnTable" type="dblClick"/>
(2)serverListener 
<af:serverListener type="TableDoubleClickEvent"
method="#{backingBeanScope.myBackingBean.handleTableDoubleClick}"/>
(3)clientListener调用的javascript函数
<af:resource type="javascript" source="js/table_function.js"/>
其中包含doubleClickOnTable函数:
function doubleClickOnTable(evt) {
    var table = evt.getSource();
    AdfCustomEvent.queue(table, "TableDoubleClickEvent", {},true);
    evt.cancel();
}

(1)(2)(3)组合在一起,实现了双击弹出修改窗口功能,原理如下:
当双击事件(dblClick)发生时,监听该事件的clientListener触发了javascript方法:doubleClickOnTable,该方法向事件队列中异步地(true参数表示异步,false表示同步)压入一个事件:TableDoubleClickEvent,监听该事件的serverListener触发了Managed Bean中的方法handleTableDoubleClick。

4. 删除功能实现说明
详细说明请参考《 使用ADF实现基于Form的CRUD (2) 》。
<af:commandButton text="Delete" disabled="#{!bindings.Delete.enabled}" id="cbDelete">
  <af:showPopupBehavior popupId="popupDelete" triggerType="action" align="endAfter"/>
</af:commandButton>
<af:popup childCreation="deferred" autoCancel="disabled" id="popupDelete">
    <af:dialog id="dialogDelete" title="Confirm Delete"
               dialogListener="#{backingBeanScope.myBackingBean.deleteDialogListener}">
        <f:facet name="buttonBar"/>
        <af:outputText value="The record will be deleted, are you sure?" id="ot5"/>
    </af:dialog>
</af:popup>


5. Managed Bean完整代码 
package view;

import javax.faces.context.FacesContext;

import oracle.adf.model.BindingContext;
import oracle.adf.view.rich.event.DialogEvent;

import oracle.adf.view.rich.event.PopupCanceledEvent;
import oracle.adf.view.rich.event.PopupFetchEvent;

import oracle.adf.view.rich.render.ClientEvent;

import oracle.binding.BindingContainer;
import oracle.binding.OperationBinding;

import org.apache.myfaces.trinidad.render.ExtendedRenderKitService;
import org.apache.myfaces.trinidad.util.Service;

import view.util.ADFUtils;

public class MyBackingBean {
    public MyBackingBean() {
        super();
    }

    public void editOrInsertDialogListener(DialogEvent dialogEvent) {
        if (dialogEvent.getOutcome().equals(DialogEvent.Outcome.ok)) {
            OperationBinding operb = ADFUtils.findOperation("Commit");
            operb.execute();
        } else {
            OperationBinding operb = ADFUtils.findOperation("Rollback");
            operb.execute();
        }
    }

    public void editOrInsertPopupFetchListener(PopupFetchEvent popupFetchEvent) {
        if (popupFetchEvent.getLaunchSourceClientId() != null) {
            if (popupFetchEvent.getLaunchSourceClientId().contains("cbInsert")) {
                OperationBinding operb = ADFUtils.findOperation("CreateInsert");
                operb.execute();
            }
        }
    }

    public void editOrInsertPopupCancelListener(PopupCanceledEvent popupCanceledEvent) {
        OperationBinding operb = ADFUtils.findOperation("Rollback");
        operb.execute();
    }

    public void deleteDialogListener(DialogEvent dialogEvent) {
        if (dialogEvent.getOutcome().equals(DialogEvent.Outcome.ok)) {
            doDelete();
        }
    }

    private void doDelete() {
        OperationBinding operb = ADFUtils.findOperation("Delete");
        Object result = operb.execute();
        if (operb.getErrors().isEmpty()) {
            operb = ADFUtils.findOperation("Commit");
            operb.execute();
        }
    }

    public void handleTableDoubleClick(ClientEvent clientEvent) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExtendedRenderKitService service = Service.getRenderKitService(facesContext, ExtendedRenderKitService.class);
        service.addScript(facesContext, "AdfPage.PAGE.findComponent('popupEditOrInsert').show();");
    }
}


Project 下载: ADF_Table_CRUD.7z

参考文献:
1. http://andrejusb.blogspot.com/2007/04/create-edit-and-delete-operations-in.html
2. http://andrejusb.blogspot.com/2007/11/jdeveloper-11g-create-edit-and-delete.html
3. http://andrejusb.blogspot.com/2009/11/crud-operations-in-oracle-adf-11g-table.html
4. http://andrejusb.blogspot.com/2009/11/crud-operations-in-jdeveloperadf-11g-r1.html

5. http://andrejusb.blogspot.com/2010/05/crud-operations-in-oracle-adf-11g-table.html

http://maping930883.blogspot.com/2010/04/adf072table-tablecrud.html

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值