I have a TilePane with a imageView items, each imageview displaying an image got from a directory in my pc. When any of the images in the tilePane is clicked a message is printed onto console with the direcory path address to the folder where the image resides, for example:
You clicked: ImageResources/wp.png
I would like to extend this further so that when a particular image is clicked the folder in which the image resides opens.
My implementation below only prints to console the message below, but no directory/ folder gets opened. The message is:
File Not Found
How can I get it to work so that the folder|directory opens? Thank you all in advance.
Also, of the directory could open with the clicked image selected, then that would be an extra, but is not a priority right now.
My implementation so far goes as follows:
public class TilePaneExample extends Application {
#Override
public void start(Stage primaryStage) {
VBox root = new VBox(30);
String[] imageResources = new String[]{
//loading images
"ImageResources/facebook.png",
"ImageResources/faviicon.png",
"ImageResources/jquery-logo.png",
"ImageResources/linkedin_32.png",
"ImageResources/loading1.png",
"ImageResources/twitter.png",
"ImageResources/twitter_32.png",
"ImageResources/wp.png",};
// Pane
TilePane tilePane = new TilePane();
tilePane.setHgap(5);
tilePane.setVgap(5);
for (final String imageResource : imageResources) {
Image image = new Image(getClass().getResourceAsStream(imageResource));
ImageView imageView = new ImageView(image);
imageView.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
File f = new File(imageResource);
String absolutePath = f.getAbsolutePath();
String folderPath = absolutePath.
substring(0, absolutePath.lastIndexOf(File.separator));
try {
Desktop.getDesktop().open(new File(folderPath));
} catch (IllegalArgumentException iae) {
System.out.println("File Not Found");
} catch (IOException ex) {
Logger.getLogger(TilePaneExample.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
tilePane.getChildren().add(imageView);
}
root.getChildren().addAll(tilePane);
primaryStage.setTitle("TilePane Example");
Scene scene = new Scene(root, 300, 150);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
For example, clicking the second image, "ImageResources/faviicon.png", prints its folder path as D:\standAloneDev\java\workingDir\Jive\TilePaneExample\ImageResources
Related
My goal is to display images that are selected from a filechooser activated by button, and add those images to my gridpane. I am able to get the right URL file path name from the file chooser in order to make a correct imageview however when doing so my gridpane does not show any images being added..
public void makeBrowseButton(Stage primaryStage) {
//attach handler
browseButton.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent event) {
FileChooser fileChooser = new FileChooser(); // create object
fileChooser.getExtensionFilters()
.addAll(new FileChooser.ExtensionFilter("Image Files", "*.png", "*.jpg", "*.gif")); //filter for music files
//FileFilter filter = new FileNameExtensionFilter("JPEG file", "jpg", "jpeg");
if (!parentPath.equalsIgnoreCase(
"")) { //go to previous directory if exists
File parentPathFile = new File(parentPath);
fileChooser.setInitialDirectory(parentPathFile);
}
File selectedFile = fileChooser.showOpenDialog(primaryStage);
if (selectedFile != null) { // display the dialog box
String wholePath = selectedFile.getPath();
String name = selectedFile.getName();
String megaPath = selectedFile.getAbsolutePath();
String megaUrl;
try {
megaUrl = Paths.get(megaPath).toUri().toURL().toString();
} catch (MalformedURLException e) {
throw new IllegalArgumentException(e);
}
parentPath = selectedFile.getParent();
System.out.println("wholePath: " + wholePath);
System.out.println("parent: " + parentPath);
System.out.println("File Name: " + name);
System.out.println("megaPath: " + megaUrl);
//System.out.println("Canonical: " + Canonical);
Image newAwesomeImage = new Image(megaUrl);
paneofgridmonkeys.add(new ImageView(newAwesomeImage), 0, 0);
//ImageView view = new ImageView();
//view.setImage(newAwesomeImage);
//paneofgridmonkeys.add(view, 1, 1);
//paneofgridmonkeys.setConstraints(view, 0, 4);
//paneofgridmonkeys.add(new Label("Changed the image!"), 0, 1);
createDisplay(primaryStage);
}
}
});
}
I've tried multiple ways of insterting an images and these are the filepaths im getting:
wholePath: \\jupiter\yr1005\Desktop\20190111_1340501.jpg
parent: \\jupiter\yr1005\Desktop
File Name: 20190111_1340501.jpg
megaPath: file://jupiter/yr1005/Desktop/20190111_1340501.jpg
(im using the megapath)
basically when i choose an image from filechooser I get no error but no image is shown after selection. I just get all the print statements in return.. an idea why?
This is my create Display method:
public void createDisplay(Stage primaryStage) {
primaryStage.setTitle(this.MONKEY_TITLE);
GridPane paneofgridmonkeys = new GridPane();
paneofgridmonkeys.setAlignment(Pos.CENTER);
paneofgridmonkeys.setVgap(10);
paneofgridmonkeys.add(browseButton, 10, 10);
ScrollPane allTehFaces = new ScrollPane(paneofgridmonkeys);
allTehFaces.setFitToWidth(true);
primaryStage.setScene(new Scene(allTehFaces, 500, 500));primaryStage.show();
}
}
You're problem is in the createDisplay method; specifically this line:
GridPane paneofgridmonkeys = new GridPane();
Here you're creating a locally-scoped GridPane called paneofgridmonkeys, which must be the name of another class-level variable called paneofgridmonkeys, since it's available to makeBrowseButton. When you do this in local scope, the new instance you've created becomes the one that's used inside of that method, rather than the class-level instance; thus the class-level one isn't the one being added to your scene, and you're not seeing the changes.
I'm trying to create a text editor using JavaFX. I want to be able to open a file from a window into the main window as a tab. So far, I've created the necessary menu items and an option window that contains the function to open the file explorer to select a file.
When the user presses the "Choose File" button, the file explorer is opened. When a user selects a file, the "Open File" window closes. The main window (3rd image) is then left but does not contain a tab with the file contents.
Upon execution of the "openFile()" function, no errors are returned, but no tab is opened. I believe it may be an issue with trying to open the tab within the "chooseFileButton.SetOnAction()" function but cannot confirm.
Any suggestions/explanations would be much appreciated.
Open File
Open File (FileChooser)
Output:
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primary) throws Exception {
primary.setTitle("Chris' Text Editor");
MenuBar menuBar = new MenuBar();
VBox vbox = new VBox(menuBar);
/* FILE MENU */
MenuItem openFile = new MenuItem("Open...");
fileMenu.getItems().add(openFile);
Pane rootPane = new Pane();
TextArea editorTextArea = new TextArea();
editorTextArea.setMinHeight(1000);
editorTextArea.setMinWidth(1000);
editorTextArea.setVisible(false);
rootPane.getChildren().add(editorTextArea);
TabPane tabPane = new TabPane();
tabPane.setSide(Side.TOP);
openFile.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Label fileLabel = new Label();
fileLabel.setText("No File selected...");
GridPane grid = new GridPane();
Scene contextScene = new Scene(grid, 450, 300);
/* NEW WINDOW */
Stage openFileWindow = new Stage();
openFileWindow.setTitle("Open File");
openFileWindow.setScene(contextScene);
/* SET WINDOW MODAL */
openFileWindow.initModality(Modality.WINDOW_MODAL);
/* SET PARENT WINDOW */
openFileWindow.initOwner(primary);
/* CHOOSE FILE DIRECTORY BUTTON */
openFileWindow.setX(primary.getX() + (primary.getX() / 2));
openFileWindow.setY(primary.getX() + (primary.getX() / 2));
openFileWindow.show();
/* CHOOSE FILE BUTTON */
Button chooseFileButton = new Button();
chooseFileButton.setText("Choose File");
chooseFileButton.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
FileChooser chooseFile = new FileChooser();
File selectedFile = chooseFile.showOpenDialog(openFileWindow);
if(selectedFile != null) {
String filePath = selectedFile.getPath();
fileLabel.setText(filePath);
String fileContent = openFile2(filePath);
/* CREATE NEW TAB */
Tab newTab = new Tab();
newTab.setContent(editorTextArea);
newTab.setText(filePath);
tabPane.getTabs().add(newTab);
editorTextArea.setVisible(true);
/* POPULATE TEXT AREA WITH FILE CONTENTS */
editorTextArea.appendText(fileContent);
/* FOCUS ON TAB */
SingleSelectionModel<Tab> selection = tabPane.getSelectionModel();
selection.select(newTab);
openFileWindow.close();
}
}
});
grid.setAlignment(Pos.CENTER);
grid.setHgap(10);
grid.setVgap(10);
grid.add(chooseFileButton, 0, 0);
grid.add(fileLabel, 0, 1);
}
});
menuBar.getMenus().add(fileMenu);
Scene scene = new Scene(vbox, 1000, 750);
primary.setScene(scene);
primary.show();
}
public String openFile2(String filePath) {
StringBuilder content = new StringBuilder();
try (Stream<String> stream = Files.lines(Paths.get(filePath), StandardCharsets.UTF_8)){
stream.forEach(s -> content.append(s).append("\n"));
} catch (IOException e) {
e.printStackTrace();
}
return content.toString();
}
You never added your TabPane to the scene:
vbox.getChildren().add(tabPane);
I'm trying to edit five images I have in a folder at once (using javafx motion blur), rather than select them one after the other. This is my code, I'm not exactly sure what I'm doing wrong but when I run it, only the last image in the folder gets edited. The others remain as they are.
public class IterateThrough extends Application {
private Desktop desktop = Desktop.getDesktop();
#Override
public void start(Stage primaryStage) throws IOException {
File dir = new File("filepath");
File [] directoryListing = dir.listFiles();
if (directoryListing != null) {
for (File file : directoryListing) {
if(file.getName().toLowerCase().endsWith(".jpeg")){
//desktop.open(file);
Image image = new Image(new FileInputStream(file));
//Setting the image view
ImageView imageView = new ImageView(image);
//setting the fit height and width of the image view
imageView.setFitHeight(600);
imageView.setFitWidth(500);
//Setting the preserve ratio of the image view
imageView.setPreserveRatio(true);
// instantiate Motion Blur class
MotionBlur motionBlur = new MotionBlur();
// set blur radius and blur angle
motionBlur.setRadius(15.0);
motionBlur.setAngle(110.0);
//set imageView effect
imageView.setEffect(motionBlur);
//Creating a Group object
Group root = new Group(imageView);
//Creating a scene object
Scene scene = new Scene(root, 600, 500);
//Setting title to the Stage
primaryStage.setTitle("Loading an image");
//Adding scene to the stage
primaryStage.setScene(scene);
//Displaying the contents of the stage
primaryStage.show();
}
}
}
}
public static void main(String[] args) {
launch(args);
}
}
first, you shouldn't just let the primaryStage show() in the for-each loop, because when the primaryStage first show(), the fx thread pause on that instruction, the remaining pictures will not be read and when you close the window, the loop won't continue to go on for remaining, it represents the end of the application.
so it's better to let the primaryStage show() outside the each-loop after all image has been read.
second, you shouldn't use the "Group" container to contains all images, better use VBox/HBox/FlowPane, make sure above image won't covers below's.
here's modified code for reference.
public class IterateThrough2 extends Application{
private Desktop desktop = Desktop.getDesktop();
#Override
public void start(Stage primaryStage) throws IOException{
File dir = new File("filepath");
File[] directoryListing = dir.listFiles();
FlowPane root = new FlowPane();
if(directoryListing != null){
for(File file : directoryListing){
if(file.getName().toLowerCase().endsWith(".jpeg")){
Image image = new Image(new FileInputStream(file));
ImageView imageView = new ImageView(image);
imageView.setFitHeight(600);
imageView.setFitWidth(500);
imageView.setPreserveRatio(true);
MotionBlur motionBlur = new MotionBlur();
motionBlur.setRadius(15.0);
motionBlur.setAngle(110.0);
imageView.setEffect(motionBlur);
root.getChildren().add(imageView);
}
}
}
Scene scene = new Scene(root, 600, 500);
primaryStage.setTitle("Loading an image");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args){
launch(args);
}
}
I have a reset and Draw button on a slide panel. I choose a desired file from file chooser, which is in RootLayout class, and pass the file path to a controller class. Then it does some processes and initializes field in DataCunstructor class. By clicking on Draw a TreeTableView will be shown on slide pane, which is in MainController class. When I click my reset button the table will be cleared but I do not know how to reset the chosen path. After reseting if I click Draw again the same treetable comes up. and If I choose another file and hit Draw, the program breaks.
How can I reset all fields including the path to null, and be able to choose another file and process that one?
Here is my Draw and Reset in MainController class:
public void treeTableDraw(ActionEvent event) {
drawTable();//creates the TreeTableView
numberOfFunctions= dc.getFuncAll().size();
numberOfOrganizations = dc.getSortedAssignedOrg().size();
funcLabel.setText(numberOfFunctions+"");//set Lable value
orgLabel.setText(numberOfOrganizations + "");//set Lable value
}
public void treeTableReset(ActionEvent event){
funcLabel.setText("0");//reset Label
orgLabel.setText("0");
treeTable.getColumns().clear(); //clears columns (TreeTable)
///////////////////////////////////////
//non of the following did the path reset//
///////////////////////////////////////
//dc = new DataConstructor();
//Controller controller = new Controller();
//controller.setPath(null);
RootLayoutController rlc = loader.getController();
rlc.reset();
}
My File Chooser in RootLayout class:
#FXML
private void handleOpen() {
FileChooser fileChooser = new FileChooser();
// Set extension filter
FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter(
"3lgm2 files (*.z3lgm)", "*z3lgm");
fileChooser.getExtensionFilters().add(extFilter);
// Show save file dialog
File file = fileChooser.showOpenDialog(main.getPrimaryStage());
path = file.toString();
if (path != null) {
new Controller(path);
}
}
public void reset(){
path = null;
}
I add OverView at the center of rootlayout here at main class:
public class Main extends Application {
private Stage primaryStage;
private BorderPane rootLayout;
//private ObservableList<DataConstructor> treeTableData = FXCollections.observableArrayList();
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("IT-Saturation");
initRootLayout();
showOverView();
}
private void showOverView() {
try{
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("/view/OverView.fxml"));
AnchorPane overView = (AnchorPane) loader.load();
rootLayout.setCenter(overView);
}catch(IOException e){
e.printStackTrace();
}
}
private void initRootLayout() {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("/view/RootLayout.fxml"));
rootLayout = (BorderPane) loader.load();
//show scene containing the root layout
Scene scene = new Scene(rootLayout);
scene.getStylesheets().add(
getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
//gives controller access to main app
RootLayoutController controller = loader.getController();
controller.setMainApp(this);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
File file = getFilePath();
if (file != null) {
loadDataFromFile(file);
}
}
/**
* Returns the main stage.
* #return primaryStage
*/
public Stage getPrimaryStage() {
return primaryStage;
}
public static void main(String[] args) {
launch(args);
}
}
Just declare a reset() in your RootLayout class:
public class RootLayout {
private Path path;
#FXML
private void handleOpen() {
...
path = file.toString();
}
public void reset() {
path= null;
}
}
Never construct the constructor using the keyword new, always get it from the FXMLLoader.
public class MainController {
...
RootLayoutController controller = loader.getController();
controller.reset();
...
}
I have 2 controller for 2 fxml files. In one controller I have a handleOpen function which opens a file chooser and gives the path to a Class which I have called model. Then on the other controller a function, treeTableDraw gets this path, after clicking on Draw Button and runs the program. I have Another Button to reset the program. It sets the result back to null, but when open another file to run, the program crashes, because the path is null. How can I reset the program and make it use the new path which is selected from open file chooser?
//Gets the path from model and runs the program
public void treeTableDraw(ActionEvent event) {
new Controller(model.getText());
drawTable();
numberOfFunctions = dc.getFuncAll().size();
numberOfOrganizations = dc.getSortedAssignedOrg().size();
funcLabel.setText(numberOfFunctions + "");
orgLabel.setText(numberOfOrganizations + "");
btnDraw.setDisable(true);
}
/**
* Clrears TreeTableView and sets back labels
*
* #param event
*/
public void treeTableReset(ActionEvent event) {
btnDraw.setDisable(false);
model.setText(null);
funcLabel.setText("0");
orgLabel.setText("0");
treeTable.getColumns().clear();
}
This is RootLayout class which has open file function:
#FXML
private void handleOpen() {
FileChooser fileChooser = new FileChooser();
// Set extension filter
FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter(
"3lgm2 files (*.z3lgm)", "*z3lgm");
fileChooser.getExtensionFilters().add(extFilter);
// Show open file dialog
File file = fileChooser.showOpenDialog(main.getPrimaryStage());
if (file != null) {
path = file.toString();
model.setText(path);
}
}
Here is the model class
public class Model {
private final StringProperty text = new SimpleStringProperty();
public StringProperty textProperty() {
return text;
}
public final String getText() {
return textProperty().get();
}
public final void setText(String text) {
textProperty().set(text);
}
}
This is the main, where I combine two fxmls and set stage:
public class Main extends Application {
private Stage primaryStage;
private BorderPane rootLayout;
private Model model = new Model();
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("IT-Saturation");
initRootLayout();
showOverView();
}
private void showOverView() {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("/view/OverView.fxml"));
loader.setController(new OverViewController(model));
AnchorPane overView = (AnchorPane) loader.load();
rootLayout.setCenter(overView);
} catch (IOException e) {
e.printStackTrace();
}
}
private void initRootLayout() {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("/view/RootLayout.fxml"));
loader.setController(new RootLayoutController(model));
rootLayout = (BorderPane) loader.load();
// show scene containing the root layout
Scene scene = new Scene(rootLayout);
scene.getStylesheets().add(
getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
// gives controller access to main
RootLayoutController controller = loader.getController();
controller.setMainApp(this);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Returns the main stage.
*
* #return primaryStage
*/
public Stage getPrimaryStage() {
return primaryStage;
}
public static void main(String[] args) {
launch(args);
}
public void showMostComputerizedStatistics() {
try {
// Load the fxml file and create a new stage for the popup.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class
.getResource("view/BirthdayStatistics.fxml"));
AnchorPane page = (AnchorPane) loader.load();
Stage dialogStage = new Stage();
dialogStage.setTitle("Birthday Statistics");
dialogStage.initModality(Modality.WINDOW_MODAL);
dialogStage.initOwner(primaryStage);
Scene scene = new Scene(page);
dialogStage.setScene(scene);
// Set the persons into the controller.
MostComputerizedController controller = loader.getController();
dialogStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The problem was not the path. I had to reset the data which got initialized at the the former run of program. So after setting path to null I just newed the instance of class which had reference to data.
...
public void treeTableReset(ActionEvent event) {
btnDraw.setDisable(false);
//model.setText(null);
funcLabel.setText("0");
orgLabel.setText("0");
treeTable.getColumns().clear();
dc = new DataConstructor();
}