Sort in a tableview
Hello,
my internal table has 10 records which are displayed in a Tableview. The user has the option to sort the information (asc/desc) according to the column which he wishes. Then he has to select a line to display the data of this record. It works perfect if there´s no sort but if the user sorts the table, the internal table is not sorted.
If the user selects record 3 on the Tableview, that record could be Nr. 9 in my internal table. How can I sort at the same time my internal table ??
Thanks
Coding
<htmlb:tableView id = "result_mat"
selectionMode = "SINGLESELECT"
headerText = "<%= otr(SOTR_VOCABULARY_BASIC/RESULT) %><%= otr(SOTR_VOCABULARY_BASIC/LIST) %>"
headerVisible = "true"
emptyTableText = "<%= otr(/SIE/AD_ZDXD0001/SUCHEF4) %>"
sort = "SERVER"
visibleRowCount = "12"
columnDefinitions = "<%=columns%>"
onRowSelection = "EventRowSelection"
table = "<%= tab_material %>" />
you can handle it in two ways, to have sort and also reading the right selected record from the itab.
option1. instead of using SORT = "SERVER" use "APPLICATION" in this case you have to manually handle the sort.
code sample for the same.
page attributes:
sort_element TYPE STRING
sort_event TYPE STRING
s_event TYPE CHAR1
layout
<% if sort_event is initial .
move: 'A' to sort_event .
endif .
if sort_event eq 'A' .
if not sort_element is initial .
sort <outtab> ascending by (sort_element).
else .
sort <outtab> ascending .
endif .
elseif sort_event eq 'D' .
if not sort_element is initial .
sort <outtab> descending by (sort_element).
else .
sort <outtab> descending .
endif .
endif .
%>
<htmlb:tableView id = "test"
headerVisible = "false"
footerVisible = "true"
onHeaderClick = "<%= sort_event %>"
table = "<%= <outtab> %>"
iterator = "<%= grid_iterator %>"
columnDefinitions = "<%= col_control_tab %>"
width = "100%"
columnHeaderVisible = "true"
sort = "APPLICATION" />
oninputprocessing.
CLEAR s_event .
CLASS cl_htmlb_manager DEFINITION LOAD.
DATA: event TYPE REF TO cl_htmlb_event .
data: tv type ref to cl_htmlb_tableview.
data: tv_data type ref to cl_htmlb_event_tableview.
event = cl_htmlb_manager=>get_event( request ).
IF event->event_type EQ cl_htmlb_event_tableview=>co_header_click .
s_event = 'Y' .
tv ?= cl_htmlb_manager=>get_data(
request = runtime->server->request
name = 'tableView'
id = 'test' ).
if tv is not initial.
tv_data = tv->data.
endif .
sort_element = tv_data->column_key .
if event->SERVER_EVENT eq 'A' .
sort_event = 'D' .
elseif event->SERVER_EVENT eq 'D' .
sort_event = 'A' .
endif .
ENDIF .
option 2:
use keyColumn = "<itab key filed name in uppercase>"
<htmlb:tableView id = "test"
design = "ALTERNATING"
headerVisible = "true"
headerText = "List of Low Value Assets"
table = "<%= det_tab %>"
width = "100%"
columnHeaderVisible = "true"
sort = "SERVER"
filter = "SERVER"
filterButtonText = "Go"
columnDefinitions = "<%= col_control_tab %>"
keepSelectedRow = "TRUE"
<b> keyColumn = "KEY_COL"</b>
where key_col is a column in the itab which holds the concatenated value of key fields.
for example if your itab has say order no., item number, value and the key is order number and item number.
concatenate them and place it in the key_col field and dont show that in display mode.
and in oninputprocessing you can read the selected row value like below.
if event->event_type eq cl_htmlb_event_tableview=>co_row_selection .
data: tv type ref to cl_htmlb_tableview.
tv ?= cl_htmlb_manager=>get_data(
request = runtime->server->request
name = 'tableView'
id = 'test' ).
if tv is not initial.
data: tv_data type ref to cl_htmlb_event_tableview.
tv_data = tv->data.
if tv_data->selectedrowindex is not initial.
data: row like line of <itab> .
either you can use this index to read the itab or
tv_data->selectedrowkey will hold the selected rows key_col value which you can use to read the itab.
Hope this helps.
Regards
Raja
Similar Messages
-
Bug or feature: TableView sorts the underlying list?
that's at least highly unexpected - all variants of table sorting I know, support some kind of sortedView on top of the user model (either by a framework outside of the table, as GlazedList, or internal as core swing).
Is it a not-yet-done feature or yet another variant of leaving the hard stuff to the user dev?
CU
JeanetteJonathanGiles wrote:
This is by-design. We consider the items list in the TableView to be the view model - clicking on a column results in the view model being sorted.
There are ways around this. If you provide a TransformationList (e.g. SortedList) wrapped around an ObservableList, the TableView will sort the SortedList, leaving the underlying ObservableList unsorted and still available via SortedList.getDirectSource() or getBottomMostSource() (depending on how many layers of wrapping you have).that's exactly what I keep complaining about:
- framework handles the trivial stuff: it simply pushes a comparator into a sortable list is or lets collections.sort do the work
- developers are left with the harder parts like index mapping
Actually, the framework is hit by those missing harder parts as well:
- SortedList freaks out on mutable elements, basically because the internal index mapping is not optimal (http://javafx-jira.kenai.com/browse/RT-14965)
- Selection synch is broken when sorting/filtering (and TableView taking the extreme easy way out in clearing ... tseee), don't have a report handy, but know that you are aware of the issue : - )
- no way to "unsort" a TableColumn (http://javafx-jira.kenai.com/browse/RT-15166) in the general case. Even for a SortedList, that would involve to restore the original comparator (instead of leaving the TableColumnComparator in place)
Cheers
Jeanette -
Getting filtered values from TableView
Hi,
We have a TableView whose columns can be sorted. Iwant to select a few rows and make the selected rows editable in another page.
If it is a unsorted/unfiltered TableView, am able to do it as the ABAP Internal Table and the TableView are the same in terms of record index positions. But am facing problem after i sort/filter the TableView because now the index of the TableView are different from the index of the ABAP Internal Table present in server.
Anybody who has dealt with this problem earlier and can guide us.
Thanks,
Chathia.Welcome to SDN.
Search the forum before you post a question, generally in mose cases you would find a answer, if not you can post a new thread.
here is a list of threads where your question was discussed. (as others mentioned its about using keyColumn attribute of htmlb:tableview)
check out these threads, its got code samples as well.
Re: HTMLB Tableview: questions..;
Re: pic actual data from a table view
Re: Error when using Filter and Sort together on a tableview
Re: Change rendering of the title column...
Have a great time in SDN.
Regards
Raja -
How do i change the cursor on a jtable header when clicked for sorting?
here is my question, how do i change the cursor on a jtable header when I click the header for sorting?
I think it is suppose to be in the fragment of code where the header listener is implemented for sorting, but I'm not quite sure what is the exact component that holds everything so that i can change the cursor...
below is what I've tried, but it doesn't seem to work... thank you
public void addMouseListenerToHeaderInTable(JTable table) {
final TableSorter sorter = this;
final JTable tableView = table;
tableView.setColumnSelectionAllowed(false);
MouseAdapter listMouseListener = new
MouseAdapter() {
public void mouseClicked(MouseEvent e) {
TableColumnModel columnModel =
tableView.getColumnModel();
int viewColumn =
columnModel.getColumnIndexAtX(e.getX());
int column =
tableView.convertColumnIndexToModel
(viewColumn);
System.out.println("column = "+column);
if (e.getClickCount() == 1 && column != -1) {
System.out.println("Sorting ...");
Cursor oldCursor =
tableView.getRootPane().getCursor();
System.out.println("oldCursor.getType()
= "+oldCursor.getType());
if (oldCursor.getType() !=
Cursor.WAIT_CURSOR){
JComponent parentPane =
tableView.getRootPane();
parentPane.getContentPane().setCursor
(new Cursor(Cursor.WAIT_CURSOR));
parentPane.setCursor(new Cursor
(Cursor.WAIT_CURSOR));
Cursor newCursor =
parentPane.getCursor();
System.out.println("newCursor.getType
() = "+newCursor.getType());
int shiftPressed = e.getModifiers(
&InputEvent.SHIFT_MASK;
boolean ascending = (shiftPressed == 0);
//System.out.println("tableView.getRootPane()
is "+tableView.getRootPane().getRootPane());
sorter.sortByColumn(column, ascending);
tableView.getRootPane().setCursor(new Cursor
(Cursor.DEFAULT_CURSOR));
//System.out.println("Done sorting");
JTableHeader th = tableView.getTableHeader();
th.addMouseListener(listMouseListener);
}Hi,
Try setting the cursor for the table header.
table.getHeader().setCursor(Wait_Cursor);
Bala. -
SORT in a BSP applicaiton doesnt work
Hi Experts,
In my BSP Application , I use a table and below is code for the
<htmlb:tableView id = "WRKLST"
headerText = "My Worklists"
headerVisible = "true"
design = "alternating"
visibleRowCount = "<%= RowCount%>"
filter = "SERVER"
sort = "server"
fillUpEmptyRows = "TRUE"
emptyTableText = "No entries found"
onHeaderClick = "MyEventHeaderClick"
onRowSelection = "rowselection"
selectionMode = "multiselect"
table = "<%= IT_WRKLIST %>"
iterator ="<%= iterator%>" >
But the sort is not very efficient. ie., it always sort only on the first click of the header 's. and also it sort only on key field.
Can anybody suggest me an option , so that on every click it sorts ascending / descending based on the click of the header.
ie., If the user clicks on 'Partner Name' , it should sort the table content based on Partner name and if the click on 'Priority', it should sort on priority.
Please suggest.
Regards,
ShinyDear Shiny
Please check these posts.
I think you will need to sort the table yourself and then have the page refreshed.
[Sort in a tableview;
[Table Sort;
Kind Regards
/Ricardo Quintas -
How to set filters to a Result view
Hi All,
How to set filters to a result view in web UI.
Thanks & Regards
Nitish.Hi Nitish Kumar,
if you want to sort the table fields like ascending , Descending create one event ex: eh_on_sorting.
in that get the event using thtmlb_event. then check whether sorting is necessary or not.
then get the name of column to be sort by using tableview->column_key.
based on that arrange the field ascending or descending using tableview->column_sort_directin.
ascending or descending.
then sort the collection using collection_wrappor->sort( lv_attrname .. etc).
here is the sample code..
data: lv_bo type ref to if_bol_bo_property_access,
lv_thtmlb_tableview type ref to cl_thtmlb_table_view,
lv_attr_name type name_komp,
lv_sort_order type char1,
lv_stable type abap_bool value abap_false.
try.
lv_thtmlb_tableview ?= iv_htmlb_event_ex.
catch cx_sy_move_cast_error.
exit.
endtry.
if lv_thtmlb_tableview is bound.
* check whether its realy a sorting event
check lv_thtmlb_tableview->event_type = cl_thtmlb_table_view=>co_header_click.
* get name of column to be sorted
lv_attr_name = lv_thtmlb_tableview->column_key.
check lv_attr_name is not initial.
* get sorting direction
case lv_thtmlb_tableview->column_sort_direction.
when 'U'.
lv_sort_order = cl_bsp_wd_collection_wrapper=>sort_ascending.
when 'D'.
lv_sort_order = cl_bsp_wd_collection_wrapper=>sort_descending.
when others.
return.
endcase.
* sort
try.
me->collection_wrapper->sort( iv_attr_name = lv_attr_name
iv_sort_order = lv_sort_order
iv_stable = lv_stable
* IV_SORT_CALLBACK =
catch cx_crm_cic_parameter_error.
* could be a renamed attribute or field which does not belong to the collection
endtry.
* in case of single selection restore the selected row index
if me->selection_mode = selmode_single
or me->selection_mode = selmode_lineedit.
if me->selected_index <> '0'.
me->selected_index = me->collection_wrapper->get_current_index( ).
endif.
endif.
else.
exit.
endif.
Thanks & Regards,
Srinivask -
JTable - make column headers clickable
Hi all
I have a JTable, and now I want to sort by column. I've actually got the column sorting working using menu items, but how can I make my column header clickable, and where do I add an actionListener to?public void addMouseListenerToHeaderInTable(JTable table) {
final JTable tableView = table;
tableView.setColumnSelectionAllowed(false);
MouseAdapter listMouseListener = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
TableColumnModel columnModel = tableView.getColumnModel();
int viewColumn = columnModel.getColumnIndexAtX(e.getX());
int column = tableView.convertColumnIndexToModel(viewColumn);
if (e.getClickCount() == 1 && column != -1) {
int shiftPressed = e.getModifiers() & InputEvent.SHIFT_MASK;
boolean ascending = (shiftPressed == 0);
// sort
JTableHeader th = tableView.getTableHeader();
th.addMouseListener(listMouseListener);
} -
TableView - How to update a running balance column after any other column in the view is re-sorted
To keep this simple and to illustrate a problem that I am trying to solve let's say we have
a domain class that contains an income per day.
This class has two persistent properties - populated from a database table - date and income.
And there is one transient property - running balance - that shows the accumulated income
starting from the first record. This property is not persisted and it is used only to show
the running/accumulated income in a table view.
This domain object is shown in a table view with three columns:
- date
- income
- running balance
The first two columns - date and income - are sortable. When the user clicks on the column
heading these can will be sorted in ascending or descending order. The running balance
column needs to reflect this change and be correctly updated.
So the question is : how would you implement the running balance update after the data in
the table has been updated by the user?
Take 1)
=============
The obvious approach is to use "setOnSort" method to consume the SortEvent event and re-sort the
data but the sort-event does not contain any useful information that would tell from which column
the sort event originated.
Take 2)
=============
Found a possible solution:
- TableView.getSortOrder() returns a list that defines the order in which TableColumn instances are sorted after the user clicked one or more column headings.
- TableColumn.getSortType() returns the sort type - ascending/descending.
- This info can be used in the TableView.setOnSort() event handler to re-sort the data and update the balance at the same time.
Take 3)
=============
When the TableView.setOnSort() event handler is called the data is already sorted therefore the only thing that needs to be done is to update the running balance.I think I understand what you're trying to do. If I've missed it, apologies, but I think this will provide you with something you can work from anyway.
I would listen to the data instead of watching specifically for sorting. This will be much more robust if you add new functionality later (such as adding and removing rows, editing the data that's there, etc).
Specifically, for the runningBalance column, create a cellValueFactory that provides a DoubleBinding; this binding should listen for changes to the data and compute the value by running through the table's items up to the point of the item for which it's displaying the value. (Hope you can untangle that sentence.)
Example. The important part is the cellValueFactory for the cumulativeAmountCol. I guess I should mention that you shouldn't try this exact approach with very large tables as the performance might be pretty bad (computations of the order of n x m on changing data, where n is the number of rows in the table and m is the number of visible rows in the table).
import java.text.DateFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.binding.DoubleBinding;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class CumulativeTableColumnExample extends Application {
private final static int NUM_ITEMS = 20 ;
@Override
public void start(Stage primaryStage) {
final TableView<LineItem> table = new TableView<>();
// using the extractor here makes sure the table item list fires a list changed event if any amounts change
// this enables the cumulative amount column to keep up to date when the amount in a different row changes.
table.setItems(FXCollections.observableList(createRandomData(), new Callback<LineItem, Observable[]>() {
@Override
public Observable[] call(LineItem item) {
return new Observable[] {item.amountProperty()};
final TableColumn<LineItem, Date> dateCol = new TableColumn<>("Date");
final TableColumn<LineItem, Number> amountCol = new TableColumn<>("Amount");
final TableColumn<LineItem, Number> cumulativeAmountCol = new TableColumn<>("Cumulative Amount");
table.getColumns().addAll(Arrays.asList(dateCol, amountCol, cumulativeAmountCol));
dateCol.setCellValueFactory(new PropertyValueFactory<LineItem, Date>("date"));
amountCol.setCellValueFactory(new PropertyValueFactory<LineItem, Number>("amount"));
cumulativeAmountCol.setCellValueFactory(new PropertyValueFactory<LineItem, Number>("amount"));
cumulativeAmountCol.setSortable(false); // otherwise bad things might happen
final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT);
dateCol.setCellFactory(new Callback<TableColumn<LineItem, Date>, TableCell<LineItem, Date>>() {
@Override
public TableCell<LineItem, Date> call(TableColumn<LineItem, Date> col) {
return new TableCell<LineItem, Date>() {
@Override
public void updateItem(Date date, boolean empty) {
super.updateItem(date, empty);
if (empty) {
setText(null);
} else {
setText(dateFormat.format(date));
cumulativeAmountCol.setCellValueFactory(new Callback<CellDataFeatures<LineItem, Number>, ObservableValue<Number>> () {
@Override
public ObservableValue<Number> call(CellDataFeatures<LineItem, Number> cellData) {
final LineItem currentItem = cellData.getValue() ;
DoubleBinding value = new DoubleBinding() {
super.bind(table.getItems());
@Override
protected double computeValue() {
double total = 0 ;
LineItem item = null ;
for (Iterator<LineItem> iterator = table.getItems().iterator(); iterator.hasNext() && item != currentItem; ) {
item = iterator.next() ;
total = total + item.getAmount() ;
return total ;
return value;
final NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();
// generics hell.. can't wait for lambdas...
final Callback<TableColumn<LineItem, Number>, TableCell<LineItem, Number>> currencyCellFactory = new Callback<TableColumn<LineItem, Number>, TableCell<LineItem, Number>>() {
@Override
public TableCell<LineItem, Number> call(TableColumn<LineItem, Number> column) {
return new TableCell<LineItem, Number>() {
@Override
public void updateItem(Number amount, boolean empty) {
if (empty) {
setText(null) ;
} else {
setText(currencyFormat.format(amount));
amountCol.setCellFactory(currencyCellFactory);
cumulativeAmountCol.setCellFactory(currencyCellFactory);
BorderPane root = new BorderPane();
root.setCenter(table);
primaryStage.setScene(new Scene(root, 600, 400));
primaryStage.show();
public List<LineItem> createRandomData() {
Random rng = new Random();
List<LineItem> items = new ArrayList<>();
for (int i=0; i<NUM_ITEMS; i++) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_YEAR, rng.nextInt(365)-365);
double amount = (rng.nextInt(90000)+10000)/100.0 ;
items.add(new LineItem(cal.getTime(), amount));
return items ;
public static void main(String[] args) {
launch(args);
public static class LineItem {
private final ObjectProperty<Date> date ;
private final DoubleProperty amount ;
public LineItem(Date date, double amount) {
this.date = new SimpleObjectProperty<>(this, "date", date);
this.amount = new SimpleDoubleProperty(this, "amount", amount);
public final ObjectProperty<Date> dateProperty() {
return date;
public final Date getDate() {
return date.get();
public final void setDate(Date date) {
this.date.set(date);
public final DoubleProperty amountProperty() {
return amount ;
public final double getAmount() {
return amount.get();
public final void setAmount(double amount) {
this.amount.set(amount); -
TableView: sort="server" with iterator-generated cell content
I have an htmlb:tableView that uses an iterator and sort ="SERVER".
In one of the columns, I change the text that is displayed a little bit in RENDER_CELL_START of the iterator.
DATA lr_text TYPE REF TO cl_htmlb_textview.
FIELD-SYMBOLS <fs_row> LIKE LINE OF me->t_bla.
ASSIGN p_row_data_ref->* TO <fs_row>.
CASE p_column_key.
WHEN 'MY_FIELDNAME'.
CREATE OBJECT lr_text.
lr_text->id = p_cell_id.
lr_text->text = me->get_name( <fs_row>-id ).
p_replacement_bee = lr_text.
Now, if I click on the sort icon of the column, the table is sorted by the field 'MY_FIELDNAME', but not by the actual content of the column.
How would I achieve that?this sounds almost possible.
I cannot write the new value into the original field of the table though, because I cannot be sure that the datatypes fit to each other and because I stil need the original values.
But I could of course add some more fields to the table structure (which I would not like so much), loop at the table before I use it in the tableView and write the new values into these fields.
Then, I wouldn't even need RENDER_CELL_START at all. -
I have been trying to get a tableview to be sortable by clicking on the header of columns. I have been reviewing existing threads on the forum in particular the one below.
https://forums.sdn.sap.com/thread.jspa?threadID=16417
I seem to understand the concept but for some reason my table does not sort, it just does nothing. Could someone take a look and see if you can find any problems - I can't wait to give points.
Here is all my code.
Here is the Java....
package MSSPackage;
import MSSBeanPackage.PositionOverviewBean;
import MSSPackage.SortTableModel;
import com.sapportals.htmlb.page.DynPage;
import com.sapportals.htmlb.page.PageException;
import com.sapportals.portal.htmlb.page.JSPDynPage;
import com.sapportals.portal.htmlb.page.PageProcessorComponent;
import com.sapportals.portal.prt.component.IPortalComponentContext;
import com.sapportals.portal.prt.component.IPortalComponentProfile;
import com.sapportals.portal.prt.component.IPortalComponentRequest;
import com.sapportals.portal.prt.component.IPortalComponentSession;
import com.sapportals.htmlb.event.*;
import com.sapportals.htmlb.*;
import com.sapportals.htmlb.table.*;
import com.sapportals.htmlb.table.DefaultTableViewModel;
import javax.servlet.http.*;
// SAP RFC Imports
import com.sap.mw.jco.IFunctionTemplate;
import com.sap.mw.jco.JCO;
import com.sapportals.portal.prt.service.jco.IJCOClientPoolEntry;
import com.sapportals.portal.prt.service.jco.IJCOClientService;
import com.sapportals.portal.prt.runtime.PortalRuntime;
import java.util.*;
public class PositionOverview extends PageProcessorComponent {
public DynPage getPage(){
return new PositionOverviewDynPage();
public static class PositionOverviewDynPage extends JSPDynPage{
JCO.Repository mRepository;
public JCO.Table tblRelations;
public JCO.Table tblPositions;
public SortTableModel tableModel;
public int visibleRow = 1;
private boolean OrgUnitSelected = false;
public void doInitialization(){
IPortalComponentSession oSession = ((IPortalComponentRequest)getRequest()).getComponentSession();
PositionOverviewBean oBean = new PositionOverviewBean();
// Table Start row
oBean.setvisibleRow(new Integer(this.visibleRow).toString());
oSession.putValue("myBean", oBean);
// Define request, context and profile containers
IPortalComponentRequest request = (IPortalComponentRequest) this.getRequest();
IPortalComponentContext myContext = request.getComponentContext();
IPortalComponentProfile myProfile = myContext.getProfile();
// Define bean reference to bean
PositionOverviewBean myBean = new PositionOverviewBean();
// Table Start row
myBean.setvisibleRow(new Integer(this.visibleRow).toString());
// Place bean in user profile.
myProfile.putValue("myBean", myBean);
public void doProcessAfterInput() throws PageException {
public void doProcessBeforeOutput() throws PageException {
String NavType = "RCORGUNIT";
String OType = "O";
//String OBjid = "10004399";
String OBjid = "";
String sapSystem = "SAP_R3_HumanResources";
IPortalComponentSession oSession = ((IPortalComponentRequest)getRequest()).getComponentSession();
PositionOverviewBean myBean = (PositionOverviewBean) oSession.getValue("myBean");
// Define request, context and profile containers
IPortalComponentRequest request = (IPortalComponentRequest) this.getRequest();
/* IPortalComponentContext myContext = request.getComponentContext();
IPortalComponentProfile myProfile = myContext.getProfile();
//HttpSession session = request.getServletRequest().getSession(); //dmm
//Get Bean from Profile
PositionOverviewBean myBean = (PositionOverviewBean) myProfile.getValue("myBean");
//PositionOverviewBean myDataBean = (PositionOverviewBean) session.getValue("POviewBean"); //dmm
String ddlbSelection = "";
String ddlbValue = "";
DropdownListBox ddlbOrgUnits = (DropdownListBox) getComponentByName("ddlbOrgUnits");
if (ddlbOrgUnits != null)
ddlbSelection = ddlbOrgUnits.getSelection();
ddlbValue = ddlbOrgUnits.getValueAsDataType().getValueAsString();
OBjid = ddlbValue;
myBean.setObjId(OBjid);
else
OBjid = "";
myBean.setObjId(OBjid);
IJCOClientService clientService;
IJCOClientPoolEntry poolEntry;
JCO.Client client;
try
clientService = (IJCOClientService) PortalRuntime.getRuntimeResources().getService(IJCOClientService.KEY);
poolEntry = clientService.getJCOClientPoolEntry(sapSystem, request);
client = poolEntry.getJCOClient();
// connect to SAP system, logon
client.connect();
// Create Jco Repository Object
mRepository = new JCO.Repository("R3USERMENU", client);
// Reset function object
JCO.Function function = null;
// Run RFC Module on SAP system
function = this.createFunction("HRWPC_GET_NAV_OBJECTS");
JCO.ParameterList input = function.getImportParameterList();
input.setValue("RCORGUNIT", "NAVTYPE");
client.execute(function);
tblRelations = function.getTableParameterList().getTable("RESULT_OBJEC");
myBean.setRowcnt(tblRelations.getNumRows());
if (tblRelations.getNumRows() != 0)
myBean.setOrgUnits(tblRelations);
if (ddlbOrgUnits == null)
// check to see if there is not a position id already assigned
tblRelations.setRow(0);
OBjid = tblRelations.getString("OBJID");
myBean.setObjId(OBjid);
//myBean.sTemp = OBjid;
// GET THE POSITION DETAILS
function = null;
input = null;
function = this.createFunction("Z_GET_POSITION_OVERVIEW");
input = function.getImportParameterList();
input.setValue(NavType, "NAVTYPE");
input.setValue(OType, "OTYPE");
input.setValue(OBjid, "OBJID");
client.execute(function);
tblPositions = function.getTableParameterList().getTable("RESULT_OBJEC");
myBean.setRowcnt(tblPositions.getNumRows());
tableViewFormat();
tableModel.setTesting("Startxxxx");
myBean.settableModel(tableModel);
//tableModel.setTesting("SSSS");
//myDataBean.settableModel(tableModel); //dmm
//session.setAttribute("POviewBean", myDataBean); //dmm
oSession.putValue("myBean", myBean);
//Release pool entry
poolEntry.release();
catch(Exception ex)
//name = ex.getMessage();
//String sTest = "this is a test";
//request.getComponentSession().putValue("Test", sTest);
//myProfile.putValue("Testx", sTest);
this.setJspName("PositionOverviewJSP.jsp");
public void getPositions()
String NavType;
String Root_Ot;
String Root_ObjId;
public void tableViewFormat()
// Define the vectors used to build tableView
Vector tempRec = new Vector();
Vector dataRec = new Vector();
String sDate = "";
String sPosLink = "";
String sPosVal = "";
String sENameLink = "";
String sENameVal = "";
String sStatus = "";
// Loop at company code list and add to vectors
for (int i = 0; i < tblPositions.getNumRows(); i++)
tblPositions.setRow(i);
tempRec = new Vector();
sStatus = (String) tblPositions.getString("STATUS");
if (sStatus != null)
if (sStatus.equals("0"))
sDate = tblPositions.getString("ZHR_VACANT_BEGDA");
sDate = sDate.substring(5, 7) + "/" + sDate.substring(8, 10) + "/" + sDate.substring(0, 4);
else
sDate = "";
sPosVal = tblPositions.getString("STEXT");
sENameVal = tblPositions.getString("ENAME");
if (sPosVal.equals(""))
sPosLink = sPosVal;
else
sPosLink = "<a HREF="myLink" onclick="return EPCM.doNavigate('ROLES://portal_content/com.sap.portal.migrated/ep_5.0/pages/com.sap.pct.hcm.positionprofile?CKey=000000" + tblPositions.getString("OBJID") + "', 1)">" + tblPositions.getString("STEXT") + "</a>";
if (sENameVal.equals(""))
sENameLink = sENameVal;
else
sENameLink = "<a HREF="myLink" onclick="return EPCM.doNavigate('ROLES://portal_content/com.phi/com.phi.mgt/com.phi.mss/com.phi.hr/com.phi.pages/com.phi.mgt.mss.hr.pages.positionholder?CKey=000000" + tblPositions.getString("OBJID") + "', 1)">" + tblPositions.getString("ENAME") + "</a>";
tempRec.addElement(sStatus);
tempRec.addElement(tblPositions.getString("OBJID"));
tempRec.addElement(sPosLink);
tempRec.addElement(sENameLink);
tempRec.addElement(sDate);
dataRec.addElement(tempRec);
// Then define the technical column names
Vector colNames = new Vector();
colNames.addElement("STATUS");
colNames.addElement("OBJID");
colNames.addElement("STEXT");
colNames.addElement("ENAME");
colNames.addElement("ZHR_VACANT_BEGDA");
// Now we build the actual tableView
//tableModel = new DefaultTableViewModel(dataRec, colNames);
tableModel = new SortTableModel(dataRec, colNames, 5);
// Define tableView parameters
tableModel.setKeyColumn(2);
TableColumn column = tableModel.getColumn("STATUS");
column.setEncode(false);
column.setType(com.sapportals.htmlb.enum.TableColumnType.USER);
column.setTitle("Vacant");
column = tableModel.getColumn("OBJID");
column.setTitle("Position Number");
column = tableModel.getColumn("STEXT");
column.setTitle("Position");
column = tableModel.getColumn("ENAME");
column.setTitle("Holder of Position");
column = tableModel.getColumn("ZHR_VACANT_BEGDA");
column.setTitle("Vacant as of");
// * Navigation Button Clicked
public void myOnNavigate(Event event)
TableNavigationEvent tne = (TableNavigationEvent) event;
visibleRow = tne.getFirstVisibleRowAfter();
// Define request, context and profile containers
IPortalComponentRequest request = (IPortalComponentRequest) this.getRequest();
IPortalComponentContext myContext = request.getComponentContext();
IPortalComponentProfile myProfile = myContext.getProfile();
// Get Bean from profile
PositionOverviewBean myBean = (PositionOverviewBean) myProfile.getValue("myBean");
// Table Start row
myBean.setvisibleRow(new Integer(this.visibleRow).toString());
public void onHeaderClick(Event event)
IPortalComponentSession oSession = ((IPortalComponentRequest)getRequest()).getComponentSession();
PositionOverviewBean myBean = (PositionOverviewBean) oSession.getValue("myBean");
TableHeaderClickEvent tne = (TableHeaderClickEvent) event; // get the event
SortTableModel tblModel = myBean.gettableModel();
//tblModel.sort();
int col = 3;
tblModel.sortByColumn(col);
myBean.settableModel(tblModel);
oSession.putValue("myBean", myBean);
// Create Function object for RFC Calls
public JCO.Function createFunction(String name) throws Exception
try
IFunctionTemplate ft = mRepository.getFunctionTemplate(name.toUpperCase());
if (ft == null)
return null;
return ft.getFunction();
catch (Exception ex)
ex.printStackTrace();
throw new Exception("Problem retrieving JCO.Function object");
public void onSelectddlbOrgUnits(Event event) throws PageException
OrgUnitSelected = true;
Here is the JSP
<%@ page import="com.sap.mw.jco.*" %>
<%@ page import="com.sapportals.htmlb.enum.*" %>
<%@ page import="MSSPackage.TableViewCellRenderer" %>
<%@ page import="com.sapportals.portal.prt.component.IPortalComponentRequest" %>
<%@ page import="javax.servlet.http.*" %>
<%@ page import="com.sapportals.portal.prt.component.IPortalComponentContext" %>
<%@ taglib uri="tagLib" prefix="hbj" %>
<hbj:content id="myContext" >
<hbj:page title="PageTitle">
<hbj:form id="myFormId" >
<jsp:useBean id="myBean" scope="session" class="MSSBeanPackage.PositionOverviewBean" />
<hbj:gridLayout rowSize="1" columnSize="1" cellSpacing="1">
<hbj:gridLayoutCell columnIndex="1" rowIndex="1">
<hbj:textView id="ddlbLable" text="Select organizational unit to display positions" design="STANDARD" />
</hbj:gridLayoutCell>
<hbj:gridLayoutCell columnIndex="1" rowIndex="2">
<hbj:dropdownListBox id="ddlbOrgUnits" onSelect="onSelectddlbOrgUnits" selection="<%=myBean.getObjId()%>">
<%
JCO.Table org_units = null;
org_units = myBean.getOrgUnits();
for (int i = 0; i < org_units.getNumRows(); i++)
org_units.setRow(i);
String sUnit = org_units.getString("STEXT");
String Unit_Id = org_units.getString("OBJID");
%>
<hbj:listBoxItem key="<%=Unit_Id%>" value="<%=sUnit%>" />
<%
%>
</hbj:dropdownListBox>
</hbj:gridLayoutCell>
<hbj:gridLayoutCell columnIndex="1" rowIndex="3">
<hbj:textView id="listLable" text="To designate a vacant position, click the icon in the 'Create Form' column" design="STANDARD" />
</hbj:gridLayoutCell>
<hbj:gridLayoutCell columnIndex="1" rowIndex="4">
<hbj:tableView
id="myTableView"
headerVisible="true"
footerVisible="true"
fillUpEmptyRows="true"
selectionMode="NONE"
navigationMode="BYPAGE"
onNavigate="myOnNavigate"
visibleFirstRow="<%= myBean.getvisibleRow() %>"
visibleRowCount="5" >
<%
myTableView.setOnHeaderClick("onHeaderClick");
myTableView.setUserTypeCellRenderer(new TableViewCellRenderer());
myTableView.setModel(myBean.gettableModel());
myTableView.setColumnType(TableColumnType.LINK, 3);
myTableView.setColumnType(TableColumnType.LINK, 4);
%>
</hbj:tableView>
</hbj:gridLayoutCell>
</hbj:gridLayout>
</hbj:form>
</hbj:page>
</hbj:content>
Here is the BEAN
package MSSBeanPackage;
//import com.sapportals.htmlb.enum.TableColumnType;
import MSSPackage.SortTableModel;
import com.sapportals.htmlb.table.DefaultTableViewModel;
//import com.sapportals.htmlb.table.TableColumn;
//import com.sapportals.htmlb.table.TableView;
//import com.sapportals.htmlb.table.TableViewModel;
import com.sap.mw.jco.JCO;
import com.sap.mw.jco.JCO.Table;
public class PositionOverviewBean {
// public DefaultTableViewModel tableModel;
public SortTableModel tableModel;
public JCO.Table OrgUnits;
public String ObjId;
public String visibleRow;
public int rowcnt;
public String sTemp;
// Get and Set methods for table model
// public DefaultTableViewModel gettableModel() { return tableModel; }
// public void settableModel(DefaultTableViewModel tableModel) { this.tableModel = tableModel; }
public SortTableModel gettableModel() { return tableModel; }
public void settableModel(SortTableModel IntableModel) { this.tableModel = IntableModel; }
public JCO.Table getOrgUnits() { return OrgUnits; }
public void setOrgUnits(JCO.Table value) { this.OrgUnits = value; }
// Get and Set methods for visiblerow
public String getvisibleRow() { return visibleRow; }
public void setvisibleRow(String visibleRow) { this.visibleRow = visibleRow; }
public int getRowcnt() { return this.rowcnt; }
public void setRowcnt(int rowcnt) { this.rowcnt = rowcnt; }
public String getObjId() { return this.ObjId; }
public void setObjId(String value) { this.ObjId = value; }
Here is the sorting class
package MSSPackage;
import java.util.Collections;
import java.util.Comparator;
import java.util.Vector;
import com.sapportals.htmlb.table.DefaultTableViewModel;
public class SortTableModel extends DefaultTableViewModel implements Comparator {
//protected int currCol;
public int currCol;
protected Vector ascendCol; // this vector stores the state (ascending or descending) of each column
protected Integer one = new Integer(1);
protected Integer minusOne = new Integer(-1);
public String testing;
public SortTableModel()
super();
ascendCol = new Vector();
public SortTableModel(Vector vec)
super(vec);
ascendCol = new Vector();
public SortTableModel(Vector vec, Vector vec2, int numberOfColumns)
super(vec, vec2);
ascendCol = new Vector();
setSortOrder(numberOfColumns);
public int compare (Object v1, Object v2)
// the comparison is between 2 vectors, each representing a row
// the comparison is done between 2 objects from the different rows that are in the column that is being sorted
int ascending = ((Integer)ascendCol.get(currCol)).intValue();
if (v1 == null && v2 == null)
return 0;
else if (v2 == null)
{ // Define null less than everything.
return 1 * ascending;
else if (v1 == null)
return -1 * ascending;
Object o1 = ((Vector)v1).get(currCol);
Object o2 = ((Vector)v2).get(currCol);
// If both values are null, return 0.
if (o1 == null && o2 == null)
return 0;
else if (o2 == null)
{ // Define null less than everything.
return 1 * ascending;
else if (o1 == null)
return -1 * ascending;
if (o1 instanceof Number && o2 instanceof Number)
Number n1 = (Number)o1;
double d1 = n1.doubleValue();
Number n2 = (Number)o2;
double d2 = n2.doubleValue();
if (d1 == d2)
return 0;
else if (d1 > d2)
return 1 * ascending;
else {
return -1 * ascending;
else if (o1 instanceof Boolean && o2 instanceof Boolean)
Boolean bool1 = (Boolean)o1;
boolean b1 = bool1.booleanValue();
Boolean bool2 = (Boolean)o2;
boolean b2 = bool2.booleanValue();
if (b1 == b2)
return 0;
else if (b1)
return 1 * ascending;
else
return -1 * ascending;
else
// default case
if (o1 instanceof Comparable && o2 instanceof Comparable)
Comparable c1 = (Comparable)o1;
Comparable c2 = (Comparable)o2; // superflous cast, no need for it!
try
return c1.compareTo(c2) * ascending;
catch (ClassCastException cce)
// forget it... we'll deal with them like 2 normal objects below.
String s1 = o1.toString();
String s2 = o2.toString();
return s1.compareTo(s2) * ascending;
* This method sorts the rows using Java's Collections class.
* After sorting, it changes the state of the column -
* if the column was ascending, its new state is descending, and vice versa.
public void sort()
Collections.sort(dataVector, this);
//Collections.sort(dataVector);
Integer val = (Integer)ascendCol.get(currCol);
ascendCol.remove(currCol);
if (val.equals(one)) // change the state of the column
ascendCol.add(currCol, minusOne);
else
ascendCol.add(currCol, one);
public void sortByColumn(int column)
this.currCol = column;
sort();
public void setSortOrder(int numberOfColumns)
for (int i = 0; i < numberOfColumns; i++)
ascendCol.add(one);
public void setTesting(String inStr)
testing = inStr;
Any help would be greatly apprciated and rewarded...Hi Don,
be aware that after the method onHeaderClick(Event event) is executed the method doProcessBeforeOutput() is executed as well.
I look over your code and found the following:
1) In method onHeaderClick you sort the table model and store the table model in the bean
2) In method doProcessBeforeOutput() you create a new table model from scratch (in helper method tableViewFormat())and store it in the bean. Thus you overwrite the sorted model.
I suggest that you move the initial creation of the table model in method doInitialization(). Do not forget to store the created table in the bean. In method doProcessBeforeOutput() you retrieve the table model from the bean instead of creating a new one for every request.
Best regards,
Martin -
How to enforce always sorting on a column in a TableView?
Hello,
I have a requirement to always sort on a column in a TableView.
So basically, I need a TableColumn's SortType go from Ascending to Descending and back to Ascedning when user clicks on a column header repeatedly.
I guess that means making sure a TableView's SortOrder list is not empty. Am I right?
I tried to listen to SortOrder list changes like below:
tableView.getSortOrder().addListener(new ListChangeListener<TableColumn<String, ?>>() {
@Override
public void onChanged(final javafx.collections.ListChangeListener.Change<? extends TableColumn<String, ?>> arg0) {
if (tableView.getSortOrder().size() > 0) {
// fine. nothing to do
else {
// add the removed column back
Is this the right approach?
I'm not sure how to use arg0 and add the removed column back.
Can people with experience in this area provide some sample code?
Thanks.The solution I came up with was to save the last column added to the SortOrder list to a map.
Whenever the SortOrder list becomes empty, I add the last saved column back to the SortOrder list.
That seems work.
Edited by: 925616 on Aug 3, 2012 3:33 PM
Edited by: 925616 on Aug 3, 2012 3:33 PM -
Problem in sorting tableview line item
Hi,
I have only one main page with with one tableview.
For example, i have the fields in header say field1, field2, field3, field4, field5.
When i click the header of the field say field2, it sorts the line item which is in table display w.r.t field2.
But i intend to sort the internal table line item , which is responsible to display the line item on page.
Is it possible. If so how?
Cheers
RKHi,
You have to use SORT = "SERVER" and in input processing validate the code:
Please see the below example:
In the view the code should something as below:
<htmlb:tableView id="tv2" table="<%=it_vbak%>"
selectionMode = "none"
onHeaderClick = "some"
sort = "SERVER"
iterator = "<%=controller%>" >
<htmlb:tableViewColumn columnName="VBELN" > </htmlb:tableViewColumn>
<htmlb:tableViewColumn columnName="ERDAT" > </htmlb:tableViewColumn>
<htmlb:tableViewColumn columnName="ERZET" > </htmlb:tableViewColumn>
<htmlb:tableViewColumn columnName="ANGDT"> </htmlb:tableViewColumn>
<htmlb:tableViewColumn columnName="ERNAM"> </htmlb:tableViewColumn>
<htmlb:tableViewColumn columnName="VBTYP" > </htmlb:tableViewColumn>
</htmlb:tableView>
In the event handler the code would be something as below:
data: tv type ref to cl_htmlb_tableview.
tv ?= cl_htmlb_manager=>get_data(
request = runtime->server->request
name = 'tableView'
id = 'tv2' ).
sort it_vbak by (tv->data->column_key).
Bhavana.G -
Hi,
I want to have an initial sort of a table and it should be done by the server. I know I could do it by application, but this is just a question if it is possible.
I found for the htmlb:tableViewColumn the attribute preSelectedSortDirection = "DESCENDING". But it seems that it is just showing the sort direction....
My tableView look like this one:
<htmlb:tableView id = "time"
table = "//model/tab_time"
emptyTableText = "do data"
selectionMode = "<%= selectionmode %>"
fillUpEmptyRows = "TRUE"
sort = "SERVER"
visibleRowCount = "3"
width = "100%" >
<htmlb:tableViewColumns>
<htmlb:tableViewColumn columnName = "personid"
title = "person"
sort = "TRUE" />
<htmlb:tableViewColumn columnName = "time"
title = "time"
edit = "TRUE" />
<htmlb:tableViewColumn columnName = "wdate"
title = "date"
edit = "TRUE"
sort = "TRUE"
preSelectedSortDirection = "DESCENDING" />
<htmlb:tableViewColumn columnName = "shortcomment"
title = "comment"
edit = "TRUE"
sort = "TRUE" />
</htmlb:tableViewColumns>
</htmlb:tableView>
Thanks for help,
Stefan Huemermy guess is that <b>preSelectedSortDirection</b> is only to mark the right icon.
lets take a case.
you sort the itab ascending and pass it to htmlb:tableView without using <b>preSelectedSortDirection</b> in column definition. in this case though the sorting is in ascending order the icons in the table header wont tell whether the current situation is ascending sort to descending sort.
so the way to use it
if you sort the itab passed to htmlb:tableview in ascending order by column a and b initially then set <b>preSelectedSortDirection</b> to 'ASCENDING' to column a and b .
if you sort the itab passed to htmlb:tableview in descending order by column a and b initially then set <b>preSelectedSortDirection</b> to 'DESCENDING' to column a and b .
if you have not sorted the itab passed to htmlb:tableView then dont set anything for <b>preSelectedSortDirection</b>
Regards
Raja -
Hi,
Just a short question about sorting. In one of our tables, there are entries for a column that have names starting With and without capital letters. Now, is there a way to force the sort to not care whether or not the first word is Capitalized or not?
Thanks and best regards,
KevinHi Kevin,
follow for example more or less the code given in this thread: Functionality to dynamically sort tableview columns and implement a <i>compare</i> method corresponding to your needs (for example using <i>compareToIgnoreCase</i> method of <i>String</i>).
Hope it helps
Detlev -
Functionality to dynamically sort tableview columns
Has anybody successfully tried sorting columns of a tableview component by clicking on its header? I need to sort a column containing dates in mm/dd/yyyy format. Please share your hints or code. BR, Maulin
Hi,
Here is the code, no support included :-):
import java.util.Collections;
import java.util.Comparator;
import java.util.Vector;
import com.sapportals.htmlb.table.DefaultTableViewModel;
public class SortTableModel extends DefaultTableViewModel implements Comparator {
protected int currCol;
protected Vector ascendCol; // this vector stores the state (ascending or descending) of each column
protected Integer one = new Integer(1);
protected Integer minusOne = new Integer(-1);
public SortTableModel() {
super();
ascendCol = new Vector();
public SortTableModel(Vector vec) {
super(vec);
ascendCol = new Vector();
public SortTableModel(Vector vec, Vector vec2, int numberOfColumns) {
super(vec, vec2);
ascendCol = new Vector();
setSortOrder(numberOfColumns);
This method is the implementation of the Comparator interface.
It is used for sorting the rows
public int compare(Object v1, Object v2) {
// the comparison is between 2 vectors, each representing a row
// the comparison is done between 2 objects from the different rows that are in the column that is being sorted
int ascending = ((Integer)ascendCol.get(currCol)).intValue();
if (v1 == null && v2 == null) {
return 0;
} else if (v2 == null) { // Define null less than everything.
return 1 * ascending;
} else if (v1 == null) {
return -1 * ascending;
Object o1 = ((Vector)v1).get(currCol);
Object o2 = ((Vector)v2).get(currCol);
// If both values are null, return 0.
if (o1 == null && o2 == null) {
return 0;
} else if (o2 == null) { // Define null less than everything.
return 1 * ascending;
} else if (o1 == null) {
return -1 * ascending;
if (o1 instanceof Number && o2 instanceof Number) {
Number n1 = (Number)o1;
double d1 = n1.doubleValue();
Number n2 = (Number)o2;
double d2 = n2.doubleValue();
if (d1 == d2) {
return 0;
} else if (d1 > d2) {
return 1 * ascending;
} else {
return -1 * ascending;
} else if (o1 instanceof Boolean && o2 instanceof Boolean) {
Boolean bool1 = (Boolean)o1;
boolean b1 = bool1.booleanValue();
Boolean bool2 = (Boolean)o2;
boolean b2 = bool2.booleanValue();
if (b1 == b2) {
return 0;
} else if (b1) {
return 1 * ascending;
} else {
return -1 * ascending;
} else {
// default case
if (o1 instanceof Comparable && o2 instanceof Comparable) {
Comparable c1 = (Comparable)o1;
Comparable c2 = (Comparable)o2; // superflous cast, no need for it!
try {
return c1.compareTo(c2) * ascending;
} catch (ClassCastException cce) {
// forget it... we'll deal with them like 2 normal objects below.
String s1 = o1.toString();
String s2 = o2.toString();
return s1.compareTo(s2) * ascending;
This method sorts the rows using Java's Collections class.
After sorting, it changes the state of the column -
if the column was ascending, its new state is descending, and vice versa.
public void sort() {
Collections.sort(dataVector, this);
Integer val = (Integer)ascendCol.get(currCol);
ascendCol.remove(currCol);
if (val.equals(one)) // change the state of the column
ascendCol.add(currCol, minusOne);
else
ascendCol.add(currCol, one);
public void sortByColumn(int column) {
this.currCol = column;
sort();
public void setSortOrder(int numberOfColumns) {
for (int i = 0; i < numberOfColumns; i++) {
ascendCol.add(one);
Maybe you are looking for
-
How to display the fields in effective
i have 10 fields names as name,add,code,no.seats...... I have two choices those are Table, and other one is add fields and JScrollpane to a panel and display it. Can any one have other choices to display the fields effectively.
-
Nokia Lumia 920 no data conection
I'm having problems with my data conection. At first i turned it on and it was showing 4g, but there was no internet. After reboot it had the E icon on the top left corner, and still no internet. My carrier(T-mobile) cannot automaticaly set up the ne
-
How to know if ane new fields are added matl. master ? In our system some new field were added, we need to know how many new fiels are added like this ? pl help guru
-
can I lock my 6th generation ipod nano whilst listening to it as it keeps switching off if i knock the sleep button?
-
Application context in cluster (using EJB3.1)
Hello there, i want to ask for recommendation. What is the best strategy for storing global application data in clustered enviroment with usage of EJB3. Imagine e.g. users and contact lists. There are browser clients (let's say they invoke EJB from t