1
\$\begingroup\$

This is a bot for Twitter where you can upload an excel file with text in as many rows as you want but in a single column and it posts every row as a tweet every certain time. It stores the credentials in another Excel file, I know this very insecure but I couldnt find a better way to do it, if anyone has a suggestion I would appreciate it.

The app needs this external libraries:

  • Apache Poi
  • Twitter4J
  • Guava

enter image description here

TwitterBot.java

    public class TwitterBot extends Application {

    Stage stage;
    SignIn SignIn = new SignIn();
    static GUI gui = new GUI();
    static Scene scene = new Scene(gui.border, 862, 449);
    ReadAccountsExcelFile readAccountsExcelFile = new ReadAccountsExcelFile();

    @Override
    public void start(Stage primaryStage) {
        stage = primaryStage;
        gui.setTop();
        gui.setCenter();
        if (readAccountsExcelFile.fileExists()) {
            gui.drawAccountsInGrid();
        }
        gui.setLeft();
        readAccountsExcelFile.readAccountsExcel();
        primaryStage.setTitle("TwitterBot 1.0 (ArteMe Radio)");
        scene.getStylesheets().add("file:tabpane.css");
        primaryStage.getIcons().add(new Image("file:img/icon.png"));
        primaryStage.setScene(scene);
        primaryStage.show();
        primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
            @Override
            public void handle(WindowEvent t) {
                Platform.exit();
                System.exit(0);
            }
        });
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
}

ReadAccountsExcelFile.java

    public class ReadAccountsExcelFile {

    Map<String, String> tokensMap = Maps.newHashMap();
    Map<String, String> secretTokensMap = Maps.newHashMap();
    ArrayList<String> usersArray = new ArrayList<>();

    public void readAccountsExcel() {
        try {
            File myFile = new File("usr_data/Accounts.xlsx");
            FileInputStream fileInputStream = new FileInputStream(myFile);
            XSSFWorkbook workbook = new XSSFWorkbook(fileInputStream);
            XSSFSheet worksheet = workbook.getSheet("Accounts");
            int numOfRows = worksheet.getLastRowNum() + 1;
            for (int x = 0; x < numOfRows; x++) {
                Row row = worksheet.getRow(x);
                Cell userCell = row.getCell(0);
                Cell tokenCell = row.getCell(1);
                Cell secretTokenCell = row.getCell(2);
                String user = userCell.getStringCellValue();
                String token = tokenCell.getStringCellValue();
                String secretToken = secretTokenCell.getStringCellValue();
                tokensMap.put(user, token);
                secretTokensMap.put(user, secretToken);
                usersArray.add(user);
            }
        } catch (FileNotFoundException te) {
            te.printStackTrace();
            System.out.println("Accounts.xlsx Not Found");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void editAccountsExcel(String user, String token, String secretToken) {
        if (fileExists()) {
            //Read Excel document 
            try {
                FileInputStream input_document = new FileInputStream(new File("usr_data/Accounts.xlsx"));
                // convert it into a POI object
                XSSFWorkbook my_xlsx_workbook = new XSSFWorkbook(input_document);
                // Read excel sheet that needs to be updated
                XSSFSheet my_worksheet = my_xlsx_workbook.getSheet("Accounts");
                //Get number of rows
                int numOfRows = my_worksheet.getLastRowNum() + 1;
                // declare a Cell object of both cells and set values
                Cell userCell = null;
                Cell tokenCell = null;
                Cell secretTokenCell = null;
                Row row = my_worksheet.createRow(numOfRows);
                userCell = row.createCell(0);
                userCell.setCellValue(user);
                tokenCell = row.createCell(1);
                tokenCell.setCellValue(token);
                secretTokenCell = row.createCell(2);
                secretTokenCell.setCellValue(secretToken);
                //important to close InputStream
                input_document.close();
                //Open FileOutputStream to write updates
                FileOutputStream output_file = new FileOutputStream(new File("usr_data/Accounts.xlsx"));
                //write changes
                my_xlsx_workbook.write(output_file);
                //close the stream
                output_file.close();
            } catch (FileNotFoundException te) {
                te.printStackTrace();
                System.out.println("Accounts.xlsx Not Found");
            } catch (IOException e) {
                e.printStackTrace();
            }
        } //create Excel Document
        else {
            XSSFWorkbook wb = new XSSFWorkbook();
            //Workbook wb = new XSSFWorkbook();
            Sheet sheet = wb.createSheet("Accounts");

            // Create a row and put some cells in it. Rows are 0 based.
            Row row = sheet.createRow((short) 0);
            // Create a cell and put a value in it.
            Cell userCell = row.createCell(0);
            Cell tokenCell = row.createCell(1);
            Cell secretTokenCell = row.createCell(2);
            userCell.setCellValue(user);
            tokenCell.setCellValue(token);
            secretTokenCell.setCellValue(secretToken);
            try (FileOutputStream outputStream = new FileOutputStream("usr_data/Accounts.xlsx")) {
                wb.write(outputStream);
                wb.close();
            } catch (FileNotFoundException te) {
                te.printStackTrace();
                System.out.println("Accounts.xlsx Not Found");
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        tokensMap.put(user, token);
        secretTokensMap.put(user, secretToken);
        usersArray.add(user);
    }

    public boolean fileExists() {
        boolean flag = false;
        File f = new File("usr_data/Accounts.xlsx");
        if (f.exists()) {
            flag = true;
        }
        return flag;
    }

    public User getUser(String token, String secretToken) {
        User twitterUser = null;
        ConfigurationBuilder cb = new ConfigurationBuilder();
        //the following is set without accesstoken- desktop client
        cb.setOAuthConsumerKey("KEY");
        cb.setOAuthConsumerSecret("SECRET");
        cb.setOAuthAccessToken(token);
        cb.setOAuthAccessTokenSecret(secretToken);
        ArrayList<User> users = new ArrayList<>();
        try {

            TwitterFactory tf = new TwitterFactory(cb.build());
            Twitter twitter = tf.getInstance();
            twitterUser = twitter.showUser(twitter.getId());
            users.add(twitterUser);
        } catch (TwitterException te) {
            te.printStackTrace();
            System.out.println("Failed to get timeline: " + te.getMessage());

        }
        return twitterUser;
    }
}

SetTweet.java

    public class SetTweet {

    private SignIn SignIn;

    public void setTweet(String userName, String tweetContent) {
        ReadAccountsExcelFile readAccountsExcelFile = new ReadAccountsExcelFile();
        readAccountsExcelFile.readAccountsExcel();

        ConfigurationBuilder cb = new ConfigurationBuilder();
        //the following is set without accesstoken- desktop client
        try {
            cb.setDebugEnabled(true);
            cb.setOAuthConsumerKey("KEY");
            cb.setOAuthConsumerSecret("SECRET");
            cb.setOAuthAccessToken(readAccountsExcelFile.tokensMap.get(userName));
            cb.setOAuthAccessTokenSecret(readAccountsExcelFile.secretTokensMap.get(userName));
            TwitterFactory tf = new TwitterFactory(cb.build());
            Twitter twitter = tf.getInstance();
            Status status = twitter.updateStatus(tweetContent + " /" + randomCharacter() + "/");

            System.out.println("Successfully updated the status to [" + status.getText() + "].");

        } catch (TwitterException te) {
            te.printStackTrace();
            System.out.println("Failed to get timeline: " + te.getMessage());

        }

    }

    public String randomCharacter() {
        String random = UUID.randomUUID().toString();
        String[] parts = random.split("-");
        String part2 = parts[1];
        String s1a = part2.substring(0, (part2.length() / 2));
        return s1a;
    }

    public void setTimer(Timer timer, int seconds, String userName, String content, VBox tabContent, ArrayList<Integer> countTweetsArray, Label statusLabel) {
        TabContent tabContentObj = new TabContent();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                setTweet(userName, content);
                System.out.println(content + "  after  " + seconds);
                System.out.println("countTweetsArray: " + countTweetsArray.get(0));
                statusLabel.setText(countTweetsArray.get(0).toString());
                countTweetsArray.set(0, (countTweetsArray.get(0) + 1));
                tabContentObj.timersMap.put(userName, timer);
            }
        }, (seconds * 1000));
    }

    public void setTimerTask(VBox tabContent, ArrayList<Integer> countTweetsArray, int remainingTweets, Text postedTweetsText, User user, Timer timer, Timeline timeline, String secondsOrMinutesString) {
        TabContent tabContentObj = new TabContent();
        tabContent.getChildren().clear();
        tabContent.getChildren().add(tabContentObj.createStatusScreen(countTweetsArray, remainingTweets, postedTweetsText, user, tabContent, timer, timeline, secondsOrMinutesString));
        if (countTweetsArray.get(0) == remainingTweets) {
            tabContent.getChildren().clear();
            Label spacer = new Label("\n\n\n\n");
            tabContent.getChildren().addAll(tabContentObj.createFileChooser(), tabContentObj.createTimerChooser(), spacer, tabContentObj.createStartButton(user, tabContent));
        }
    }

    public void setFXTimer(int seconds, int remainingTweets, VBox tabContent, ArrayList<Integer> countTweetsArray, Text postedTweetsText, User user, Timer timer, Timeline timeline, String secondsOrMinutesString) {
        timeline.getKeyFrames().add(
                new KeyFrame(Duration.millis(seconds * 1000), e -> {
                    setTimerTask(tabContent, countTweetsArray, remainingTweets, postedTweetsText, user, timer, timeline, secondsOrMinutesString);
                })
        );
        timeline.setCycleCount(remainingTweets - 1);
        timeline.play();
    }
}

SignIn.java

public class SignIn {

    SetTweet setTweet = new SetTweet();
    ReadAccountsExcelFile raef;

    public void signIn() {
        GUI gui = new GUI();
        ConfigurationBuilder cb = new ConfigurationBuilder();

        //the following is set without accesstoken- desktop client
        cb.setDebugEnabled(true);
        cb.setOAuthConsumerKey("KEY");
            cb.setOAuthConsumerSecret("SECRET");

        try {
            TwitterFactory tf = new TwitterFactory(cb.build());
            Twitter twitter = tf.getInstance();

            try {
                System.out.println("-----");

                // get request token.
                // this will throw IllegalStateException if access token is already available
                // this is oob, desktop client version
                RequestToken requestToken = twitter.getOAuthRequestToken();

                System.out.println("Got request token.");
                System.out.println("Request token: " + requestToken.getToken());
                System.out.println("Request token secret: " + requestToken.getTokenSecret());

                System.out.println("|-----");

                AccessToken accessToken = null;
                pinDialog(accessToken, requestToken, twitter);
            } catch (IllegalStateException ie) {
                // access token is already available, or consumer key/secret is not set.
                if (!twitter.getAuthorization().isEnabled()) {
                    System.out.println("OAuth consumer key/secret is not set.");
                }
            }

        } catch (TwitterException te) {
            te.printStackTrace();
            System.out.println("Failed to get timeline: " + te.getMessage());
        }
    }

    public void pinDialog(AccessToken accessToken, RequestToken requestToken, Twitter twitter) {
        ReadAccountsExcelFile readAccountsExcelFile = new ReadAccountsExcelFile();
        TextInputDialog dialog = new TextInputDialog();
        dialog.setTitle("Twitter Sign In");
        dialog.setHeaderText("Otorga acceso a tu cuenta");
        dialog.setContentText("Escribe el PIN:");

        try {
            Desktop.getDesktop().browse(new URI(requestToken.getAuthorizationURL()));
        } catch (URISyntaxException e) {
        } catch (IOException e) {
        }

        Optional<String> result = dialog.showAndWait();
        try {
            accessToken = twitter.getOAuthAccessToken(requestToken, result.get());
            System.out.println("Got access token.");
            System.out.println("Access token: " + accessToken.getToken());
            System.out.println("Access token secret: " + accessToken.getTokenSecret());

            User user = twitter.showUser(twitter.getId());
            readAccountsExcelFile.editAccountsExcel(user.getScreenName(), accessToken.getToken(), accessToken.getTokenSecret());

        } catch (TwitterException te) {
            if (401 == te.getStatusCode()) {
                System.out.println("Unable to get the access token.");
            } else {
                te.printStackTrace();
            }
        }
    }

}

TabContent.java

public class TabContent {

    SetTweet setTweet = new SetTweet();
    TwitterBot root = new TwitterBot();
    File path;
    ComboBox secondsOrMinutes = new ComboBox();
    Label timeOfCoverage = new Label();
    TextField firstValue = new TextField();
    GUI gui = new GUI();
    Map<String, Timer> timersMap = Maps.newHashMap();

    public Tab setTabContent(Map<String, Tab> tabs, User user) {
        VBox tabContent = new VBox();
        tabContent.setAlignment(Pos.TOP_CENTER);
        tabContent.setSpacing(20);
        tabContent.setPadding(new Insets(40));
        Tab tab = new Tab();
        tabs.put("@" + user.getScreenName(), tab);
        tab.setText("@" + user.getScreenName());
        Label spacer = new Label("\n\n\n\n");
        tabContent.getChildren().addAll(createFileChooser(), createTimerChooser(), spacer, timeOfCoverage, createStartButton(user, tabContent));
        tab.setContent(tabContent);

        return tab;
    }

    public HBox createFileChooser() {
        HBox fileChooserBox = new HBox();
        fileChooserBox.setAlignment(Pos.CENTER_LEFT);
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("Selecciona archivo de Excel");
        Label excelFuente = new Label("Selecciona archivo de Excel fuente:     ");
        Button btn = new Button();
        btn.setText("Buscar archivo");
        btn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                path = fileChooser.showOpenDialog(root.stage);
                String absolutePath = path.getAbsolutePath();
                excelFuente.setText("Ruta de archivo:     " + absolutePath + "     ");
                btn.setText("Cambiar archivo");
                setTimeOfCoverage();
                readSelectedExcel(path);
            }
        });

        fileChooserBox.getChildren().addAll(excelFuente, btn);
        return fileChooserBox;
    }

    public ArrayList<String> readSelectedExcel(File path) {
        ArrayList<String> tweetsArray = new ArrayList<>();
        try {
            FileInputStream fileInputStream = new FileInputStream(path);
            XSSFWorkbook wb = new XSSFWorkbook(fileInputStream);
            XSSFSheet sheet = wb.getSheetAt(0);
            sheet = wb.getSheetAt(0);
            for (Row myrow : sheet) {
                for (Cell mycell : myrow) {
                    tweetsArray.add(mycell.getStringCellValue());
                }
            }
        } catch (FileNotFoundException te) {
            te.printStackTrace();
            System.out.println("Accounts.xlsx Not Found");
        } catch (IOException e) {
            e.printStackTrace();
        }

        return tweetsArray;
    }

    public HBox createTimerChooser() {
        HBox timerChooserBox = new HBox();
        timerChooserBox.setAlignment(Pos.CENTER_LEFT);
        Label label1 = new Label("Postear tweet cada   ");
        Label label2 = new Label("   ");
        firstValue.setPrefWidth(45);
        secondsOrMinutes.setPrefWidth(94);
        secondsOrMinutes.getItems().addAll("segundos", "minutos");
        secondsOrMinutes.setValue("segundos");
        //firstValue.setText("0");
        timerChooserBox.getChildren().addAll(label1, firstValue, label2, secondsOrMinutes);

        return timerChooserBox;
    }

    public HBox createStartButton(User user, VBox tabContent) {
        HBox startButtonBox = new HBox();
        Label statusLabel = new Label("");
        startButtonBox.setAlignment(Pos.BOTTOM_CENTER);
        Button btn = new Button();
        btn.setText("Iniciar");
        btn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                Timer timer = new Timer();
                Timeline timeline = new Timeline();
                Text postedTweetsText = new Text();
                String secondsOrMinutesString = secondsOrMinutes.getValue().toString();
                ArrayList<Integer> countTweetsArray = new ArrayList<>();
                int time = Integer.parseInt(firstValue.getText());
                if (secondsOrMinutes.getValue() == "minutos") {
                    int seconds = Integer.parseInt(firstValue.getText());
                    time = (seconds * 60);
                }
                int stopTimer = readSelectedExcel(path).size();
                countTweetsArray.add(0, 1);
                tabContent.getChildren().clear();
                tabContent.getChildren().add(createStatusScreen(countTweetsArray, stopTimer, postedTweetsText, user, tabContent, timer, timeline, secondsOrMinutesString));
                setTweet.setFXTimer(time, stopTimer, tabContent, countTweetsArray, postedTweetsText, user, timer, timeline, secondsOrMinutesString);
                //tabContent.getChildren().add(createStatusScreen(countTweetsArray, stopTimer, postedTweetsText));
                for (int i = 0; i < readSelectedExcel(path).size(); i++) {
                    setTweet.setTimer(timer, time * i, user.getScreenName(), readSelectedExcel(path).get(i), tabContent, countTweetsArray, statusLabel);
                }
            }
        });

        startButtonBox.getChildren().add(btn);
        return startButtonBox;
    }

    public VBox createStatusScreen(ArrayList<Integer> countTweetsArray, int remainingTweets, Text postedTweetsText, User user, VBox tabContent, Timer timer, Timeline timeline, String secondsOrMinutesString) {
        VBox statusScreenBox = new VBox();
        Label postedTweetsLabel = new Label();
        postedTweetsLabel.setText("Estado: Publicando tweets...(" + countTweetsArray.get(0).toString() + "/" + remainingTweets + ")");
        // status.setFill(Color.GREENYELLOW);
        statusScreenBox.setAlignment(Pos.BOTTOM_CENTER);
        postedTweetsLabel.setStyle("-fx-font: 25 helvetica;");
        Button btn = new Button();
        btn.setText("Detener");
        btn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                tabContent.getChildren().clear();
                Label spacer = new Label("\n\n\n\n");
                tabContent.getChildren().addAll(createFileChooser(), createTimerChooser(), spacer, timeOfCoverage, createStartButton(user, tabContent));
                timer.purge();
                timer.cancel();
                timeline.stop();
            }
        });
        System.out.println("secs or mins: " + secondsOrMinutesString);
        Label spacer = new Label("\n\n\n\n");
        statusScreenBox.getChildren().addAll(postedTweetsLabel, spacer, btn);
        return statusScreenBox;

    }

    public void setTimeOfCoverage() {
        timeOfCoverage.setStyle("-fx-font: 16 helvetica;");
        firstValue.textProperty().addListener((observable, oldValue, newValue) -> {
            int valueOfTextBox = Integer.parseInt(newValue);
            int timeOfCoverageInt = valueOfTextBox * readSelectedExcel(path).size();
            if (secondsOrMinutes.getValue() == "minutos") {
                int hours = timeOfCoverageInt / 60; //since both are ints, you get an int
                int minutes = timeOfCoverageInt % 60;
                timeOfCoverage.setText("Tiempo aproximado de cobertura: " + hours + " horas " + minutes + " minutos");
                System.out.println("time of coverage: " + timeOfCoverageInt);
            } else {
                int minutes = timeOfCoverageInt / 60; //since both are ints, you get an int
                int seconds = timeOfCoverageInt % 60;
                timeOfCoverage.setText("Tiempo aproximado de cobertura: " + minutes + " minutos " + seconds + " segundos");
                System.out.println("time of coverage: " + timeOfCoverageInt);
            }

        });

        secondsOrMinutes.valueProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue ov, String t, String t1) {
                int time = Integer.parseInt(firstValue.getText());
                int timeOfCoverageInt = time * readSelectedExcel(path).size();
                if (ov.getValue() == "minutos") {
                    int hours = timeOfCoverageInt / 60; //since both are ints, you get an int
                    int minutes = timeOfCoverageInt % 60;
                    timeOfCoverage.setText("Tiempo aproximado de cobertura: " + hours + " horas " + minutes + " minutos");
                    System.out.println("time of coverage: " + timeOfCoverageInt);
                } else {
                    int minutes = timeOfCoverageInt / 60; //since both are ints, you get an int
                    int seconds = timeOfCoverageInt % 60;
                    timeOfCoverage.setText("Tiempo aproximado de cobertura: " + minutes + " minutos " + seconds + " segundos");
                    System.out.println("time of coverage: " + timeOfCoverageInt);
                }

            }
        });
    }
}

GUI.java

public class GUI {

    SignIn SignIn = new SignIn();
    SetTweet setTweet = new SetTweet();
    BorderPane border = new BorderPane();
    TabPane tabPane = new TabPane();
    GridPane grid = new GridPane();
    TwitterBot root;
    Map<String, Tab> tabs = new HashMap();

    public void setTop() {
        border.setStyle("-fx-background-color: white");
        HBox topPane = new HBox();
        Image img = new Image("file:img/logo.png");
        ImageView imgView = new ImageView(img);

        Image img2 = new Image("file:img/twitterbot.png");
        ImageView imgView2 = new ImageView(img2);

        topPane.setSpacing(90);
        topPane.getChildren().addAll(imgView2, imgView);
        topPane.setAlignment(Pos.TOP_RIGHT);
        border.setTop(topPane);
    }

    public void setLeft() {
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(0, 10, 0, 10));
        Text title = new Text("Lista de Usuarios");
        title.setFont(Font.font("Helvetica", FontWeight.NORMAL, 20));
        grid.add(title, 0, 0);
        grid.add(signInButton(), 1, 0);
        border.setLeft(grid);
    }

    public void setCenter() {
        Text title = new Text("Lista de Usuarios");
        Text title2 = new Text("Lista de Usuarios");
        title.setFont(Font.font("Helvetica", FontWeight.NORMAL, 20));
        tabPane.setId(("MyTabPane"));
        border.setCenter(tabPane);
    }

    public ImageView signInButton() {
        Image img = new Image("file:img/agregarcuenta.png");
        ImageView imgView = new ImageView(img);
        imgView.setOnMouseEntered(event -> {
            TwitterBot.scene.setCursor(Cursor.HAND);
        });
        imgView.setOnMouseExited(event -> {
            TwitterBot.scene.setCursor(Cursor.DEFAULT);
        });

        imgView.setOnMouseClicked(event -> {
            SignIn.signIn();
            ReadAccountsExcelFile readAccountsExcelFile = new ReadAccountsExcelFile();
            readAccountsExcelFile.readAccountsExcel();
            int numOfAccounts = readAccountsExcelFile.usersArray.size() - 1;
            gui.setAccountLabel(readAccountsExcelFile.getUser(readAccountsExcelFile.tokensMap.get(readAccountsExcelFile.usersArray.get(numOfAccounts)),
                    readAccountsExcelFile.secretTokensMap.get(readAccountsExcelFile.usersArray.get(numOfAccounts))), numOfAccounts + 1);
        });

        return imgView;
    }

    private int getRowCount(GridPane pane) {
        int numRows = pane.getRowConstraints().size();
        for (int i = 0; i < pane.getChildren().size(); i++) {
            Node child = pane.getChildren().get(i);
            if (child.isManaged()) {
                Integer rowIndex = GridPane.getRowIndex(child);
                if (rowIndex != null) {
                    numRows = Math.max(numRows, rowIndex + 1);
                }
            }
        }
        return numRows;
    }

    public void setAccountLabel(User user, int rowPos) {
        TabContent tabContent = new TabContent();
        Label account = new Label("");
        account.setPrefWidth(200);
        Image img = new Image(user.getProfileImageURL());
        ImageView imgView = new ImageView(img);
        account.setText("@" + user.getScreenName());
        account.setGraphic(imgView);
        account.setOnMouseEntered(event -> {
            TwitterBot.scene.setCursor(Cursor.HAND);
        });
        account.setOnMouseExited(event -> {
            TwitterBot.scene.setCursor(Cursor.DEFAULT);
        });
        account.setOnMouseClicked(event -> {
            for (int i = 0; i < getRowCount(grid); i++) {
                grid.getChildren().get(i).setStyle("-fx-background-color: white");
            }
            account.setStyle("-fx-background-color: #b3e6ff");
            if (tabPane.getTabs().contains(tabs.get("@" + user.getScreenName()))) {
                SingleSelectionModel<Tab> selectionModel = tabPane.getSelectionModel();
                selectionModel.select(tabs.get("@" + user.getScreenName()));
            } else {
                TabContent tab = new TabContent();
                tabPane.getTabs().add(tab.setTabContent(tabs, user));
                SingleSelectionModel<Tab> selectionModel = tabPane.getSelectionModel();
                selectionModel.select(tabs.get("@" + user.getScreenName()));
            }
        });
        grid.add(account, 0, rowPos);
    }

    public void drawAccountsInGrid() {
        ReadAccountsExcelFile readAccountsExcelFile = new ReadAccountsExcelFile();
        readAccountsExcelFile.readAccountsExcel();
        System.out.println("Numero de usuarios activos: " + readAccountsExcelFile.usersArray.size());
        for (int x = 0; x < readAccountsExcelFile.usersArray.size(); x++) {
            setAccountLabel(readAccountsExcelFile.getUser(readAccountsExcelFile.tokensMap.get(readAccountsExcelFile.usersArray.get(x)),
                    readAccountsExcelFile.secretTokensMap.get(readAccountsExcelFile.usersArray.get(x))), x + 1);
        }
    }

}
\$\endgroup\$
2
\$\begingroup\$

Prefer interfaces over implementations as types

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

Almost always you should define types as an interface rather than an implementation.

    List<String> usersArray = new ArrayList<>();

This makes it easier to switch implementations later or use alternate data sources.

There are rare exceptions, but if this was one of them, I'd expect to see the choice commented so as to avoid someone "fixing" the type later.

try-with-resources

        try {
            File myFile = new File("usr_data/Accounts.xlsx");
            FileInputStream fileInputStream = new FileInputStream(myFile);

If you do this in different order, you can use the try-with-resources form.

        File myFile = new File(FILE_NAME);
        try (FileInputStream fileInputStream = new FileInputStream(myFile)) {

Now the file will close automatically however you leave the try block.

You use the pattern elsewhere. It's not clear why you didn't use it here.

Named constants are better than repeated string literals

This would also require

    private static final String FILE_NAME = "usr_data/Accounts.xlsx";

since I replaced the string literal.

If you make a typo in the name of a constant, your IDE or compiler will notify you. (Unless you accidentally change it to another valid named constant.) If you make a typo in a string literal, you won't get notified until runtime, when the code tries to open the wrong file. And then only if it fails and doesn't just write to the wrong file. Compiler errors are better than runtime errors are better than logic errors, because they are easier to diagnose and quicker to reach. So try to create situations where if errors arise, they are found as quickly as possible.

Don't Repeat Yourself (DRY)

        if (fileExists()) {
            //Read Excel document 
            try {
                FileInputStream input_document = new FileInputStream(new File("usr_data/Accounts.xlsx"));
                // convert it into a POI object
                XSSFWorkbook my_xlsx_workbook = new XSSFWorkbook(input_document);
                // Read excel sheet that needs to be updated
                XSSFSheet my_worksheet = my_xlsx_workbook.getSheet("Accounts");
                //Get number of rows
                int numOfRows = my_worksheet.getLastRowNum() + 1;
                // declare a Cell object of both cells and set values
                Cell userCell = null;
                Cell tokenCell = null;
                Cell secretTokenCell = null;
                Row row = my_worksheet.createRow(numOfRows);
                userCell = row.createCell(0);
                userCell.setCellValue(user);
                tokenCell = row.createCell(1);
                tokenCell.setCellValue(token);
                secretTokenCell = row.createCell(2);
                secretTokenCell.setCellValue(secretToken);
                //important to close InputStream
                input_document.close();
                //Open FileOutputStream to write updates
                FileOutputStream output_file = new FileOutputStream(new File("usr_data/Accounts.xlsx"));
                //write changes
                my_xlsx_workbook.write(output_file);
                //close the stream
                output_file.close();
            } catch (FileNotFoundException te) {
                te.printStackTrace();
                System.out.println("Accounts.xlsx Not Found");
            } catch (IOException e) {
                e.printStackTrace();
            }
        } //create Excel Document
        else {
            XSSFWorkbook wb = new XSSFWorkbook();
            //Workbook wb = new XSSFWorkbook();
            Sheet sheet = wb.createSheet("Accounts");

            // Create a row and put some cells in it. Rows are 0 based.
            Row row = sheet.createRow((short) 0);
            // Create a cell and put a value in it.
            Cell userCell = row.createCell(0);
            Cell tokenCell = row.createCell(1);
            Cell secretTokenCell = row.createCell(2);
            userCell.setCellValue(user);
            tokenCell.setCellValue(token);
            secretTokenCell.setCellValue(secretToken);
            try (FileOutputStream outputStream = new FileOutputStream("usr_data/Accounts.xlsx")) {
                wb.write(outputStream);
                wb.close();
            } catch (FileNotFoundException te) {
                te.printStackTrace();
                System.out.println("Accounts.xlsx Not Found");
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        tokensMap.put(user, token);
        secretTokensMap.put(user, secretToken);
        usersArray.add(user);
    }

First, it's great that you have a helper method fileExists. That's a good pattern. You should do more of it. Consider

        int numOfRows = 0;
        XSSFWorkbook workbook;
        XSSFSheet sheet;
        if (fileExists()) {
            workbook = readWorkbook();
            XSSFSheet my_worksheet = my_xlsx_workbook.getSheet(SHEET_NAME);
            numOfRows = my_worksheet.getLastRowNum() + 1
        }
        else {
            // create Excel Document
            workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet(SHEET_NAME);
        }

        // Create a row and put some cells in it. Rows are 0 based.
        Row row = sheet.createRow(numOfRows);
        // Create a cell and put a value in it.
        Cell userCell = row.createCell(0);
        Cell tokenCell = row.createCell(1);
        Cell secretTokenCell = row.createCell(2);
        userCell.setCellValue(user);
        tokenCell.setCellValue(token);
        secretTokenCell.setCellValue(secretToken);

        writeWorkbook(workbook);

        tokensMap.put(user, token);
        secretTokensMap.put(user, secretToken);
        usersArray.add(user);

And add

    private void writeWorkbook(XSSFWorkbook workbook) {
        try (FileOutputStream outputStream = new FileOutputStream(FILE_NAME)) {
            workbook.write(outputStream);
        } catch (FileNotFoundException te) {
            te.printStackTrace();
            System.out.println("Accounts.xlsx Not Found");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

and

    private XSSFWorkbook readWorkbook() {
        try (FileInputStream input_document = new FileInputStream(new File(FILE_NAME))) {
            // convert it into a POI object
            XSSFWorkbook my_xlsx_workbook = new XSSFWorkbook(input_document);
            return my_xlsx_workbook;
        } catch (FileNotFoundException te) {
            te.printStackTrace();
            System.out.println("Accounts.xlsx Not Found");
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

Note that this will implicitly close the input stream for you. So you don't have to do it explicitly.

Now we only add a row and save the workbook once. We don't repeat the same code twice for each.

Your original would keep going on an error. If that happens here, we'll get a null pointer exception and execution will halt. That seems like a more reliable process than continuing without saving the new entries. Yes, the program will stop running, but it will be in a consistent state. If it keeps going, one data store will include the new data while the other won't.

Simplify

    public boolean fileExists() {
        boolean flag = false;
        File f = new File("usr_data/Accounts.xlsx");
        if (f.exists()) {
            flag = true;
        }
        return flag;
    }

The flag variable is unnecessary.

    public boolean fileExists() {
        File f = new File(FILE_NAME);
        return f.exists();
    }

You could even cut this down to a one-liner. This is probably more readable though.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.