In this app that i am building i have in one stage a TableView and a few buttons. When i click on one of the buttons it opens a new window that is made of TextFields and a "OK" button. When i click on the OK, i need to insert that data into a Table.
So, i know how to insert a row into a TableView from a controller that controlles that TableView, but now i need to insert it from controller of another window. I tried everything, and it doesent work. I tried to get an instance of TableController and pass the data to its method, then i tried to pass ObservableList to a NewWindowController, and that also doesent work. I'm out of ideas. Can someone help me with this, i would appreciate it. Thank you.
Part of the code:
public class MainController {
#FXML public TableView<Film> tabel;
public TableView<Film> getTabel(){
return tabel;
}
}
newWindow'sController:
public UnosController(){
#FXML protected void insert(ActionEvent e){
Film film = new Film(funosNaziv.getText(), funosZanr.getText(),Integer.valueOf(funosGodina.getText()));
TableView<Film> tabel = mainController.getTabel();
ObservableList<Film> data = tabel.getItems();
data.add(film);
}
}
That is my last try. Doesent work.
Related
I have a Problem with my Vaadin Grid.
Its a rather simple Grid that just shows some cars with name, model, ps, etc.
If you click on one of the rows, the grid detail opens, and shows a picture of the car.
If you click on the first row in the grid, the Image is cut of and you cant scroll.
But if you click around a bit, for example you click on the 6th row , then the Picture is fine.
Also then you can scroll and if you click on the first row, the image is now shown correctly.
Is this a mistake by me or is this a bug?
public FahrzeugView()
{
final Grid<Fahrzeug> grid = new Grid<>(Fahrzeug.class, false);
grid.setWidthFull();
grid.setHeight("800px");
grid.addColumn(Fahrzeug::getId).setHeader("Id").setSortable(true);
grid.addColumn(Fahrzeug::getMarke).setHeader("Marke").setSortable(true);
grid.addColumn(Fahrzeug::getModell).setHeader("Modell").setSortable(true);
grid.addColumn(Fahrzeug::getPs).setHeader("Ps").setSortable(true).setId("ps");
grid.setItemDetailsRenderer(this.createFahrzeugDetailsRenderer());
final List<Fahrzeug> fahrzeuge = Fahrzeug.setData();
grid.setItems(fahrzeuge);
this.add(grid);
}
private Renderer<Fahrzeug> createFahrzeugDetailsRenderer()
{
return new ComponentRenderer<>(FahrzeugDetailLayout::new,
FahrzeugDetailLayout::setFahrzeug);
}
}
public class FahrzeugDetailLayout extends FormLayout
{
private final Image image = new Image("", "");
public FahrzeugDetailLayout()
{
setResponsiveSteps(new ResponsiveStep("0", 1));
setColspan(this.image, 1);
this.add(this.image);
}
public void setFahrzeug(final Fahrzeug fahrzeug)
{
this.image.setAlt("Bild wird nicht angezeigt!");
this.image.setSrc(fahrzeug.getUrl());
}
}
I dont understand why it is only cut of when you first open the detail and not when you click around and click on it again.
I dont really know what to try to fix this, because i dont know what is causing it to happen.
I tryed google for it but this Problem is very specific.
Thankfull for all the help!
I'm having a problem and I don't know how to solve it. I'm building a "food company" and want to write a program to control the items that have been bought/sold, etc.
I have viewDrinks.fxml, jdbcDrinks.java, controllerDrinks.java where I controll the drinks, for adding or deleting them and persisting them in a database.
But now, I have another view called "Sales" where I want to choose from a ComboBox what drink I want to sell. I'm not sure how I should fill this combobox with items that are not in jdcbSales, sales.fxml and controllerSales.fxml.
I been trying differrent approaches but I haven't found a working solution.
On my controllerSales I have:
jdbcDrinks databaseObject;
#FXML
private ComboBox drinkField;
public void initialize(URL location, ResourceBundle resources) {
ObservableList<String> drinkList = FXCollections.observableArrayList(databaseObject);
this.drinkField.setItems(drinkList);
this.drinkField.setEditable(false);
this.drinkField.getSelectionModel().select(0);
}
In jdbcDrinks I have:
public void getDrinkName{
ps = conexion.prepareStatement("SELECT name FROM drinks");
rs = ps.executeQuery();
}
I want to write a method in jdbcDrinks to get the items from the database, but I'm not sure how to write it and use it on controllerSales.
I have some trouble using javaFX to fill a tableColumn with some data according to a selected index from an other table.
the Table starts empty.
and then I want to fill it when the user press a button. (so far, so good)
here's what the button controller looks like :
#FXML
private void handleNextRequest() {
int selectedIndex = headingTable.getSelectionModel().getSelectedIndex();
if (selectedIndex >= 0)
mainApp.updateEntity(headingColumn.getCellData(selectedIndex));
entityTable.setItems(mainApp.getEntity());
}
So this calls a function from the main class which update my observable list.
The selectedIndex parameter is used to determine which data I have to load in the list (those data are located on a database which I can access via a web service, hence the "api" (which works fine)).
So here's what this function looks like :
public void updateEntity(String header){
try {
this.entity.clear();
int i = 0;
while(header != heading.get(i).getName()){
i++;
}
api.getEntity(new URL(heading.get(i).getURL()), this.entity, primaryStage);
} catch(MalformedURLException e){}
}
And up to this point everything is functional. when pressing the button the function is called properly and the observable list (entity) is updated correctly. (checked and re-checked)
and then... boom.
the "setItems" function (back to the button controller) doesn't seems to like whatever I've done and throw a NullPointerException.
If someone could help me understand what the problem might be here I would be delighted !
EDIT :
here's the initialize code that I have :
I have this in the initialize method :
#FXML
private void initialize() {
headingColumn.setCellValueFactory(CellData -> CellData.getValue().nameProperty());
entityColumn.setCellValueFactory(CellData -> CellData.getValue().nameProperty());
showTableDetails(null);
headingTable.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> showTableDetails(newValue));
}
and both entityTable and entityColumn declared properly.
Okay I figured it out.
Pretty dumb mistake but the fx:id="entityTable" was missing in the fxml file.
thank you for helping me realizing that !
I dont think my problem is that hard to solve but I have been searching for a while and cant figure it out.
I have two scene2d SelectBox widgets one above the other, in a table, on a stage. Let's call them A and B. Whatever is selected in A determines which list is shown in B. I implement this using a ChangeListener on A and all works fine (this isn't the problem).
However, my list A was getting extremely long (500+ items) so I wanted to add a TextField above it which would search and match the strings, replacing the old list of A with a shorter one, making it much easier to find what you are looking for. This works fine, I use a ChangeListener on the textfield to get the string, compare it to a main list of strings using a for loop and use aList.setItems(); to add the adjusted string to the SelectBox. The list displays (without a click, so I use aList.showList(); in the ChangeListener of the TextField) and I think this is where the problem occurs - instead of a click, showList() is called from elsewhere. Lets say I change my mind and want to select a different item from A, it will no longer drop down the menu on click. Yet if I change the text which is in the search bar, it displays the list. When the list is displayed, I can click an item and it hides as normal.
This might seems a bit confusing, so here is the code (edited for clarity, so if something is missing let me know)
SelectBox aSelect, bSelect;
TextField searchBar;
Stage stage;
Table table;
Skin skin;
ArrayList<String> completeAList;
ArrayList<String> abrevAList;
public chooseItemScreen()
{
stage = new Stage(new ScreenViewport());
skin = new Skin(Gdx.files.internal("uiskin.json"));
table = new Table();
table.setFillparent(true);
completeAList = new ArrayList<String>;
abrevAList = new ArrayList<String>;
aSelect = new SelectBox(skin);
//ItemList is a class with the list of strings as a static method
completeAList = ItemList.getAList();
aSelect.setItems(completeAList.toArray());
//bSelect omitted as is same as A
//aSelect changeListener also omitted as it is working fine
searchBar = new TextField("", skin);
searchBar.setMessageText("SEARCH LIST");
searchPokemon.addListener(new ChangeListener() {
#Override
public void changed(ChangeEvent event, Actor actor) {
updateASelect();
}
});
table.add(searchBar);
table.row();
table.add(aList);
stage.addActor(table);
Gdx.input.setInputProcessor(stage);
}
private void updateAList()
{
abrevAList.clear();
aSelect.clearItems();
aSelect.hideList()
for (String string: completeAList)
{
if (string.toLowerCase().startsWith(searchBar.getText().toLowerCase()))
{
abrevAList.add(string);
}
}
if (abrevAList.isEmpty())
{
abrevAList.add("NOT FOUND");
}
aSelect.setItems(abrevAList.toArray());
//It's at this point where I am no longer to click on aSelect
//I can still select an item from the drop down list, closing the list
//it's just I can't show list by clicking on the widget after that
aSelect.showList();
}
#Override
public void render(float delta) {
Gdx.gl20.glClearColor(0,0,0,0);
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act();
stage.draw();
}
I added the following listener to tell if the selectBox was being clicked (which it was). I gave all actors names
stage.getRoot().addCaptureListener(new InputListener() {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
System.out.println(event.getTarget().getName());
return false;
}
});
The click is recognised, just the list doesn't show. In my opinion, it is a problem with calling showList() and changing the list at the same time.
Any help is appreciated, and if you need more code or any other information, let me know.
Thanks
Set a fixed size to the selectbox when adding it to the table, something like
table.add(selectBox).width(someValue);
or
table.add(selectBox).growX();
Also, after reviewing your code, I suggest you to remove
aSelect.clearItems();
aSelect.hideList();
And make ArrayList be just libgdx Array< String>, it will make things easier, wont cause allocation when iterating with ':' and you wont need .toArray() when setting the items of your selectboxes. You also can set SelectBox type with SelectBox< String>, and, you can add a row in the same line with table.add(something).row().
After changing the size of the selectbox cell your code worked just fine in my side.
The content of the tab is formed and displayed when the application is loaded. Later the content of the tab may be changed by other actions. I want to show the newer content after each action. And each time when I click the tab sheet, the content should be refresh/updated. But I failed.
//the content of the tab from the "reprintsTab" class
//in the "reprintsTab" it query data from database and print out
//later I update the data in the database from somewhere else, and I want the tab shows the new content
//I want to click the tab sheet to reload the "reprintTab" class and print out the new content
//here is what I did:
public TabSheet sheet;
//add tab and add the content from "reprintTab" into this tab
sheet.addTab(new reprintsTab());
//add the listener
sheet.addListener(new TabSheet.SelectedTabChangeListener() {
#Override
public void selectedTabChange(SelectedTabChangeEvent event) {
//I know it does not work, because it only reload the class. but not put the content under the tab I want
new reprintsTab();
}
});
What should I do? please help me, thanks.
You can use TabSheet.replaceComponent method to do this:
//Field to store current component
private reprintsTab currentComponent;
//during initialization
currentComponent = new reprintsTab();
sheet.addTab(currentComponent);
sheet.addListener(new TabSheet.SelectedTabChangeListener() {
#Override
public void selectedTabChange(SelectedTabChangeEvent event) {
reprintsTab newComponent = new reprintsTab();
sheet.replaceComponent(currentComponent, newComponent);
currentComponent = newComponent;
}
});
Also, you might want to reload this tab only when it's shown:
sheet.addListener(new TabSheet.SelectedTabChangeListener() {
#Override
public void selectedTabChange(SelectedTabChangeEvent event) {
if (event.getTabSheet().getSelectedTab() == currentComponent) {
//here goes the code
}
}
});
This should work for you, but I would suggest a cleaner approach: implement reprintsTab as a container for components, create method reload or buildInterface method to refresh its' state, so you can just call:
currentComponent.reload();
when you need to update interface.
Also, I hope reprintsTab is just an example name, java class names starting with lowercase letter look ugly.