I am building GUI text editor using thread .In this editor, one thread is use to count number of words and char in text area and another thread to save file in given interval(which is not yet implemented).
Main Window GUI
import java.util.Calendar;
import java.util.Locale;
public class MainWindow extends javax.swing.JFrame {
/**
* Creates new form MainWindow
*/
private long initial,last;
public MainWindow() {
initComponents();
Operation op = new Operation(this);
// new FileOperation(op, "demo.txt");
new Count(op);
}
public void saveFile(){
}
public void countUpdate(String wordCount){
System.out.println(wordCount);
counting.setText(wordCount);
}
public long getTime(){ return last-initial;}
public String getInput(){ return textfield.getText();}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
textfield = new javax.swing.JTextArea();
save = new javax.swing.JLabel();
counting = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
textfield.setColumns(20);
textfield.setRows(5);
textfield.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyPressed(java.awt.event.KeyEvent evt) {
textfieldKeyPressed(evt);
}
public void keyReleased(java.awt.event.KeyEvent evt) {
textfieldKeyReleased(evt);
}
});
jScrollPane1.setViewportView(textfield);
save.setText(" ");
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, false)
.addGroup(layout.createSequentialGroup()
.addComponent(save, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(counting, javax.swing.GroupLayout.PREFERRED_SIZE, 103, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 370, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(18, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(26, 26, 26)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 240, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(save)
.addGap(0, 0, Short.MAX_VALUE))
.addComponent(counting, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void textfieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_textfieldKeyReleased
// TODO add your handling code here:
last = Calendar.getInstance().getTimeInMillis();
}//GEN-LAST:event_textfieldKeyReleased
private void textfieldKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_textfieldKeyPressed
// TODO add your handling code here:
if(getTime() > 1000)
notifyAll();
initial = Calendar.getInstance().getTimeInMillis();
}//GEN-LAST:event_textfieldKeyPressed
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
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(MainWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(MainWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(MainWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(MainWindow.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 MainWindow().setVisible(true);
}
});
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel counting;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JLabel save;
private javax.swing.JTextArea textfield;
// End of variables declaration//GEN-END:variables
}
COUNT.JAVA
import java.util.logging.Level;
import java.util.logging.Logger;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author DEV
*/
public class Count implements Runnable{
Operation target;
Thread t;
public Count(Operation operation) {
target = operation;
t = new Thread(this,"Counting Thread");
t.start();
}
@Override
public void run() {
while(true){
target.countWord();
}
}
}
Operation.java
import java.io.FileWriter;
import java.io.IOException;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author DEV
*/
public class Operation {
boolean flag= true;
MainWindow window ;
String text ;
Operation(MainWindow window){
this.window = window;
this.text="";
}
synchronized public void save(FileWriter data){
try {
while(flag)
{
wait();
}
data.write(text);
data.close();
flag = true;
} catch (IOException ex) {
Logger.getLogger(Operation.class.getName()).log(Level.SEVERE, null, ex);
} catch (InterruptedException ex) {
Logger.getLogger(Operation.class.getName()).log(Level.SEVERE, null, ex);
}
}
synchronized public void countWord(){
while(!flag){
try {
wait();
} catch (InterruptedException ex) {
Logger.getLogger(Operation.class.getName()).log(Level.SEVERE, null, ex);
}
}
String result;
StringTokenizer token= null;
text = window.getInput();
if(text.length() > 0)
{
token = new StringTokenizer(text);
result = token.countTokens() + " w, "+ text.length()+" c";
window.countUpdate(result);
}
else{
result =" 0 w, 0,c";
}
flag = true;
}
}
The thread within Count
is running an endless loop:
while(true){
target.countWord();
}
so this is going to consume a lot of CPU cycles.
The whole approach needs to be changed. Take a look at event listeners. For example, when a user presses a key would be a good opportunity to update the count.