Search code examples
javadisposehashsetjdialog

Filling a HashSet doesn't work the first time -- only on second call


what i try to do:

I want a HashSet to be filled with new words that the program doesn't know. User press the "convert" Button on the mainFrame. The path of a file with words is given on the mainFrame.

If the word is new, a JDialog is opened and asking to insert the new word (so you can change the spelling e.g. first letter big...).

The word is added to the HashSet if the user press the button "write" on the JDialog.

But if i print my HashSet after that, there are only the "old" values shown. When i press the "convert" Button on the mainFrame the second time, all the Values will be shown correctly in the HashSet.

If anyone can help me i would be very grateful. If any more Informations are needed let me know. Here is the code from the ActionListener when the Button "convert" is pressed:

        if (e.getActionCommand().equals(convert.getActionCommand())) {
        try {
            //a file with words is given
            fileHandler = new FileIO(path.getText().trim());

            //lines is a ArrayList<String> and returns all the lines
            lines = fileHandler.readFile();

            for (int i = 0; i < lines.size(); i++) {
                //words is a String[]
                words = lines.get(i).split(" ");
                for (int j = 0; j < words.length; j++) {

                    //hs is a HashSet<String>
                    if (hs.contains(words[j])) {
                        System.out.println("hit: " + words[j]);
                    }else if (!hs.contains(words[j])) {
                        dialog = new JDialog(mainFrame);
                        dialog.setTitle("new Word");
                        dialog.setLayout(new BorderLayout());

                        newWord = new JTextField(words[j].toLowerCase());
                        newWord.selectAll();

                        write = new JButton("write");

                        write.addActionListener(new ActionListener() {

                            public void actionPerformed(ActionEvent e) {
                                //can not use the counters "i" or "j" here otherwise it would be so easy...
                                s = newWord.getText().trim();
                                dialog.setVisible(false);
                                if(dialog != null)
                                    dialog.dispose();
                                if (dialog.isActive()) {
                                    System.out.println("active");
                                }else {
                                    //dead code ??? -- never executed so far
                                    System.out.println("finally....done");
                                }
                            }
                        });

                        dialog.add(newWord, BorderLayout.NORTH);
                        dialog.add(write, BorderLayout.SOUTH);
                        dialog.pack();
                        dialog.setVisible(true);

                        //todo is filled correctly IF pressed "convert Button" the second time
                        if (!s.contentEquals("")) {
                            words[j] = s;
                            hs.add(s);
                            s = "";
                        }

                    }
                } // words


                //Displays the input line but why not the manipulated from the JDialog input?
                StringBuffer sb = new StringBuffer();
                for (String string : words) {
                    sb.append(string);
                    sb.append(" ");
                }
                System.out.println(sb.toString());
                lines.set(i, sb.toString());
                sb.delete(0, sb.length());

            } // lines

code that writes (in a file) and displays my HashSet when i press the "exit" button on the mainFrame:

    hashSetHandler = new HashSetIO(WORDS_FILE);
    hashSetHandler.write(hs);
    for (String string : hs) {
        System.out.println(string);

Solution

  • You should consider making your dialog modal.

    Currently you see many pop-ups (one for each new word read from file) when you press convert, dont't you?

    The difference between modal and "normal" dialog will affect your code here:

    dialog.setVisible(true);
    //todo is filled correctly IF pressed "convert Button" the second time
    if (!s.contentEquals("")) {
      words[j] = s;
      hs.add(s);
      s = "";
    }
    

    A modal dialog will block at the dialog.setVisible(true) line until the write button is pressed, and your ActionListener will process the Event, setting s = newWord.getText().trim(); and disposing the dialog.

    An only after this event (write pressed) is processed the lines of code following the dialog.setVisible(true) will be executed, and s will contain the value of the newWord.getText().trim().

    With "normal" (non-modal) dialog you are not blocking at dialog.setVisible(true) hence the

    if (!s.contentEquals(""))
    

    line will check some value of s that was not yet set (you have not pressed write button yet), the test will fail, and the code in if block will be not executed.

    I would recommend you to debug the code Setting the breakpoints on the if line and in the ActionListener of the write button. Then you will understand better when the code is executed and what the values of your fields are.