How to get all selected rows data in javafx - javafx-2

there is a problem!!
In javafx table view i applied multiple selected mode by Shift+mouseClick or Clt+MouseClick. By This
tblViewCurrentStore.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
tblViewCurrentStore.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
}
});
it's ok on GUI but problem is, if i use this code it give me the last selection cell's value,
private void btnDeleteOnAction(ActionEvent event) {
System.out.println(tblViewCurrentStore.getSelectionModel().getSelectedItem().getProductName().toString());
}
Out Put SAMSUNG HDD
but when i use this code it give this!
private void btnDeleteOnAction(ActionEvent event) {
System.out.println(tblViewCurrentStore.getSelectionModel().getSelectedItems().toString());
}
It Give me This types of output
[List.ListProduct#3a22ea22, List.ListProduct#6d99efa2, List.ListProduct#40fd0f67]
But i need when i select multiple row then press delete it will show all selected data like first one.
Hear is my GUI(With multiple selection)

You can even use this :
ArrayList<YourModel> products = new ArrayList<>(table.getSelectionModel().getSelectedItems());
for (YourModel model : models) {
System.out.println(model);
}
//OR
final List<YourModel> collect = table.getSelectionModel().getSelectedItems().stream().collect(Collectors.toList());

There are multiple problems with your code:
tblViewCurrentStore.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);only needs to be set once (thus its a setter). Do it after your TableView has been initialized and not on every click.
SelectionModel#getSelectedItem() clearly says what it does:
Returns the currently selected object (which resides in the selected index position). If there are multiple items selected, this will return the object contained at the index returned by getSelectedIndex() (which is always the index to the most recently selected item).
And finally SelectionModel#getSelectedItems returns all selected objects (as in Java Objects).
So if you want the names, you can something like this:
List<String> names = tblViewCurrentStore.getSelectionModel().getSelectedItems().stream()
.map(ListProduct::getProductName)
.collect(Collectors.toList());

Related

Add note to custom data record in code

I was searching for a solution to add a note to a database row I am creating in a custom table. I found the solution below from Ruslan for accessing the noteid, but I don't understand how this would be used to add a note to the row. I have all the code to create the row, I just need the attributes or function call to actually attach the text of the note to the row.
==================================================================
To have Note record automatically created when a new parent record gets saved, one should invoke the static PXNoteAttribute.GetNoteID(PXCache cache, object data) method when the parent record is inserted in the cache.
For example, to have Note record automatically created when a new Stock Item gets saved, you should subscribe to RowInserted handler for the InventoryItem DAC and call PXNoteAttribute.GetNoteID(...):
public class InventoryItemMaintExt : PXGraphExtension<InventoryItemMaint>
{
public void InventoryItem_RowInserted(PXCache sender, PXRowInsertedEventArgs e)
{
var noteCache = Base.Caches[typeof(Note)];
var oldDirty = noteCache.IsDirty;
PXNoteAttribute.GetNoteID<InventoryItem.noteID>(sender, e.Row);
noteCache.IsDirty = oldDirty;
}
}
The code snippet above can be incorporated into almost any custom BLC with a couple simple changes to replace InventoryItem with a custom DAC.
After implementing Gabriel's suggestions:
I do not seem to get any note in the database. The code compiles and runs fine, but the notes are not generated as far as I can tell. The note id is set in my table, but no data appears in the note table. Please take a look at my code and let me know what needs to change. Also, how do I get the note column into a grid, or does it automatically become available when it is done correctly?
Database field definition:
[NoteID] [uniqueidentifier] NULL
DAC field:
#region NoteID
public abstract class noteID : PX.Data.IBqlField
{
}
protected Guid? _NoteID;
[PXNote()]
public virtual Guid? NoteID
{
get
{
return this._NoteID;
}
set
{
this._NoteID = value;
}
}
#endregion
Code to create record:
private static bool acumaticaException(Exception e, EDImportExceptionMaint excpMaint, LingoRet850 res850)
{
excpMaint.Clear();
var except = new EDImportExcept();
except.ExceptReason = "U";
except.Active = true;
<...field assignments...>
except.OrderNbr = "";
PXNoteAttribute.SetNote(excpMaint.Exception.Cache, excpMaint.Exception.Current,
((PX.Data.PXOuterException)e).InnerMessages[0] + "-" + e.Message);
excpMaint.Exception.Insert(except);
excpMaint.Actions.PressSave();
return true;
}
To set the note of a record, use the SetNote()static function of PXNoteAttribute
PXNoteAttribute.SetNote(Base.Item.Cache, Base.Item.Current, "Hello, World!");
Calling SetNote will also take care of adding the Note record if it doesn't exist, so you don't have to call GetNoteID before setting the note value as in your question.
P.S. There is also a GetNote function which allows you to retrieve the current value of the note:
string note = PXNoteAttribute.GetNote(Base.Item.Cache, Base.Item.Current);

How to handel ValueChangeEvent getNewValue() and getOldValue()?

In my application there are several drop-down boxes each mapped with ValueChangeListner so when any value changes from the drop-down, the ValueChangeEvent was fired and searches for all the methods in the controller layer who takes ValueChangeEvent as an argument.
This is how I initialize the drop-down for which I am getting error
private void methodForDropDown1(){
bean.setValue(null);
List<String> datas=new ArrayList<>();
datas.add("val1");
datas.add("val2");
datas.add("val3");
List<SelectItem> tableData = buildSelectionItems(datas);//takes String and returns SelectItem
datas.setComboBox(tableData);
}
This is how I am handling the ValueChangeEvent
public void comboBoxDropDown1(ValueChangeEvent event) {
if(event.getOldValue()==null){
return;
}
try {
if (event.getNewValue()!=null) {
process event
}
Problem with me that if after server start at the first time if I click on any other drop-down box then the drop-down I have mentioned here, was initialized and event.getNewValue() -> val1,
but if I click on the drop-down then it is not taking the event.getOldValue() it is showing null.
in the page by default it shows val1 when the page was loaded, so by assuming that, this is the new value if I select val2/val3 then it is taking these values as getNewValue() but as expected it is not taking va1 as getOldValue().

UICollectionview SelectItem programmatically not changing background

I have a UICollectionView with images. The user can select (multiselect) the images. When the user taps a single image, everything works fine. The SelectedBackgroundView is visible and on tap again, the normal image is visible.
But my problem is, I have a option for the user "Select all". In that i want to select all items programmatically. With following code:
for (int i = 0; i < CollectionView.NumberOfItemsInSection(0); i++)
{
var ip = NSIndexPath.FromItemSection(i, 0);
CollectionView.SelectItem(ip, false, UICollectionViewScrollPosition.None);
}
The following method returns the correct number for the selected items:
var number = CollectionView.GetIndexPathsForSelectedItems().Length;
But the UI is not changing to the SelectedBackgroundView.
Can anyone help me? Thanks.
Calling SelectItem does not cause the display to be updated; it just changes the Selected property of the UICollectionViewCell therefore updating the selected index set in the collection view.
What I do is override the Selected property of my UICollectionViewCell implementation and adjust the UI at that point:
public class MyCell : UICollectionViewCell
{
// ...
public override bool Selected
{
get { return base.Selected; }
set
{
base.Selected = value;
// change the state of the selected background
imageBackground.Image = LoadAnImage(value ? "BackgroundOn" : "BackgroundOff");
}
}
}
This way ensures that the UI is updated at all possible points when the selected state of the cell changes, either by user interaction or programmatically calling SelectItem or DeselectItem on the collection view.
I do not personally use the SelectedBackgroundView property on a cell (I do my own layering, most of the time), but you may have to manually bring that view to the front yourself in a similar Selected property override.

Disable TableRow based on data

I face a problem with TableView in JavaFX 2.1. I want to disable TableRow based on data.
For eg.:
public class RowData() {
private String name;
private boolean used;
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public boolean isUsed(){
return this.used;
}
public void setUsed(boolean used) {
this.used = used;
}
}
In program:
public class ViewController implements Initializable {
#FXML
private TableView<RowData> tableAttribute;
public void initialize(URL location, ResourceBundle resources) {
List<RowData> data = new ArrayList<RowData>();
// datatype col
TableColumn<DataRow, String> attNameCol = new TableColumn<DataRow, DataRow>(
"Name");
attNameCol
.setCellValueFactory(new PropertyValueFactory<DataRow, String>(
"name"));
attNameCol .setMinWidth(110.0);
tableComponent.getColumns().addAll(attNameCol );
loadData(data);
tableAttribute.setItems(FXCollections.observableList(data));
//I want to disable row which used = true, enable otherwise
}
}
How can I do to achieve that?
Example strategies for disabling a row based on the value of a row field:
Use a rowFactory which renders the row content as disabled as needed.
After the table has been shown, lookupAll the TableRows and render them as disabled as appropriate.
I create a sample app which uses the second principle.
The key logic in the sample is the following code executed after the table has been shown on an active stage, which enables and disables rows as needed (as well as applying style classes to each row so that they can be styled separately if required). Note, for this approach, if the rows in the table change or are reordered, then the lookup and enabling/disabling code will have to be re-run over the table after the table has been re-rendered so that the table is correctly styled and has the correct disabled properties for rows.
// highlight the table rows depending upon whether we expect to get paid.
int i = 0;
for (Node n: table.lookupAll("TableRow")) {
if (n instanceof TableRow) {
TableRow row = (TableRow) n;
if (table.getItems().get(i).getWillPay()) {
row.getStyleClass().add("willPayRow");
row.setDisable(false);
} else {
row.getStyleClass().add("wontPayRow");
row.setDisable(true);
}
i++;
if (i == table.getItems().size())
break;
}
}
When using a fxml controller the lookupAll return 0 "TableRow" nodes. It seems that after table.setItems(data) when doing lookup rows are populated why ?
Before answering this, I will note that using a rowFactory is really the preferred solution to this question, rather than using a lookup. Some of the reasons why will become apparent in the rest of this answer. For a sample of a rowFactory approach, please refer to this linked sample code by james-d.
A lookup is a CSS operation and it requires that css has been applied to the nodes being looked up. To explicitly apply css, call applyCss after the node has been placed in a scene.
A difficulty with a controller is that, in the initialize call, the node might not yet be in a scene. To work around that issue you can apply the following pattern:
Pane parent = (Pane) table.getParent();
parent.getChildren().remove(table);
Scene applyCssScene = new Scene(table);
table.applyCss();
table.layout();
applyCssScene.setRoot(null);
if (parent != null) {
// Assumes that the original order in the parent does not matter.
// If it did, you would also need to keep track of the child list position.
parent.getChildren().add(table);
}
. . .
// perform css based lookup operation on the table.
This creates a dummy holder scene with the table in it, applies CSS (after which CSS based lookup operations will work) and then removes the table from the scene so that you can add it to the real scene at a later time and afterwards places the table back in it's original parent. As you may have noted this is a bit confusing. Note that I didn't try to actually execute the CSS application process outlined above in an example application with an FXML controller, however I believe it will work.
In the sample app I linked which uses lookups, the above complexity is not needed because the lookup is made after the stage containing the table has been initially shown. The stage.show() call implicitly runs layout and css application passes on the scene to be shown (it needs to do this to determine the initial size of the stage based upon the calculated size of the initial scene and perhaps for other reasons).

GXT FillToolItem

The FillToolItem , fills the toolbar width, pushing any newly added items to the right.
public FillToolItem() {
getAriaSupport().setPresentation(true);
}
#Override
protected void onRender(Element target, int index) {
setElement(DOM.createDiv(), target, index);
}
I want to create a new class LeftFillToolItem that will extend the FillToolItem , but will pushing any newly added items to the left.
how can i do that?
Hi I can't seem to understand your question can you give an example. By default(when a FillToolItem is not inserted) new items are already added to the left.

Resources