I need to make a programm in JavaFX where I need to manage a movie library. I have a tableview that is filled by an observable list. Then I made bindings between the Properties and the Textboxes or Labels next to the tableview. Now the problem is, I have also pictures that are related to the movies, like cinema posters. and at the moment I just use a hardcoded one:
imgPoster = new Image(getClass().getResourceAsStream("../resources/images/posters/" + 5 + ".jpg"));
In the datafile there is one column with the ID of the movie and the same number is also the picture for it. So I need to replace that "5" in the sample code with a binding or so that it actively changes the picture as soon as I click on a row in the tableview.
How do I do that?
edit:
After the first comment i did that:
imgOscars = new Image(getClass().getResourceAsStream("../resources/images/oscar/Oscar-logo.png"));
oscars = new ImageView(imgOscars);
oscars.setPreserveRatio(true);
oscars.setFitHeight(45);
but question stays
Either add a listener to the selected item property in the table (I am just guessing at the model you are using for the table):
TableView<Movie> table = ... ;
table.getSelectionModel().selectedItemProperty().addListener((obs, oldSelectedMovie, newSelectedMovie) -> {
if (newSelectedMovie == null) {
oscars.setImage(null);
} else {
// get image from new selection
Image image = new Image(getClass().getResourceAsStream("../resources/images/oscar/"+newSelectedMoviegetId()+".png"));
oscars.setImage(image);
}
});
or use a binding:
oscars.imageProperty().bind(Bindings.createObjectBinding(() -> {
if (table.getSelectionModel().getSelectedItem() == null) {
return null ;
} else {
Movie selected = table.getSelectionModel().getSelectedItem();
return new Image(getClass().getResourceAsStream("../resources/images/oscar/"+selected.getId()+".png")); ;
},
table.getSelectionModel().selectedItemProperty());
Related
So, I have a grid called "eventGrid". I added a component column with a down-arrow icon. When a user clicks on a row, addition information is displayed for that row. I want to change the down arrow to an up arrow for the selected row. How can I achieve this?
eventGrid.addColumn(Person::getFirst).setHeader("First Name");
eventGrid.addColumn(Person::getLast).setHeader("Last Name");
eventGrid.addColumn(Person::getNumber).setHeader("Phone Number");
eventGrid.addComponentColumn(item -> {
Icon icon = new Icon("lumo", "angle-down");
return icon;
}).setWidth("6em").setFlexGrow(0);
There are two steps to the solution. First you need to make the renderer react differently for selected items and second, you need to make the grid re-render the row for which the selected status changes.
The first part can be handled in the component renderer:
eventGrid.addComponentColumn(item -> {
String name = eventGrid.getSelectedItems().contains(item) ? "angle-down" : "angle-up";
Icon icon = new Icon("lumo", name);
return icon;
}).setWidth("6em").setFlexGrow(0);
The second part is a listener that uses DataProvider::refreshItem to trigger specific rows to be rendered again. This is implemented through asSingeSelect to get an event that contains both the old and the new value.
eventGrid.asSingleSelect().addValueChangeListener(event -> {
String newValue = event.getValue();
String oldValue = event.getOldValue();
if (newValue != null) {
eventGrid.getDataProvider().refreshItem(newValue);
}
if (oldValue != null) {
eventGrid.getDataProvider().refreshItem(oldValue);
}
});
Assuming you have an in-memory DataProvider:
Grid<Person> eventGrid = new Grid<Person>();
eventGrid.addColumn(Person::getFirst).setHeader("First Name");
eventGrid.addColumn(Person::getLast).setHeader("Last Name");
eventGrid.addColumn(Person::getNumber).setHeader("Phone Number");
eventGrid.addComponentColumn(item -> {
Icon icon = new Icon("lumo", "angle-down");
if (item.equals(eventGrid.asSingleSelect().getValue())) {
icon = new Icon("lumo", "angle-up");
}
return icon;
}).setWidth("6em").setFlexGrow(0);
eventGrid.addSelectionListener(e -> {
eventGrid.getListDataView().refreshAll();
});
I have a MultiSelectComboBox but when trying to select some items through its select() method nothing happens.
My code looks as follows:
Binder<Technology> binder = new BeanValidationBinder<>(Technology.class);
MultiSelectComboBox<TechnologyLabel> multiComboBox = new MultiSelectComboBox<>("Labels");
binder
.forField(this.multiComboBox)
.bind(Technology::getLabels, Technology::setLabels);
List<TechnologyLabel> labelList = technologyLayout.technologyLabelService.getTechnologyLabels(technology);
List<Label> containedLabels = new ArrayList<>();
for (var tl : labelList) {
containedLabels.add(tl.getLabel());
}
List<Label> labels = labelService.findAllLabels();
for (var label : labels) {
if (!containedLabels.contains(label)) {
labelList.add(new TechnologyLabel(technology, label));
}
}
multiComboBox.setItems(labelList);
multiComboBox.setItemLabelGenerator(TechnologyLabel::getLabelName);
note.setMaxHeight("10em");
multiComboBox.select(labelList.get(0);
What I do above is querying my ManyToMany relation to find all labels given the technology. Then I find all the labels and create a list from that. Lastly, I try to select first item of the list, but it does not show a tick next to it.
By refreshing the items within a grid sometimes it happen that the grid shows completely crazy:
That's how I update the data every time. The instance of the Grid stays the same:
dataProvider = new ListDataProvider<>(newItems);
grid.setItems(dataProvider);
Does someone have an idea whether I do something wrong or there is a bug within Vaadin?
Complete code:
if (!columnsIntialized) {
for (Method method : gridProperties) {
Column<T> column = grid.addColumn(data -> {
Object value = method.invoke(data);
return getFormattedValue(value, method.getReturnType());
});
String resourceKey = method.getDeclaredAnnotation(GridProperties.class).resourceKey();
column.setKey(resourceKey);
column.setHeader(AppResources.getString(resourceKey));
int width = method.getDeclaredAnnotation(GridProperties.class).width();
if (width == -1) {
column.setAutoWidth(true);
} else {
column.setWidth(width + "px");
}
}
columnsIntialized = true;
}
dataProvider = new ListDataProvider<>(items);
grid.setItems(dataProvider);
grid.recalculateColumnWidths();
Vaadin 22.0.3 is scheduled to be released on Monday with the fix.
Okey so my problem is next: I use web scraping to take some data from web page IMDB in this case, that data is titles of movies, and I already tried to print it in console and that works fine. My problem is that I can not save that titles in my table columns, I put all needed codes for this problem, and I cant find where I made mistake and why titles wont show in table columns. At the and, user need to pick one title and that title need to be stored in text field. Have someone any idea, please?
I have table:
TableColumn izborAuta = new TableColumn("Izbor auta");
TableColumn lokacijaPreuzimanja = new TableColumn("Lokacija
preuzimanja");
TableColumn lokacijaVracanja = new TableColumn("Lokacija Vracanja");
TableColumn cena = new TableColumn("Cena");
I have this code to setup columns:
izborAuta.setCellValueFactory(new PropertyValueFactory<Vozila, String>
("izborAuta"));
lokacijaPreuzimanja.setCellValueFactory(new
PropertyValueFactory<Vozila, String>("lokacijaPreuzimanja"));
lokacijaVracanja.setCellValueFactory(new
PropertyValueFactory<Vozila, String>("lokacijaVracanja"));
cena.setCellValueFactory(new PropertyValueFactory<Vozila, String>
("cena"));
tableView.setItems(Baza.baza.prikazBaze());
tableView.getColumns().addAll(izborAuta, lokacijaPreuzimanja,
lokacijaVracanja, cena);
I have this code, so when I pick one item from table that item need to be stored in textField:
tableView.setOnMouseClicked((e) -> {
Vozila v = (Vozila)
tableView.getSelectionModel().getSelectedItem();
txIzborAuta.setText(v.getIzborAuta());
txLokacijaPreuzimanja.setText(v.getLokacijaPreuzimanja());
txLokacijaVracanja.setText(v.getLokacijaVracanja());
txCena.setText(v.getCena());
});
And at the end I use web scraping to save items in table:
Document doc = Jsoup.connect("https://www.imdb.com/chart/top?
ref_=nv_mv_250").get();
Elements elems = doc.select("table.chart.full-width");
for (Element e : elems) {
String izborAuta = e.select(".titleColumn").text();
String lokacijaPreuzimanja = e.select(".titleColumn").text();
String lokacijaVracanja = e.select(".titleColumn").text();
String cena = e.select(".titleColumn").text();
Vozila v = new Vozila();
v.setIzborAuta(izborAuta);
v.setLokacijaPreuzimanja(lokacijaPreuzimanja);
v.setLokacijaVracanja(lokacijaVracanja);
v.setCena(cena + " " + "RSD");
Baza.insertVozila(v);
}
I can't seem to update an existing record in my table using a strongly-typed dataset. I can add a new record, but if I make changes to an existing record it doesn't work.
Here is my code:
private void AddEmplMaster()
{
dsEmplMast dsEmpMst = new dsEmplMast();
SqlConnection cn = new SqlConnection();
cn.ConnectionString = System.Configuration.ConfigurationSettings.AppSettings["cn.ConnectionString"];
SqlDataAdapter da1 = new SqlDataAdapter("SELECT * FROM UPR00100", cn);
SqlCommandBuilder cb1 = new SqlCommandBuilder(da1);
da1.Fill(dsEmpMst.UPR00100);
DataTable dtMst = UpdateEmpMst(dsEmpMst);
da1.Update(dsEmpMst.UPR00100);
}
This procedure is called from above to assign the changed fields to a record:
private DataTable UpdateEmpMst(dsEmplMast dsEmpMst)
{
DataTable dtMst = new DataTable();
try
{
dsEmplMast.UPR00100Row empRow = dsEmpMst.UPR00100.NewUPR00100Row();
empRow.EMPLOYID = txtEmplId.Text.Trim();
empRow.LASTNAME = txtLastName.Text.Trim();
empRow.FRSTNAME = txtFirstName.Text.Trim();
empRow.MIDLNAME = txtMidName.Text.Trim();
empRow.ADRSCODE = "PRIMARY";
empRow.SOCSCNUM = txtSSN.Text.Trim();
empRow.DEPRTMNT = ddlDept.SelectedValue.Trim();
empRow.JOBTITLE = txtJobTitle.Text.Trim();
empRow.STRTDATE = DateTime.Today;
empRow.EMPLOYMENTTYPE = "1";
dsEmpMst.UPR00100.Rows.Add(empRow);
}
catch { }
return dtMst;
}
Thank you
UPDATE:
Ok I figured it out. In my UpdateEmpMst() procedure I had to check if the record exists then to retrieve it first. If not then create a new record to add. Here is what I added:
try
{
dsEmplMast.UPR00100Row empRow;
empRow = dsEmpMst.UPR00100.FindByEMPLOYID(txtEmplId.Text.Trim());
if (empRow == null)
{
empRow = dsEmpMst.UPR00100.NewUPR00100Row();
dsEmpMst.UPR00100.Rows.Add(empRow);
}
then I assign my data to the new empRow I created and updates fine.
In order to edit an existing record in a dataset, you need to access a particular column of data in a particular row. The data in both typed and untyped datasets can be accessed via the following:
With the indices of the tables, rows, and columns collections.
By passing the table and column names as strings to their respective collections.
Although typed datasets can use the same syntax as untyped datasets, there are additional advantages to using typed datasets. For more information, see the "To update existing records using typed datasets" section below.
To update existing records in either typed or untyped datasets
Assign a value to a specific column within a DataRow object.
The table and column names of untyped datasets are not available at design time and must be accessed through their respective indices.