0

How can I add thread synchronization to this piece of code? It's a GUI-based WordCount project

This is my finals project and I need to apply the concept of thread synchronization in this application:

I have tried some methods but none of them are working and you please suggest or write some code that can help me implement the thread synchronization concept.

import java.text.NumberFormat;

public class Count_word_character extends javax.swing.JFrame {

    NumberFormat nf;
    public Count_word_character() {
        initComponents();
        nf=NumberFormat.getInstance();
        nf.setMaximumFractionDigits(0);
        nf.setMinimumFractionDigits(0);
    }
    
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        txt = new javax.swing.JTextArea();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JSeparator();
        letter = new javax.swing.JLabel();
        word = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jLabel1.setFont(new java.awt.Font("Calibri", 1, 14)); // NOI18N
        jLabel1.setText("ENTER YOUR TEXT HERE :");

        txt.setColumns(20);
        txt.setRows(5);
        jScrollPane1.setViewportView(txt);

        jButton1.setFont(new java.awt.Font("Calibri", 1, 13)); // NOI18N
        jButton1.setText("Count");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jButton2.setFont(new java.awt.Font("Calibri", 1, 13)); // NOI18N
        jButton2.setText("Clear");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        letter.setFont(new java.awt.Font("Calibri", 1, 12)); // NOI18N
        letter.setText("Total Number of Character : ");

        word.setFont(new java.awt.Font("Calibri", 1, 12)); // NOI18N
        word.setText("Total Number of Word : ");

        jLabel2.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
        jLabel2.setText("JAVA WORD COUNTER");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE)
                        .addContainerGap())
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jSeparator1)
                        .addContainerGap())))
            .addGroup(layout.createSequentialGroup()
                .addGap(55, 55, 55)
                .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(jButton2, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(62, 62, 62))
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 151, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(55, 55, 55)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(letter, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(word, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(95, 95, 95)
                        .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 206, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel2)
                .addGap(10, 10, 10)
                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton1)
                    .addComponent(jButton2))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(27, 27, 27))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(letter)
                        .addGap(18, 18, 18)))
                .addComponent(word)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                        

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        // TODO add your handling code here:
        
        String s;
        s=txt.getText();
        char c[]= new char[s.length()];
        int i=0,count=0,l=0;
        for(i=0;i<s.length();i++){
            c[i]=s.charAt(i);
            
            //count Charcters
            if(i>0 ||((c[0]!=' ')&&(i==0)))
                l++;
            
          
   
            //count Words
            if(((i>0)&&(c[i]!=' ')&&(c[i-1]==' '))||((c[0]!=' ')&&(i==0))){
               count++; 
            }
            
        }
        
        letter.setText(nf.format(l));
        word.setText(nf.format(count));
    }                                        

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        // TODO add your handling code here:
        txt.setText(null);
        letter.setText(null);
        word.setText(null);
    }                                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(Count_word_character.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(Count_word_character.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(Count_word_character.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(Count_word_character.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>
        

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Count_word_character().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JLabel letter;
    private javax.swing.JTextArea txt;
    private javax.swing.JLabel word;
    // End of variables declaration                   
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • What synchronization? Your entire logic runs on the Swing EDT so no sync is needed. – akarnokd Jun 21 '22 at 07:02
  • So can i implement threading in this Piece of code ? – Ibad hussain Jun 21 '22 at 07:17
  • Why would you? Unless you are to count megabytes of text, there is no need for threading. – akarnokd Jun 21 '22 at 07:34
  • Your existing code correctly constructs a `new Runnable()`, although it looks like the IDE did it for you. See also [*Initial Threads*](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html). – trashgod Jun 21 '22 at 22:37

1 Answers1

1

Please don't be insulted but, forget about that nonsense. Just use a Document Filter on the JTextArea to take care of business. To try this out, I would like you to do the following:

  1. Place the following line of code directly under the code line that you used to initialized your JTextArea (txt), for example:

    txt = new javax.swing.JTextArea();
    // Apply a Document Filter to JTextArea
    ((javax.swing.text.AbstractDocument)txt.getDocument()).setDocumentFilter(new CharacterAndWordCountingDocumentFilter());
    

    EDIT: I see now that you changed your provided code and your JTextArea component is initialized in a non-editable section of the class (NetBeans does this and for good reason). You can just add the line within the class constructor under the initComponents(); method call.

  2. Add the Inner Class supplied below named CharacterAndWordCountingDocumentFilter to your Count_word_character class:

    private class CharacterAndWordCountingDocumentFilter extends javax.swing.text.DocumentFilter {
    
        String docText = "";
        int charCount = 0, wordCount = 0;
    
        @Override
        public void insertString(FilterBypass fb, int offset, String text,
                javax.swing.text.AttributeSet attr)
                throws javax.swing.text.BadLocationException {
    
            super.insertString(fb, offset, text, attr);
        }
    
        @Override
        public void replace(FilterBypass fb, int offset, int length, String text,
                javax.swing.text.AttributeSet attrs)
                throws javax.swing.text.BadLocationException {
    
            super.replace(fb, offset, length, text, attrs);
    
            charCount = fb.getDocument().getLength();
            letter.setText("<html>Total Number of Characters: <font color = blue>"
                    + charCount + "</font></html>");
    
            docText = fb.getDocument().getText(0, fb.getDocument().getLength());
            wordCount = wordCount = getWordCount(docText);
            word.setText("<html>Total Number of Words: <font color=blue>"
                    + wordCount + "</font></html>");
        }
    
        @Override
        public void remove(javax.swing.text.DocumentFilter.FilterBypass fb, int i,
                int i1) throws javax.swing.text.BadLocationException {
    
            super.remove(fb, i, i1);
    
            charCount = fb.getDocument().getLength();
            letter.setText("<html>Total Number of Characters: <font color = blue>"
                    + charCount + "</font></html>");
    
            docText = fb.getDocument().getText(0, fb.getDocument().getLength());
            if (docText.trim().isEmpty()) {
                wordCount = 0;
            }
            else {
                wordCount = getWordCount(docText);
            }
            word.setText("<html>Total Number of Words: <font color=blue>"
                    + wordCount + "</font></html>");
        }
    
        private int getWordCount(String text) {
            return text.replaceAll("\\p{Punct}{1,}", " ").split("\\s+").length;
        }
    }
    

Now run your application and start typing, deleting, copy/pasting, etc and watch the two labels (Character count and Word Count) at the bottom of the JFrame Window. I pasted text containing over 6.5 million characters and had no problems with this. You should experience something like this:

enter image description here

If you like this sort of thing then you can delete the Count button and any events and or concepts related to it.

DevilsHnd - 退職した
  • 8,739
  • 2
  • 19
  • 22