Javafx: How do you target objects in nested views? - javafx

I understand that for each time I load a nested fxml and controller that I can use that controller to manipulate the nested fxml. For example I can make every other row purple, but what I don't understand is how, after everything is loaded, can I target something specific to manipulate.
This is the most bare bones minimal replicate-able example I can make, anything reduced from this doesn't fit the criteria of a nested fxml and a child. What I want to do here is take the first score, with the text "Score0" and change it to "10" when the 10 button is pushed. I have a feeling I'm close, the score box should be score[0]. It should also be nested in row[0], but I can't seem to get the scoreEntry method to find the box to change it.
Main.java:
public class Main extends Application {
#Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(Main.class.getResource("view1.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 400, 300);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
view1.fxml:
<AnchorPane prefHeight="300.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.nested.Ctrl1">
<children>
<VBox fx:id="rowHolder" prefHeight="260.0" prefWidth="400.0" />
<Button mnemonicParsing="false" onAction="#scoreEntry" prefHeight="40.0" prefWidth="40.0" text="10" AnchorPane.leftAnchor="70.0" AnchorPane.topAnchor="260.0" />
<Button mnemonicParsing="false" onAction="#scoreEntry" prefHeight="40.0" prefWidth="40.0" text="0" AnchorPane.topAnchor="260.0" />
</children>
</AnchorPane>
Ctrl1.java:
public class Ctrl1 {
#FXML
private VBox rowHolder;
#FXML
void initialize() {
addRows();
}
public void addRows() {
int rounds = 2;
HBox row[];
row = new HBox[rounds];
String ctrlArray[];
ctrlArray = new String[rounds];
for (int i = 0; i < row.length; i++) {
row[i] = new HBox();
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/nested/view2.fxml"));
row[i] = loader.load();
rowHolder.getChildren().add(row[i]);
Ctrl2 ctrl2 = loader.getController();
ctrlArray[i] = String.valueOf(ctrl2);
ctrl2.setRoundNum(String.valueOf(i));
System.out.println(row[i]);
} catch (IOException e) {
e.printStackTrace();
}
}
for (int i = 0; i < ctrlArray.length; i++) {
System.out.println("Controller: " + ctrlArray[i]);
}
}
private BigDecimal scoreInput;
private boolean numberInput;
#FXML
public void scoreEntry(ActionEvent event) {
Button button = (Button) event.getSource();
String buttonText = button.getText();
if (buttonText.matches("[0-10\\.]")) {
if (!numberInput) {
numberInput = true;
//TODO: find Label for input text
//I think it should be something like "row[0].getChildren().score[0].clear();"
}
//And then I would append it with something like "score[0].appendText(buttonText);"
return;
}
}
}
view2.fxml
<HBox prefHeight="30.0" prefWidth="400.0" style="-fx-background-color: #77e77e;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.nested.Ctrl2">
<children>
<Label fx:id="rowNum" text="Row Number" />
<HBox fx:id="scoresHolder" prefHeight="100.0" prefWidth="200.0" />
<Label fx:id="subTotal" text="Sub Total" />
<Label fx:id="total" text="Total" />
</children>
</HBox>
Ctrl2.java
public class Ctrl2 {
#FXML
private Label rowNum;
#FXML
private Label subTotal;
#FXML
private HBox scoresHolder;
#FXML
private Label total;
public void setRoundNum(String strRnd) {
rowNum.setText(strRnd);
}
public void setSubTotal(String strRnd) {
subTotal.setText(strRnd);
}
public void setTotal(String strRnd) {
total.setText(strRnd);
}
#FXML
void initialize() {
int plays = 1;
Label score[];
score = new Label[plays];
for (int i = 0; i < score.length; i++) {
score[i] = new Label("Score" + i);
scoresHolder.getChildren().add(score[i]);
System.out.println(score[i]);
}
}
}

I took #James_D's advice and wrapped my controllers and cells in arrays.
//This is the array for the controllers. It's outside the method to be accessed by other methods.
public static Ctrl2[] ctrlArray = new Ctrl2[2];
public void addRows() {
int rounds = 2;
HBox row = null;
for (int i = 0; i < rounds; i++) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/nested/view2.fxml"));
row = loader.load();
rowHolder.getChildren().add(row);
ctrlArray[i] = loader.getController();
ctrlArray[i].setRoundNum(String.valueOf(i));
} catch (IOException e) {
e.printStackTrace();
}
}
for (int i = 0; i < ctrlArray.length; i++) {
System.out.println("Controller: " + ctrlArray[i]);
}
}
The problem I was having was with scope. If I make the array holder outside the method I can access it from other methods.
private Label[] score;
public void addScores() {
int plays = 2;
//Moved array holder from here to outside
score = new Label[plays];
for (int i = 0; i < score.length; i++) {
score[i] = new Label("Score" + i);
scoresHolder.getChildren().add(score[i]);
System.out.println(score[i]);
}
}

Related

Update structure JavaFX TreeTableView

I create two windows and pass the Instance controller to the child window as a parameter. My problem is updating on the fly. I tried calling the refresh() method on treeTblState but nothing came of it.
First window
<AnchorPane xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mo.specdoc.controllers.StateController">
<children>
<TreeTableView fx:id="treeTblState" showRoot="false">
<columns>
....
</columns>
</TreeTableView>
</children>
</AnchorPane>
Controller
public class StateController implements Initializable {
private static Map<Long, TreeItem> subdivisions = new HashMap<>();
private static StateController instance;
#FXML private TreeTableColumn<StateEntity, String> tblClmnTitle,...,tblClmnDelete;
#FXML private TreeTableView<StateEntity> treeTblState = new TreeTableView<>();
//Create root element (property setShow = false в FXML)
private StateEntity root = new StateEntity(0L,"State");
//Pattern Instance
public static StateController getInstance() {
if (instance == null) {
instance = new StateController();
}
return instance;
}
#Override
public void initialize(URL location, ResourceBundle resources) {
try {
tblClmnTitle.setCellValueFactory(new TreeItemPropertyValueFactory<>("postName"));
...
tblClmnDelete.setCellValueFactory(new TreeItemPropertyValueFactory<>("delete"));
treeGreate();
} catch ....
}
public void addChildren(StateEntity state) {
TreeItem<StateEntity> item = null;
for (Long key : subdivisions.keySet()) {
if (key == state.getSubdivisionId()) {
TreeItem<StateEntity> subdiv = subdivisions.get(key);
item = new TreeItem<StateEntity>(state);
subdiv.getChildren().add(item);
}
}
}
private void treeGreate() {
TreeItem<StateEntity> itemRoot = new TreeItem<StateEntity>(root);
treeTblState.setRoot(itemRoot);
//create tree - level 2
//subdivisions
for (SubdivisionEntity subdivision : subdivisionDAO.findAll()) {
StateEntity state = new StateEntity(
subdivision.getId(),
subdivision.getTitle()
);
state.getAdd().setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent e) {
createScene("Add post", new StateEntity(), subdivision.getId());
}
});
TreeItem<StateEntity> subdiv = new TreeItem<StateEntity>(state);
itemRoot.getChildren().add(subdiv);
subdivisions.put(state.getSubdivisionId(), subdiv);
//posts
List<StateEntity> childrens = stateDAO.findByIdSubdiv(state.getSubdivisionId());
if (!childrens.isEmpty()) {
for (StateEntity child : childrens) {
TreeItem<StateEntity> item = new TreeItem<StateEntity>(child);
subdiv.getChildren().add(item);
}
}
}
}
private void createScene(String title, StateEntity state, Long subdivisionId) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/views/state-edit.fxml"));
StateEditController stateEditController = new StateEditController(state, subdivisionId);
loader.setController(stateEditController);
Stage stage = new Stage();
Scene scene = new Scene(loader.load());
stage.setScene(scene);
stage.initModality(Modality.APPLICATION_MODAL);
stage.showAndWait();
} catch ....
}
}
Result
Second window
<AnchorPane xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1">
<children>
...elements...
</children>
</AnchorPane>
Controller
public class StateEditController implements Initializable {
....
#FXML
void saveAction(ActionEvent event) {
currentEntry.setSubdivisionId(subdivisionId);
currentEntry.setMaxAmountPersonal(cmbBoxMaxAmount.getSelectionModel().getSelectedItem().intValue());
currentEntry.setMinAmountPersonal(cmbBoxMaxAmount.getSelectionModel().getSelectedItem().intValue());
currentEntry.setAmplification(tglSwitchAmpl.isSelected());
currentEntry.setPostId(cmbBoxPost.getSelectionModel().getSelectedItem().getId());
if (currentEntry.getId() == null) {
stateDAO.save(currentEntry);
} else {
stateDAO.update(currentEntry);
}
stateController.addChildren(currentEntry); //call instance metod
}
#Override
public void initialize(URL location, ResourceBundle resources) {
....
}
}
Result
Everything is entered into the database successfully, but it is not updated when the window is closed 2.
I redraw the child elements using the clear method when adding an item
public void addChildren(StateEntity state) {
subdivisions.get(state.getSubdivisionId()).getChildren().clear();
List<StateEntity> childrens = stateDAO.findByIdSubdiv(state.getSubdivisionId());
if (!childrens.isEmpty()) {
for (StateEntity child : childrens) {
TreeItem<StateEntity> item = new TreeItem<StateEntity>(child);
subdivisions.get(state.getSubdivisionId()).getChildren().add(item);
}
}
}

issue with using extended JavaFX Class Dialog<R> and initializing the DialogPane

I use an extended Dialog class in my JavaFX application, but I failed to initialize the fields of the DialogPane. It seems the initialize method is never invoked. I make several modifications of the program code, unfortunately I do not have success. Therefore I hope you can help me. Thanks!
The application is reduced to a minimum: the main program starts via ControllerFactory the PortalController. There is a button to open my 'DialogFriZi'. The related DialogPane contains a label. The initializing of this label failed.
main program:
public class Main extends Application {
private final Logger logger = Logger.getLogger(this.getClass().getName());
private final String FXML_PORTAL = "portal.fxml";
private MyHandler myHandler = new MyHandler();
#Override
public void init() {
try{
// Thread.currentThread is the FX-Launcher thread:
Thread.currentThread().setUncaughtExceptionHandler(myHandler);
try {
logger.addHandler(new FileHandler("java.myLOG"));
}
catch (IOException e) {
throw new IllegalStateException("IOException when adding File Handler");
}
}
catch (Exception ex) {
myHandler.uncaughtException(Thread.currentThread(), ex);
throw(ex);
}
}
#Override
public void start(Stage primaryStage) {
try{
logger.info("Test Application started");
Thread.currentThread().setUncaughtExceptionHandler(myHandler);
try{
URL location = new URL(this.getClass().getResource("resources/fxml/" + FXML_PORTAL).toString());
FXMLLoader loader = new FXMLLoader(location);
loader.setControllerFactory(new SimpleControllerFactory(primaryStage));
Pane root = loader.load();
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setTitle("*** TEST App ***");
primaryStage.show();
}
catch(IOException ex) {
ex.printStackTrace();
throw new IllegalStateException("check program source code!");
}
}
catch(Exception ex) {
myHandler.uncaughtException(Thread.currentThread(), ex);
throw(ex);
}
}
public static void main(String[] args) {
launch(args);
}
class MyHandler implements Thread.UncaughtExceptionHandler{
#Override
public void uncaughtException(Thread thread, Throwable throwable) {
logger.log(Level.SEVERE, "** STOPP ** due to uncaught exception", throwable);
Platform.exit();
}
}
}
ControllerFactory
public class SimpleControllerFactory implements Callback<Class<?>,Object> {
private static final Logger logger = Logger.getLogger(SimpleControllerFactory.class.getName());
private final Stage primaryStage;
// types of controller
public SimpleControllerFactory(Stage stage) {
this.primaryStage = stage;
}
public SimpleControllerFactory() { this(null); }
#Override
public Object call(Class<?> type) {
try {
for (var c : type.getConstructors()) {
switch(c.getParameterCount()) {
case 0 -> { }
case 1 -> {
if ( c.getParameterTypes()[0] == Stage.class) {
return c.newInstance(primaryStage) ;
}
else;
}
default -> { }
}
}
return type.getDeclaredConstructor().newInstance();
}
catch (InvocationTargetException | InstantiationException | IllegalAccessException | NoSuchMethodException ex) {
logger.log(Level.SEVERE,ex.toString(),ex);
throw new RuntimeException(ex);
}
}
}
PortalController
public class PortalController implements Initializable {
private static final Logger logger = Logger.getLogger(PortalController.class.getName());
private final Stage recentStage;
private ResourceBundle resourceBundle;
public PortalController(Stage stage) {
this.recentStage = stage;
}
public PortalController() {
this(null);
}
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
this.resourceBundle = resourceBundle;
}
#FXML
private void start(ActionEvent event) {
DialogFriZi dialog = null;
dialog = new DialogFriZi(recentStage);
Optional<Boolean> result = dialog.showAndWait();
}
}
related FXML file
<VBox prefHeight="500.0" prefWidth="400.0" spacing="5.0" style="-fx-padding: 5 5 5 5;-fx-font-size: 11px" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="TestSimpleDialog.PortalController">
<children>
<HBox alignment="CENTER">
<children>
<Button mnemonicParsing="false" onAction="#start" text="start FriZi dialog">
<HBox.margin>
<Insets top="50.0" />
</HBox.margin>
</Button>
</children>
</HBox>
</children>
the extended Dialog class
public class DialogFriZi extends Dialog<Boolean> {
#FXML private ButtonType okButtonType;
#FXML Label label;
private static final Logger logger = Logger.getLogger(DialogFriZi.class.getName());
private final Stage recentStage;
public DialogFriZi(Stage primaryStage) {
this.recentStage = primaryStage;
runDialog();
}
public DialogFriZi() {
this(null);
}
#FXML private void initialize() {
System.out.println("start initializing");
label.setText("hello");
}
private void runDialog() {
FXMLLoader loader = new FXMLLoader();
try {
loader.setLocation(new URL
(this.getClass().getResource("resources/fxml/dialogFriZi.fxml").toString()));
DialogPane dialogPane = loader.load();
loader.setController(this);
initOwner(recentStage);
initModality(Modality.APPLICATION_MODAL);
setResizable(true);
setTitle("FriZi Dialog");
setDialogPane(dialogPane);
}
catch (IOException e) {
String message = "illegale state due to problem with 'resource dialogFriZi.fxml'";
logger.log(Level.SEVERE,message);
throw new IllegalStateException(message);
}
}
}
related FXML file
<DialogPane prefHeight="400.0" prefWidth="300.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1">
<content>
<HBox prefHeight="100.0" prefWidth="200.0">
<children>
<Label fx:id="label" text="Label" />
</children></HBox>
</content>
<buttonTypes>
<ButtonType buttonData="OK_DONE" text="ok" />
<ButtonType buttonData="CANCEL_CLOSE" text="Abbrechen" />
</buttonTypes>
The initalize() method is invoked on the controller, if there is one, during the execution of the load() method. You are setting the controller after calling load(), so when load() runs, there is no controller. You need to change the order of the calls:
private void runDialog() {
FXMLLoader loader = new FXMLLoader();
try {
loader.setLocation(new URL
(this.getClass().getResource("resources/fxml/dialogFriZi.fxml").toString()));
loader.setController(this);
DialogPane dialogPane = loader.load();
// loader.setController(this);
initOwner(recentStage);
initModality(Modality.APPLICATION_MODAL);
setResizable(true);
setTitle("FriZi Dialog");
setDialogPane(dialogPane);
}
catch (IOException e) {
String message = "illegale state due to problem with 'resource dialogFriZi.fxml'";
logger.log(Level.SEVERE,message);
throw new IllegalStateException(message);
}
}

How to add a javafx shortcut key combinations for buttons

My UI has a adding button and I want to assign a keyboard shortcut combination for that. I have failed to use the setAcceleartor for this purpose.
What is the easiest way to set up keyboard shortcuts in javafx applications?
button declaration in the UI:
<Button fx:id="addButton" alignment="CENTER" minWidth="-Infinity" mnemonicParsing="false" onAction="#addAction" prefHeight="31.0" prefWidth="130.0" text="Add" HBox.hgrow="ALWAYS" />
Controller button binding:
#FXML
private Button addButton;
The method that wants to setOnAction for the shortcut for the button:
public void addAction(ActionEvent event) throws SQLException, ClassNotFoundException {
if (validateInput()) {
String productName = productField.getText();
double unitPrice = Double.parseDouble(priceField.getText());
int quantity = Integer.parseInt(quantityField.getText());
double total = unitPrice * quantity;
ITEMLIST.add(new Item(productName, unitPrice, quantity, total));
calculation();
resetAdd();
productTableView.getSelectionModel().clearSelection();
ObservableList<Product> productsData = ProductDAO.searchProducts();
populateProducts(productsData);
searchField.setText("");
}
}
initialize() method:
#FXML
private void initialize() throws SQLException, ClassNotFoundException, IOException {
setSaveAccelerator(addButton);
}
The code I tried with setAccelerator:
private void setSaveAccelerator(final Button button) {
Scene scene = button.getScene();
if (scene == null) {
throw new IllegalArgumentException("setSaveAccelerator must be called when a button is attached to a scene");
}
scene.getAccelerators().put(
new KeyCodeCombination(KeyCode.S, KeyCombination.SHORTCUT_DOWN),
new Runnable() {
#FXML public void run() {
button.fire();
}
}
);
}
In your setSaveAccelerator method, instead of directly calling addAction(ActionEvent event), just instruct the button to fire its event to its listeners such as: button.fire(). For example:
private void setSaveAccelerator(Button button) {
if(button==null) {
System.out.println("Button is null! "); // check that the button was injected properly through your fxml
}
Scene scene = button.getScene();
if (scene == null) {
throw new IllegalArgumentException("setSaveAccelerator must be called when a button is attached to a scene");
}
scene.getAccelerators().put(
new KeyCodeCombination(KeyCode.S, KeyCombination.SHORTCUT_DOWN),
new Runnable() {
#FXML public void run() {
button.fire();
}
}
);
}
EDIT
To also avoid the IllegalArgumentException you must attach the accelerator after the button is attached to a scene. I managed to achieve this by creating a public method in the controller to attach the accelerator after the scene has been set. Then, in the class where the scene is loaded the controller's method can be called which sets up this functionality. See the example below:
In the controller class (in my case MainController):
public void setup() {
setSaveAccelerator(button);
}
In your main class when loading the fxml file:
FXMLLoader loader = new FXMLLoader(MainController.class.getResource("mainFXML.fxml"));
AnchorPane page = (AnchorPane) loader.load();
MainController controller = loader.getController();
Scene scene = new Scene(page);
controller.setup(); // calls the setup method attaching the accelerators
FULL EXAMPLE
Main class:
public class Main extends Application{
public static Stage primaryStage;
#Override
public void start(Stage primaryStage) throws Exception {
Main.primaryStage=primaryStage;
FXMLLoader loader = new FXMLLoader(MainController.class.getResource("mainFXML.fxml"));
AnchorPane page = (AnchorPane) loader.load();
MainController controller = loader.getController();
Scene scene = new Scene(page);
primaryStage.setTitle("Shortcut example");
primaryStage.setScene(scene);
controller.setup();
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Maincontroller:
public class MainController {
#FXML
private ResourceBundle resources;
#FXML
private URL location;
#FXML
private Button button;
#FXML
private AnchorPane rootPane;
#FXML
private TextArea textarea;
#FXML
void action(ActionEvent event) {
textarea.setText("Action fired!!");
}
#FXML
void initialize() {
assert button != null : "fx:id=\"button\" was not injected: check your FXML file 'MainFXML.fxml'.";
assert rootPane != null : "fx:id=\"rootPane\" was not injected: check your FXML file 'MainFXML.fxml'.";
assert textarea != null : "fx:id=\"textarea\" was not injected: check your FXML file 'MainFXML.fxml'.";
}
public void setup() {
setSaveAccelerator(button);
}
private void setSaveAccelerator(Button button) {
if(button==null) {
System.out.println("Button null!!");
}
Scene scene = button.getScene();
if (scene == null) {
throw new IllegalArgumentException("setSaveAccelerator must be called when a button is attached to a scene");
}
scene.getAccelerators().put(
new KeyCodeCombination(KeyCode.S, KeyCombination.SHORTCUT_DOWN),
new Runnable() {
#FXML public void run() {
button.fire();
}
}
);
}
}
MainFXML.fxml
<AnchorPane fx:id="rootPane" prefHeight="408.0" prefWidth="330.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainController">
<children>
<Button fx:id="button" layoutX="139.0" layoutY="350.0" mnemonicParsing="false" onAction="#action" text="Button" />
<TextArea fx:id="textarea" layoutX="73.0" layoutY="38.0" prefHeight="200.0" prefWidth="200.0" />
</children>
</AnchorPane>

How to change values in tableview simultaneously whenever i select an corresponding item from comboboxtablecell

I tried but I got stuck at a point where am getting the corresponding values of the selected item from comboboxtablecell but cannot add the values to the corresponding column in the table view
Controller.java
public class controller {
GetConnection gc = new GetConnection();
PreparedStatement pst;
ResultSet rs;
Statement st;
private ObservableList<Users> datas = FXCollections.observableArrayList();
public controller(){}
#FXML
private TableView<Users> table;
#FXML
private TableColumn<Users,String> c1;
#FXML
private TableColumn<Users,String> c2;
#FXML
private TableColumn<Users,String> c3;
#FXML
private void editable() {
try {
ObservableList<Users> datas = FXCollections.observableArrayList();
ObservableList<String> item = FXCollections.observableArrayList();
ObservableList<String> iprice = FXCollections.observableArrayList();
String sql = "select * from itemsadd";
pst = gc.getConnection().prepareStatement(sql);
rs = pst.executeQuery();
while (rs.next()) {
String name = rs.getString("itemcode");
String cat=rs.getString("unitprice");
item.add(name);
iprice.add(cat);
System.out.println("probs" + item);
}
ResultSet rs2 = gc.getConnection().createStatement()
.executeQuery("SELECT * FROM itemsadd WHERE itemcode=1001");
while (rs2.next()) {
datas.add(new Users(rs2.getString("itemcode"),rs2.getString("category"),rs2.getString("unitprice")));
}
c1.setCellValueFactory(new PropertyValueFactory("Itemc"));
c1.setCellFactory(ComboBoxTableCell.forTableColumn(item));
for(String name:item){
c1.setCellValueFactory(new PropertyValueFactory("Itemc"));
c1.setCellFactory(ComboBoxTableCell.forTableColumn(item));
System.out.println("hell3"+name);
}c1.setOnEditCommit( ( TableColumn.CellEditEvent<Users, String> e ) ->
{
String newValue = e.getNewValue();
int index = e.getTablePosition().getRow();
System.out.println("position"+index);
try{
System.out.println("new values"+newValue);
String dsql="SELECT category,unitprice FROM itemsadd WHERE itemcode=?;";
pst=gc.getConnection().prepareStatement(dsql);
pst.setString(1, newValue); //this replaces the 1st "?" in the query for username
rs=pst.executeQuery();
while(rs.next())
{
String category1 = rs.getString(1);
String price1 = rs.getString(2);
System.out.println("category is"+category1);
System.out.println("unitprice is"+price1);
}
}catch(Exception ed){} } );
c2.setCellValueFactory(new PropertyValueFactory("category"));
c2.setCellFactory(TextFieldTableCell.forTableColumn());
c3.setCellValueFactory(new PropertyValueFactory("unitprice"));
c3.setCellFactory(ComboBoxTableCell.forTableColumn(iprice));
table.setEditable(true);
table.getItems().clear();
table.setItems(datas);
} catch (Exception e) {
e.printStackTrace();
System.out.println("Error on Building Data");
}
}
public static class Users {
private StringProperty Itemc;
private StringProperty category;
private StringProperty unitprice;
private Users(String Itemc,String category,String unitprice) {
this.Itemc= new SimpleStringProperty(Itemc);
this.category=new SimpleStringProperty(category);
this.unitprice=new SimpleStringProperty(unitprice);
}
public String getItemc() {
return Itemc.get();
}
public void setItemc(String Itemc) {
this.Itemc.set(Itemc);
}
public StringProperty ItemcProperty() {
return Itemc;
}
public String getcategory() {
return category.get();
}
public void setcategory(String category) {
this.category.set(category);
}
public StringProperty categoryProperty() {
return category;
}
public String getunitprice() {
return unitprice.get();
}
public void setunitprice(String unitprice) {
this.unitprice.set(unitprice);
}
public StringProperty unitpriceProperty() {
return unitprice;
}}
}
Table.fxml
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication47.controller">
<children>
<TableView fx:id="table" editable="true" layoutX="136.0" layoutY="58.0" onKeyPressed="#editable" prefHeight="200.0" prefWidth="335.0">
<columns>
<TableColumn fx:id="c1" prefWidth="116.0" text="Code" />
<TableColumn fx:id="c2" prefWidth="115.0" text="Address" />
<TableColumn fx:id="c3" prefWidth="102.0" text="Price" />
</columns>
</TableView>
</children>
</AnchorPane>
Tableview.java
public class Tableveiw extends Application {
private Stage primaryStage;
private AnchorPane pane;
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("AddressApp");
showPerson();
}
public void showPerson() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Tableveiw.class
.getResource("table.fxml"));
pane= (AnchorPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(pane);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}}
public static void main(String[] args) {
launch(args);
}
}
GetConnection.java
public class GetConnection{
public Connection getConnection() throws Exception
{
Connection con=null;
try {
System.out.println("MySQL Connect Example.");
String url = "jdbc:mysql://localhost:3306/";
String dbName = "login";
String driver = "com.mysql.jdbc.Driver";
Class.forName(driver).newInstance();
con = DriverManager.getConnection(url+dbName,"root","");
} catch (Exception e) {
e.printStackTrace();
}
return con;
}
public static void main(String arg[])
{
GetConnection con =new GetConnection();
System.out.println("Connection"+con);
}
}
The above code is runnable and simplified and the program has a tableview and three column with first columncell is a comboboxtablecell having items in it.The second columncell is a editable text field and third column cell is a comboboxtablecell with its items in database.I have tried myself where am getting values of the corresponding values in the row whenever I select value in combo box table cell in category.java System.out.println("categoryis"+category1);
System.out.println("unitprice is"+price1); .Please help me to change values in tableview whenever I select item in the combobox in table view.
You need to
Go to your cell factory code
1add event handler for combobox selection change
Get current row
Get current item
Change the value you need
Sample ComboBox Selected items changing values of tableview example.
Tablecombo.java
public class Tablecombo extends Application {
Stage primaryStage;
Scene scene;
String username;
AnchorPane anchorpane;
BorderPane borderpane;
// Pane pane;
BorderPane border;
Stage sstage;
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("Login");
root();
}
public void root() {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Tablecombo.class.getResource("tcombo.fxml"));
anchorpane = (AnchorPane) loader.load();
Stage dialogStage = new Stage();
dialogStage.setTitle("Main");
dialogStage.initModality(Modality.WINDOW_MODAL);
Scene scene = new Scene(anchorpane);
dialogStage.setScene(scene);
dialogStage.showAndWait();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
tablecontroller.java
public class tablecontroller {
Tablecombo main;
GetConnection gc = new GetConnection();
PreparedStatement pst;
ResultSet rs;
public tablecontroller(){
}
#FXML
private TableView<UserData> table4;
#FXML
private TableColumn<UserData,String> c1;
#FXML
private TableColumn<UserData,String> c2;
#FXML
private void editable() {
try {
ObservableList<UserData> datas = FXCollections.observableArrayList();
ObservableList<String> names = FXCollections.observableArrayList();
ObservableList<String> rat = FXCollections.observableArrayList();
// ObservableList<Users> datas = FXCollections.observableArrayList();
String sql = "select * from pdfs";
// String msql="select * from category";
pst = gc.getConnection().prepareStatement(sql);
rs = pst.executeQuery();
while (rs.next()) {
String name = rs.getString("name");
String cat=rs.getString("country");
rat.add(cat);
names.add(name);
System.out.println("probs" + names);
}
ResultSet rs2 = gc.getConnection().createStatement().executeQuery("SELECT * FROM pdfs LIMIT 1");
//ObservableList<Users> datas = FXCollections.observableArrayList();
while (rs2.next()) {
datas.add(new UserData(rs2.getString("name"),rs2.getString("country")));
}
c1.setCellValueFactory(new PropertyValueFactory("Itemc"));
c1.setCellFactory(ComboBoxTableCell.forTableColumn(names));
for(String name:names){
c1.setCellValueFactory(new PropertyValueFactory("Itemc"));
// System.out.println("hell2"+name);
c1.setCellFactory(ComboBoxTableCell.forTableColumn(names));
System.out.println("hell3"+name);
}
c1.setOnEditCommit( ( TableColumn.CellEditEvent<UserData, String> e ) ->
{
String newValue = e.getNewValue();
int index = e.getTablePosition().getRow();
System.out.println("position"+index);
try{
ObservableList<UserData> data = FXCollections.observableArrayList();
System.out.println("new values"+newValue);
String dsql="SELECT * FROM pdfs WHERE name=?;";
pst=gc.getConnection().prepareStatement(dsql);
System.out.println("quer"+dsql);
pst.setString(1, newValue); //this replaces the 1st "?" in the query for username
rs=pst.executeQuery();
while(rs.next())
{
data.add(new UserData(rs.getString("name"),rs.getString("country")));
}
table4.setItems(data);
String a = rs.getString(1);
String b = rs.getString(2);
String c = rs.getString(3);
System.out.println("su"+a);
System.out.println("ma"+b);
System.out.println("man"+c);
}catch(Exception ed){} } );
c2.setCellValueFactory(new PropertyValueFactory("quantity"));
c2.setCellFactory(TextFieldTableCell.forTableColumn());
table4.setEditable(true);
table4.setItems(datas);
} catch (Exception e) {
e.printStackTrace();
System.out.println("Error on Building Data");
}
}
}
UserData.java
public class UserData {
private StringProperty Itemc;
private StringProperty quantity;
public UserData(String Itemc,String quantity) {
//this.Quantity = new SimpleStringProperty(Quantity);
this.Itemc= new SimpleStringProperty(Itemc);
this.quantity = new SimpleStringProperty(quantity);
}
public String getItemc() {
return Itemc.get();
}
public void setItemc(String Itemc) {
this.Itemc.set(Itemc);
}
public StringProperty ItemcProperty() {
return Itemc;
}
public void setquantity(String quantity) {
this.quantity.set(quantity);
}
public String getquantity() {
return quantity.get();
}
public StringProperty quantityProperty() {
return quantity;
}
}
tcombo.fxml
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="tablecombo.tablecontroller">
<children>
<TableView fx:id="table4" layoutX="168.0" layoutY="81.0" onKeyPressed="#editable" prefHeight="200.0" prefWidth="230.0">
<columns>
<TableColumn fx:id="c1" prefWidth="75.0" text="name" />
<TableColumn fx:id="c2" prefWidth="75.0" text="country" />
</columns>
</TableView>
</children>
</AnchorPane>

On Mouse Entered Method to swap Button position

I would like to develop a mouse entered method that swaps the locations of two buttons in real time using FXML and JavaFX which I am unfortunately very new to. Relocate(x,y), get/setLayoutX/Y and below get/setTranslateX/Y all throw IllegalArgumentEceptions with not much more understandable information in the stack trace. What is the preferred Button Property to use in order to get and then set a real-time location swap?
#FXML protected void neinHover (ActionEvent evt){
double jTmpX, jTmpY, nTmpX, nTmpY;
nTmpX = neinButton.getTranslateX();
nTmpY = neinButton.getTranslateY();
jTmpX = jaButton.getTranslateX();
jTmpY = jaButton.getTranslateY();
jaButton.setTranslateX(nTmpX);
jaButton.setTranslateY(nTmpY);
neinButton.setTranslateX(jTmpX);
neinButton.setTranslateY(jTmpY);
}
I supose you want something like this:
FXML:
<fx:root onMouseClicked="#swap" type="Pane" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8">
<children>
<Button fx:id="b1" mnemonicParsing="false" text="1" />
<Button fx:id="b2" layoutX="90.0" mnemonicParsing="false" text="2" />
</children>
</fx:root>
Controller:
public class MockPane extends Pane {
#FXML
private Button b1;
#FXML
private Button b2;
public MockPane() {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(
"MockPane.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
#FXML
private void swap() {
double b1x = b1.getLayoutX();
double b1y = b1.getLayoutY();
double b2x = b2.getLayoutX();
double b2y = b2.getLayoutY();
b1.setLayoutX(b2x);
b1.setLayoutY(b2y);
b2.setLayoutX(b1x);
b2.setLayoutY(b1y);
}
}
App:
public class MockApp extends Application {
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void start(Stage stage) throws Exception {
MockPane root = new MockPane();
Scene scene = new Scene(root, 200, 100);
stage.setScene(scene);
stage.show();
}
}

Resources