0

I have made a simple JavaFx application, which reads/writes the txt file (the code is below). I have tested it on Windows platform (7 and higher). After I gave app my friend for test on Mac. But when we run it, it just does nothing. The GUI did not appear.

I tried run it through terminal (just "drag and drop" the icon to terminal, then enter in terminal. I don't know did I do right?) and terminal returned message "Permission denied". Can somebody explain what is require to run application, and what is not permitted exactly?

I found the similar question there but it does not have an answer...

Code:

import javafx.application.*;
import javafx.concurrent.Task;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.*;
import javafx.scene.control.Label;
import javafx.scene.control.SplitPane;
import javafx.scene.text.Font;
import javafx.stage.*;
import javafx.scene.layout.*;

import java.io.*;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

public class Main extends Application {

    static Properties props;
    static double fontSize;
    static String charsetName;
    static long mills;
    static String delimiter;
    static String pathToDictionary;
    static String pathErrLog;

    static {
        String pathFileProps = System.getProperty("user.dir") + "\\props.txt";
        props = new Properties();
        try {
            FileInputStream fis = new FileInputStream(pathFileProps);
            props.load(fis);
            fontSize = Double.parseDouble(props.getProperty("Font"));
            charsetName = props.getProperty("Charset");
            mills = Long.parseLong(props.getProperty("mills"));
            delimiter = props.getProperty("delimiter");
            pathToDictionary = props.getProperty("dict.path");
            fis.close();
        } catch (IOException e) {
            try {
                props.put("Font", "20");
                props.put("Charset", "UTF-8");
                props.put("mills", "1000");
                props.put("delimiter", "\t");
                props.put("dict.path", System.getProperty("user.dir") + "\\dict.txt");
                System.out.println("dictPath:" + System.getProperty("user.dir") + "\\dict.txt");
                System.setProperty("file.encoding", "UTF-8");
                FileOutputStream fos = new FileOutputStream(pathFileProps);
                props.store(fos
                        , "Props description:" + "\n" +
                                "Font" + "\t\t" + "size of font's words " + "\n" +
                                "Charset" + "\t" + "charset of file-dictionary" + "\n" +
                                "mills" + "\t\t" + "per animations in milliseconds" + "\n" +
                                "delimiter" + "\t" + "delimiter between a pair words in string: eng<->rus \"<->\" is delimiter there." + "\n" +
                                "dict.path" + "\t" + "path to file-dictionary. Use \"/\"-symbol in path. Ex: C:/temp/dict.txt" + "\n" +
                                "\t\t\t" + "Use only eng symbols to set path!" + "\n" +
                                "\tYou can change only values!\n");
                fos.close();
                System.exit(0);
            } catch (IOException e1) {
                errPrint(e1,"Ошибка создания файла: " + pathFileProps + "\n");

            }
        }

    }

    ArrayList<String> dictionary = new ArrayList<>();

    public static void errPrint(Exception exc, String note) {
        if (pathErrLog == null) {
            pathErrLog = System.getProperty("user.dir") + "\\errors.log";
        }
        try {
            PrintWriter outFile = new PrintWriter(new FileWriter(pathErrLog, true));
            outFile.println(note);
            exc.printStackTrace(outFile);
            outFile.close();
            System.exit(0);

        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    public static void main(String[] args) throws Exception {

        launch(args);
    }

    public void init() throws IOException {
        try {
            BufferedReader reader = new BufferedReader(new FileReader(pathToDictionary));
            int cnt = 0;
            while (reader.ready()) {
                String line = new String(reader.readLine().getBytes(), Charset.forName(charsetName));
                dictionary.add(line);
            }
        } catch (FileNotFoundException e) {
            errPrint(e,"Не найден файл " + pathToDictionary);
        } catch (IOException e) {
            errPrint(e,"Ошибка чтения файла " + pathToDictionary);
        }
    }

    public void start(Stage myStage) {

        myStage.setTitle("WordsLearner");
        SplitPane sp = new SplitPane();
        sp.setOrientation(Orientation.VERTICAL);
        Label labelUp = new Label();
        Label labelDw = new Label();

        labelUp.setFont(new Font(fontSize));
        labelDw.setFont(new Font(fontSize));

        Scene scene = new Scene(sp, 600, 200);
        myStage.setScene(scene);

        final StackPane sp1 = new StackPane();
        sp1.getChildren().add(labelUp);
        sp1.setAlignment(Pos.BOTTOM_CENTER);
        final StackPane sp2 = new StackPane();
        sp2.getChildren().add(labelDw);
        sp2.setAlignment(Pos.TOP_CENTER);

        final boolean[] flag = {true};
        sp.setOnMouseClicked(event -> {
            Task<Void> task = new Task<Void>() {
                @Override
                public Void call() throws Exception {
                    if (flag[0]) {
                        flag[0] = false;
                        final String[] str = new String[1];
                        final String[] eng = new String[1];
                        final String[] rus = new String[1];
                        while (true) {
                            Platform.runLater(() -> {
                                try {
                                    str[0] = dictionary.get(ThreadLocalRandom.current().nextInt(0, dictionary.size()));
                                    eng[0] = str[0].split(delimiter)[0];
                                    rus[0] = str[0].split(delimiter)[1];
                                    labelUp.setText(eng[0]);
                                    labelDw.setText(rus[0]);
                                } catch (Exception e) {
                                    System.exit(-1);
                                }
                            });
                            Thread.sleep(mills);
                        }
                    }
                    return null;
                }
            };
            new Thread(task).start();

        });

        sp.getItems().addAll(sp1, sp2);
        sp.setDividerPositions(0.5f, 0.5f);

        myStage.show();
    }

    public void stop() {
        System.exit(0);
    }
}
Jason Aller
  • 3,541
  • 28
  • 38
  • 38
  • You're hardcoding file paths in windows format (`System.getProperty("user.dir")+"\\dict.txt"`, etc.) You can't really expect that to work on a Mac. Use the `java.nio.file` API (specifically `Files` and `Path`) to access the file system in a platform independent way. Also note that you don't initialize `fontSize`, `charsetName`, etc etc if you can't load the properties file. – James_D Sep 18 '17 at 14:34
  • I am pretty sure that the System.getProperty("user.dir") is working on linux which returns the /home/username/ directory. Are you sure that is not working on Mac? hmmm i didn't knew that. – JKostikiadis Sep 18 '17 at 14:40
  • 1
    To execute a jar file (technically, execute the Java Virtual Machine and pass it a runnable jar file) from the terminal on a Mac, use `java -jar MyJarFile.jar`. – James_D Sep 18 '17 at 14:40
  • 1
    @JKostikiadis The system property works, but hardcoding a backslash as the separator is pretty obviously not going to work. – James_D Sep 18 '17 at 14:41
  • works perfect for me – Towfik Alrazihi Sep 18 '17 at 14:42
  • @James_D can you explain why? Even if the getProperty return a path like /home/name/ adding an additional '/' at the end is not going to cause any problem, at least i haven't face something like that before. – JKostikiadis Sep 18 '17 at 14:47
  • @James_D, should i change directory on where my .jar store in terminal before run it java -jar MyJarFile.jar ? – Дмитрий Sep 18 '17 at 14:48
  • @JKostikiadis Are you not reading the code or the comments? He is using a *backslash*, not a forward slash. That only works on windows, because DOS uses a *backslash* (again **not a forward slash**) as the delimiter between folders and subfolders/files. – James_D Sep 18 '17 at 14:48
  • @Дмитрий Yes, or just pass the complete path. – James_D Sep 18 '17 at 14:49
  • @James_D oh now i see my mistake i knew that forward and backslash has the same result cause i mostly work on windows and i assumed it will have the same effect on Linux too, that's why i didn't gave so much attention on the 'backslash'. Thanks for pointing that out. – JKostikiadis Sep 18 '17 at 14:52
  • @James_D, can you recommend me some universal and safety way to make files independ from system? i have not the Mac, and i can not check it. In windows i wanted to use forward slash, but it did not work. – Дмитрий Sep 18 '17 at 14:56
  • As in my first comment, use `java.nio.file.Path`, `java.nio.file.Paths`, and `java.nio.file.Files`. E.g. `Path propPath = Paths.get(System.getProperty("user.dir"), "props.txt");`, `InputStream is = Files.newInputStream(propPath);`, etc. – James_D Sep 18 '17 at 15:00
  • oh, sorry, i have missed it. @James_D, one more question pls. How to do .jar in Mac as runnable file by double click (like in Windows platform)? – Дмитрий Sep 18 '17 at 15:02
  • It should work the same way. The reason you're not seeing anything is because your code is throwing exceptions (probably null pointer exceptions as you don't initialize those static variables). – James_D Sep 18 '17 at 15:03

0 Answers0