I have 3 MenuButtons in my JavaFX-Application, each one filled with CheckMenuItems.
I want to get the Text of every selected Item of the MenuButton. How shall i proceed?
Take all MenuItems, filter selected and map them to String.
MenuButton mb = new MenuButton();
mb.getItems().addAll(new CheckMenuItem("One"), new CheckMenuItem("Two"), new CheckMenuItem("Three"));
mb.getItems().stream().forEach((MenuItem menuItem) -> menuItem.setOnAction(ev -> {
final List<String> selectedItems = mb.getItems().stream()
.filter(item -> CheckMenuItem.class.isInstance(item) && CheckMenuItem.class.cast(item).isSelected())
.map(MenuItem::getText)
.collect(Collectors.toList());
System.out.println(selectedItems);
}));
Related
This is likely embarrassingly easy but I'm new and I've been beating my head against the wall on this for a while now. What I am attempting to do is basically a modified version of the "Hello App Maker!" If else test.
The necessary info I have the following widgets attached to the appropriate data sources:
Dropdown widget called source_name (string - list)
Label widget I've called name (string)
Text Box widget called qty_duration (number)
Label widget I've called hours (number)
I have a dropdown widget called source_name with 5 options. On selection I have the value appear in a label widget I've called name. If the option selected from the drop down widget is ever LABOUR I am trying to then have the value of a Text Box widget called qty_duration appear in a label widget I've called hours
On the source_name dropdown event - onValueChange I have the following code:
// Define variables for the input and output widgets
var nameWidget = app.pages.Apex_job_details.descendants.name;
var outputWidget = app.pages.Apex_job_details.descendants.hours;
var techhours = app.pages.Apex_job_details.descendants.qty_duration;
var nothing = 0;
// If a name is LABOUR, add the qty to the output widget Else output 0.
if (nameWidget == 'LABOUR') {
outputWidget.text = techhours;
} else {
outputWidget = nothing;
}
It's not giving me any errors, but it's also not outputting to the hours label. If I edit the code as follows just to muck with it:
// Define variables for the input and output widgets
var nameWidget = app.pages.Apex_job_details.descendants.name;
var outputWidget = app.pages.Apex_job_details.descendants.hours;
var techhours = app.pages.Apex_job_details.descendants.qty_duration;
var nothing = 0;
// If a name is LABOUR, add the qty to the output widget Else output 0.
if (nameWidget == 'LABOUR') {
outputWidget.text = techhours;
} else {
outputWidget.text = nothing;
}
I'm not sure what I'm doing wrong.
Assuming all labels and input widgets are inside a table row you will want to adjust your code as follows:
var tablerow = widget.parent;
var nameWidget = tablerow.descendants.name.text;
var outputWidget = tablerow.descendants.hours;
var techhours = tablerow.descendants.qty_duration.value;
if(nameWidget === 'LABOUR') {
outputWidget.text = techhours;
} else {
outputWidget.text = null;
}
By using widget.parent in the onValueChange event of the dropdown you will automatically reference the table row and then by using descendants you are referencing only the descendants of that table row. This will bridge the error by using an absolute reference when using table rows. If it still doesn't work let me know.
Good evening.
Tell me please
I need to make such an implementation
Have: CollectionView
Rxswift
The maximum number of cells is 6
If there are less than 6 elements in a certain array, then the first cells are filled with one type (by the number of elements in the array), and the rest with other cells.
collectionView.register(UINib(nibName: "PhotoCollectionCell", bundle: nil), forCellWithReuseIdentifier: "PhotoCell")
collectionView.register(UINib(nibName: "EmptyCollectionCell", bundle: nil), forCellWithReuseIdentifier: "EmptyCell")
Please check collectionView.rx.items in UICollectionView+Rx.swift from RxCocoa
Here is the example from code itselft
let items = Observable.just([
1,
2,
3
])
items
.bind(to: collectionView.rx.items) { (collectionView, row, element) in
let indexPath = IndexPath(row: row, section: 0)
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! NumberCell
cell.value?.text = "\(element) # \(row)"
return cell
}
.disposed(by: disposeBag)
You can dequeue whatever cell you want based on the index of the row or type of the data, just like the way we did in DataSource
You need to import RxDataSources in case you want different cell type.
// TableView Cell Nib Register
tableView.register(R.nib.meChatCell)
tableView.register(R.nib.otherChatCell)
vm.output.chats
.bind(to: tableView.rx.items){(tv, row, item) -> UITableViewCell in
if item.userId == 0 {
let cellIdentifier = R.reuseIdentifier.meChatCell.identifier
let cell = tv.dequeueReusableCell(withIdentifier: cellIdentifier, for: IndexPath.init(row: row, section: 0)) as! MeChatCell
cell.vm = item
return cell
} else {
let cellIdentifier = R.reuseIdentifier.otherChatCell.identifier
let cell = tv.dequeueReusableCell(withIdentifier: cellIdentifier, for: IndexPath.init(row: row, section: 0)) as! OtherChatCell
cell.vm = item
return cell
}
}.disposed(by: disposeBag)
}
I am trying to make point of sale terminal. I need to read read (item ID, item names, and item price) from a text file with FileChooser. Then the itemID should be listed in a comboBox. The comboBox selection should change labels and prices to the corresponding item name and item price. I believe this has to do with properties and binding but I don't understand how to use those.
I've tried creating an Items class, I tried reading the file into three arrays and then comparing the ID array item to the combobox selection and then switching the label text to the name array item with the same position.
stage.setTitle("Open Resource File");
FileChooser fileChooser = new FileChooser();
try {
FileReader reader = new
FileReader(fileChooser.showOpenDialog(stage));
Scanner scanner = new Scanner(reader);
for (int i = 0; i < 10; i++) {
itemID[i] = scanner.next();
itemName[i] = scanner.next();
itemPrice[i] = scanner.nextDouble();
}
scanner.close();
reader.close();
}
catch (Exception FileNotFoundException) {
}
Items item = new Items();
ComboBox idBox = new ComboBox();
idBox.setPromptText("Select an item");
idBox.getItems().addAll("A", "B", "C", "D", "E", "F", "G", "H", "I",
"J");
idBox.setOnAction(e -> {
item.setName(idBox.getValue().toString(), itemID, itemName);
item.setPrice(idBox.getValue().toString(), itemID, itemPrice);
nameLbl.setText(item.name.toString());
});
double quantity;
Label idLabel = new Label("Item ID: ");
Label nameLabel = new Label("Item Name: ");
Label nameLbl = new Label(item.name.toString());
Label priceLabel = new Label("Item Price: ");
Label priceLbl = new
Label(NumberFormat.getCurrencyInstance(newLocale("en",
"US")).format(item.price));
Label priceLbl = new Label("");
Program compiles and main window opens but shows error and crashes when
it tries to create the point of sales terminal window.
So there are a number of things you're going to want to look into, this isn't going to contain all the code, but it should be enough to get you going.
1) You're going to want to scan your Items into an ObservableList<Item> so that you have them in a single List to work with. At a bare minimum you can do something like this in your for:
String id = scanner.next();
String name = scanner.next();
String price = scanner.nextDouble();
items.add(new Item(id, name, price));
although you probably want to make the looping within the scanner a little more dynamic (instead of to 10) - possibly use a while loop or a different reader.
2) Now that you have your list of Items you want to use a ComboBox<Item> cbItems = new ComboBox<Item>() in order to display. You're going to have to set the cbItems.setCellFactory(...) and cbItems.setButtonFactory(...) in order to display the Id or the name in the drop down. The ObservableList you've added to can then be set to the cbItems.setItems(items) described in (1). There are a ton of SO articles on doing so, so I'll leave out the full code.
3) It's dealers choice on whether you want to use ObjectProperty<Item> or cbItems.selectedProperty() in order to bind to the text boxes that you're using. 'd suggest starting with the on change handler you're using now and setting the labels directly with item.getName() and once you've got that working move on to lblName.textProperty().bind(Bindings....).
With regards to the error, you haven't posted enough information (what the exception is, or the full code to replicate) so I can't help in that way. But if you research the items above, you should be closer.
I have a treeTable with editable cells within the expanded rows. The editable cells get a dirty flag after editing (in the example the background color is set to red).
The problem i'm running into is that i found no certain way to update the dirty flag on expand/collapse (edited cells get the css class 'edited-cell').
At the moment the code looks like that:
// each editable textfield gets a Listener
textField.attachLiveChange(
var source = oEvent.oSource;
...
jQuery('#' + source.getId()).addClass(EDITED_CELL_CLASS, false)
// list with cell ids, e.g. "__field1-col1-row1"
DIRTY_MODELS.push(model.getId()) //*** add also binding context of row
)
// the table rows are updated on toggleOpenState
new sap.ui.table.TreeTable({
toggleOpenState: function(oEvent) {
...
this.updateRows() // see function below
}
})
// update Rows function is also delegated
oTable.addDelegate({ onAfterRendering : jQuery.proxy(this.updateRows, oTable)});
//http://stackoverflow.com/questions/23683627/access-row-for-styling-in-sap-ui5-template-handler-using-jquery
// this method is called on each expand/collapse: here i can make sure that the whole row has it's correct styling...
// but how to make sure that special cells are dirty?
function updateRows(oEvent) {
if (oEvent.type !== 'AfterRendering'){
this.onvscroll(oEvent);
}
var rows = this.getVisibleRowCount();
var rowStart = this.getFirstVisibleRow();
var actualRow;
for (var i = 0; i < rows; i++){
actualRow = this.getContextByIndex(rowStart + i); //content
var row = this.getRows()[i]
var obj = actualRow.getObject()
var rowId = row.getId()
updateStyleOfRows(obj, rowId, actualRow)
updateDirtyCells(rowId) //*** how to get the binding context in this function???
}
};
// update Dirty Cells in function updateRows():
function updateDirtyCells(rowId){
for (var i = 0; i < DIRTY_MODELS.length; i++){
var dirtyCellId = DIRTY_MODELS[i]
//*** make sure that only the correct expanded/collapsed rows will be updated -> depends on the bindingContext of the row
jQuery('#' + rowId).find('#' + dirtyCellId + '.editable-cell').addClass(EDITED_CELL_CLASS, false)
}
}
This doesn't work correctly, because the ids of the cells change on each layout render (e.g. collapse/expand rows). Please see attached image.
Let me know if i should provide more information.
I would like to get all data of one column from my TableView after Button click.
I found this code
TablePosition pos = table.getSelectionModel().getSelectedCells().get(0);
int row = pos.getRow();
// Item here is the table view type:
Item item = table.getItems().get(row);
TableColumn col = pos.getTableColumn();
// this gives the value in the selected cell:
String data = (String) col.getCellObservableValue(item).getValue();
But this is code for selected cell and i have button and all cells of one column.
Can you help me pls?
Thankyou.
Just do the same thing for all elements of table.getItems():
TableColumn<MyDataType, String> column = ... ; // column you want
List<String> columnData = new ArrayList<>();
for (MyDataType item : table.getItems()) {
columnData.add(col.getCellObservableValue(item).getValue());
}
where MyDataType is the data type of the TableView.