Access textarea in one controller from another controller JavaFX - javafx

I have two controllers FXMLDocumentController and FXMLOpenedCodeController. I am reading the contents of a .txt file from FXMLDocumentController and I want that text to be placed in a textarea in the FXMLOpenedCodeController. The code is running and reading well from the FXMLDocumentController but when the window from FXMLOpenedCodeController is opened, the read contents from .txt contents is not visible in the textarea. My system.out.println shows that String mine has the contents but it is not showing in the textarea in FXMLOpenedCodeController. Please help anyone. Thank you.
FXMLDocumentController code
public class FXMLDocumentController implements Initializable {
#FXML
private MenuItem open;
#FXML
private MenuItem about;
#Override
public void initialize(URL url, ResourceBundle rb) {
open.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle (ActionEvent event){
try {
showSingleFileChooser();
} catch (IOException ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
private void showSingleFileChooser() throws IOException {
//Stage s = new Stage();
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("ZEBRA file open...");
FileChooser.ExtensionFilter exfil = new FileChooser.ExtensionFilter("TXT files (*.txt)", "*.txt");
fileChooser.getExtensionFilters().add(exfil);
File selectedFile = fileChooser.showOpenDialog(stage);
if(selectedFile != null){
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("FXMLOpenedCode.fxml"));
AnchorPane frame = (AnchorPane) fxmlLoader.load();
FXMLOpenedCodeController c = fxmlLoader.getController();
//c.codeExecute = codeExecute;
c.codeExecute.appendText(readFile(selectedFile));
String mine;
mine = readFile(selectedFile);
//c.codeExecute.appendText(mine);
System.out.println(mine);
Parent root = FXMLLoader.load(getClass().getResource("FXMLOpenedCode.fxml"));
Scene scene = new Scene(root);
stage4.initModality(Modality.APPLICATION_MODAL);
stage4.setTitle("Compile Code");
stage4.setScene(scene);
stage4.show();
}
}
private void newWindow() throws IOException{
Parent root = FXMLLoader.load(getClass().getResource("FXMLNew.fxml"));
Scene scene = new Scene(root);
stage3.initModality(Modality.APPLICATION_MODAL);
stage3.setTitle("Enter code to run here");
stage3.setScene(scene);
stage3.show();
}
private String readFile(File selectedFile) throws FileNotFoundException, IOException {
StringBuilder content = new StringBuilder();
BufferedReader buffRead = null;
buffRead = new BufferedReader(new FileReader(selectedFile));
String text;
while((text = buffRead.readLine())!=null){
content.append(text);
}
return content.toString();
}
}
and in the FXMLOpenedCodeController there is a public TextArea codeExecute; I removed the #FXML and private so that the code works.

You are loading FXMLOpenedCode.fxml twice. You put the text in the text area you get from loading it the first time, but then you display the UI you get from loading it the second time. So, obviously, you don't see the text as it is set to the wrong text area.
Just load the FXML file once:
if(selectedFile != null){
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("FXMLOpenedCode.fxml"));
AnchorPane frame = (AnchorPane) fxmlLoader.load();
FXMLOpenedCodeController c = fxmlLoader.getController();
//c.codeExecute = codeExecute;
String mine;
mine = readFile(selectedFile);
c.codeExecute.appendText(mine);
System.out.println(mine);
Scene scene = new Scene(frame);
stage4.initModality(Modality.APPLICATION_MODAL);
stage4.setTitle("Compile Code");
stage4.setScene(scene);
stage4.show();
}

Related

how i can open different stage in one windows in javafx?

Dears Developers I have more stages but when I open any stage is showing as the following picture in down so please dear developers I need it in one window just how I can code it ?
this code for example for open stage
#FXML
public void btnsaveinvoice() throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("/FX/saveinvoice.fxml"));
Scene scene = new Scene(root);
Stage stage = new Stage();
stage.initStyle(StageStyle.UNDECORATED);
stage.setScene(scene);
stage.setTitle("saveInvoice");
stage.getIcons().add(new Image(getClass().getResourceAsStream("/image/restlogo.png")));
stage.show();
}
and this is for the salesinvoice open stage
#FXML
public void opensalesinvoice() {
try {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("/FX/salesinterface.fxml"));
Scene scene = new Scene(fxmlLoader.load());
Stage stage = new Stage();
stage.getIcons().add(new Image(getClass().getResourceAsStream("/image/restlogo.png")));
stage.setTitle("SalesInvoice");
stage.setScene(scene);
stage.show();
} catch (IOException e) {
Logger logger = Logger.getLogger(getClass().getName());
logger.log(Level.SEVERE, "Failed to create new Window.", e);
}
}
You need to set parent stage for the child stage like so
childStage.initOwner(parentStage);
EX.
#FXML
public void btnsaveinvoice() throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("/FX/saveinvoice.fxml"));
Scene scene = new Scene(root);
Stage stage = new Stage();
stage.initStyle(StageStyle.UNDECORATED);
stage.setScene(scene);
stage.setTitle("saveInvoice");
stage.iniOwner(primaryStage); // or whatever your primaryStage is
stage.getIcons().add(new Image(getClass().getResourceAsStream("/image/restlogo.png")));
stage.show();
}

Open Image From FileChooser On a Button

enter image description hereI need help I want to open a Image with a button of browse using filechooser on javafx ? how can I do it?
FileChooser f;
File file;
Image img;
ImageView mv;
#Override
public void start(Stage primaryStage)
{
f = new FileChooser();
Button browse = new Button("Browse");
browse.setOnAction((event) ->
{
file = f.showOpenDialog(primaryStage);
img = new Image(file.toURI().toString());
mv = new ImageView(img);
});
mv.setImage(img);
BorderPane root = new BorderPane();
root.setTop(browse);
root.setCenter(mv);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
The start method sets up the scene and shows the window. It completes before the button handler is run and the information you get during it's execution is not available at this time. You need to do modify the scene with the image from the event handler for this reason:
#Override
public void start(Stage primaryStage) {
final FileChooser f = new FileChooser();
final ImageView mv = new ImageView(); // create empty ImageView
Button browse = new Button("Browse");
browse.setOnAction((event) -> {
File file = f.showOpenDialog(primaryStage);
if (file != null) { // only proceed, if file was chosen
Image img = new Image(file.toURI().toString());
mv.setImage(img);
}
});
BorderPane root = new BorderPane();
root.setTop(browse);
root.setCenter(mv);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
Alternatively you could create the ImageView in the event handler and place it in the scene:
#Override
public void start(Stage primaryStage) {
final FileChooser f = new FileChooser();
Button browse = new Button("Browse");
final BorderPane root = new BorderPane();
browse.setOnAction((event) -> {
File file = f.showOpenDialog(primaryStage);
if (file != null) { // only proceed, if file was chosen
Image img = new Image(file.toURI().toString());
ImageView mv = new ImageView(img);
root.setCenter(mv); // add ImageView to scene
}
});
root.setTop(browse);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}

JavaFX - creating a new window on button clicked(using Scene Builder) [duplicate]

Looking at this code they show a way to display a new window after a login. When username and password are correct it opens new dialog. I want a button click to open new dialog, without checking for username and password.
If you just want a button to open up a new window, then something like this works:
btnOpenNewWindow.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
Parent root;
try {
root = FXMLLoader.load(getClass().getClassLoader().getResource("path/to/other/view.fxml"), resources);
Stage stage = new Stage();
stage.setTitle("My New Stage Title");
stage.setScene(new Scene(root, 450, 450));
stage.show();
// Hide this current window (if this is what you want)
((Node)(event.getSource())).getScene().getWindow().hide();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
I use the following method in my JavaFX applications.
newWindowButton.setOnMouseClicked((event) -> {
try {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("NewWindow.fxml"));
/*
* if "fx:controller" is not set in fxml
* fxmlLoader.setController(NewWindowController);
*/
Scene scene = new Scene(fxmlLoader.load(), 600, 400);
Stage stage = new Stage();
stage.setTitle("New Window");
stage.setScene(scene);
stage.show();
} catch (IOException e) {
Logger logger = Logger.getLogger(getClass().getName());
logger.log(Level.SEVERE, "Failed to create new Window.", e);
}
});
The code below worked for me I used part of the code above inside the button class.
public Button signupB;
public void handleButtonClick (){
try {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("sceneNotAvailable.fxml"));
/*
* if "fx:controller" is not set in fxml
* fxmlLoader.setController(NewWindowController);
*/
Scene scene = new Scene(fxmlLoader.load(), 630, 400);
Stage stage = new Stage();
stage.setTitle("New Window");
stage.setScene(scene);
stage.show();
} catch (IOException e) {
Logger logger = Logger.getLogger(getClass().getName());
logger.log(Level.SEVERE, "Failed to create new Window.", e);
}
}
}

binding progress bar with a method, javafx

I have a method which performs some task(reading, writing files and other tasks also) for almost 3 minutes.
I want to bind progress bar in javafx which can run with progress of the method.
This is my method
System.out.println("Going to load contract/security:"+new Date());
Map<Integer,FeedRefData> map = loadContractAndSecurityFromFile(loadFO);
addIndicesRefData(map);
BufferedWriter writer = createFile();
for (FeedRefData feedRefData : map.values()) {
try {
updateInstrumentAlias(map, feedRefData);
String refDataString = feedRefData.toString();
writer.write(refDataString, 0, refDataString.length());
writer.newLine();
writer.flush();
} catch (IOException e) {
e.printStackTrace();
log.info("Unable to write Quote Object to : " );
}
}
System.out.println("Ref Data File Generated:"+new Date());
For bind your method with progressbar you should do these steps :
Create a task which contains your method.
Create a thread which run this task.
Bind your progress property with your task property.
I made this simple example ,just change my code with your method code :
public class Bind extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
ProgressBar pb = new ProgressBar();
pb.setProgress(1.0);
Button button = new Button("start");
button.setOnAction((ActionEvent event) -> {
/*Create a task which contain method code*/
Task<Void> task = new Task<Void>() {
#Override
protected Void call() throws Exception {
File file = new File("C:\\Users\\Electron\\Desktop\\387303_254196324635587_907962025_n.jpg");
ByteArrayOutputStream bos = null;
try {
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[1024];
bos = new ByteArrayOutputStream();
for (int len; (len = fis.read(buffer)) != -1;) {
bos.write(buffer, 0, len);
updateProgress(len, file.length());
/* I sleeped operation because reading operation is quiqly*/
Thread.sleep(1000);
}
System.out.println("Reading is finished");
} catch (FileNotFoundException e) {
System.err.println(e.getMessage());
} catch (IOException e2) {
System.err.println(e2.getMessage());
}
return null;
}
};
Thread thread = new Thread(task);
thread.start();
/*bind the progress with task*/
pb.progressProperty()
.bind(task.progressProperty());
});
HBox box = new HBox(pb, button);
Stage stage = new Stage();
StackPane root = new StackPane();
root.getChildren().add(box);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
}
Operation started :
Operation finished :
PS: I used Thread.sleep(1000) because my file is so small.You can remove it if your progress time is long.

How to edit fxml from code?

So I have a BorderPane in my FXML, what I want to do is to reload my BorderPane.Center properties so it shows a different pane with different layout,
How can I achieve this? The codes below doesn't work for me.
p.s : sorry for indonesian.
My FXML :
<BorderPane fx:id="bPane" xmlns:fx="http://javafx.com/fxml" fx:controller="fx.HomeMhsController" stylesheets="#css.css">
<left>
<VBox spacing="10" fx:id="vbox" id="vbox" prefWidth="100" >
<Label id="Label" fx:id="biodata" text="Biodata" onMouseClicked="#showIdentity"/>
<Label id="Label" fx:id="histori" text="Histori Nilai" onMouseClicked="#showHistory" />
<Label id="Label" fx:id="jadwal" text="Jadwal Kuliah" onMouseClicked="#showSchedule" />
<Label id="Label" fx:id="pilih" text="Pilih Mata Kuliah" onMouseClicked="#chooseSchedule"/>
</VBox>
</left>
My Controller :
public class HomeMhsController{
#FXML private Label biodata2;
#FXML private BorderPane bPane;
#FXML private void showIdentity() throws SQLException{
init.initializeDB();
String query="select * from mahasiswa where nama_dpn ='" + MainController.username + "'";
ResultSet rset = init.stmt.executeQuery(query);
if(rset.next()){
String nim = rset.getString(1);
String nama_dpn = rset.getString(2);
String nama_blkg = rset.getString(3);
String tgl_lahir = rset.getString(4);
String tempat_lahir = rset.getString(5);
String jns_kelamin = rset.getString(6);
String agama = rset.getString(7);
String alamat = rset.getString(8);
String no_hp = rset.getString(9);
biodata2.setText(nim + nama_dpn + nama_blkg + tgl_lahir + tempat_lahir + jns_kelamin + agama + alamat + no_hp);
}
}
#FXML private void showHistory() throws IOException{
FXMLLoader loader = new FXMLLoader();
Parent rootNode = null;
rootNode = loader.load(getClass().getResource("homeMhs_fxml.fxml"));
Label dua = new Label("2");
Pane pane = new Pane();
pane.getChildren().add(dua);
((BorderPane) rootNode).setCenter(pane);
}
#FXML private void showSchedule() throws SQLException, IOException{
FXMLLoader loader = new FXMLLoader();
Parent rootNode = null;
rootNode = loader.load(getClass().getResource("homeMhs_fxml.fxml"));
Label tiga = new Label("3");
Pane pane = new Pane();
pane.getChildren().add(tiga);
((BorderPane) rootNode).setCenter(pane);
}
#FXML private void chooseSchedule() throws SQLException{
}
In the following code snippet:
#FXML private void showHistory() throws IOException{
FXMLLoader loader = new FXMLLoader();
Parent rootNode = null;
rootNode = loader.load(getClass().getResource("homeMhs_fxml.fxml"));
Label dua = new Label("2");
Pane pane = new Pane();
pane.getChildren().add(dua);
((BorderPane) rootNode).setCenter(pane);
}
you are loading the fxml file again, which is a new instance and different from the one you already have (since this method in its controller class). Moreover you are not doing anything with this newly loaded one (i.e. rootNode is not being added to any scene).
Instead just use the existing injected border pane:
#FXML private void showHistory() {
Label dua = new Label("2");
Pane pane = new Pane();
pane.getChildren().add(dua);
bPane.setCenter(pane);
}
or more shorter:
#FXML private void showHistory() {
bPane.setCenter(new Pane(new Label("2")));
}

Resources