Need Realtime updating in JTextArea - java

I am trying to get this JTextArea, called textArea, to update while it is copying these photos but I can't quite seem to get it to work. I was using this code:
String name = "";
int numberOfPicturesCopied = 0;
while (pictures.isEmpty() == f) {
try {
File tmp = pictures.firstElement();
name = tmp.getName();
String filename = destination + Meta.date(tmp) + tmp.getName();
Path source = tmp.toPath();
File destFile = new File(filename);
Path destination = destFile.toPath();
Files.copy(source, destination,
StandardCopyOption.COPY_ATTRIBUTES);
textArea.append("Copied " + name + "\n");
pictures.removeElementAt(0);
numberOfPicturesCopied++;
} catch (FileAlreadyExistsException faee) {
textArea.append("Skipped " + name
+ ": Picture Already In Computer\n");
} catch (NoSuchFileException ncfe) {
File tmp = pictures.firstElement();
String filename = destination + Meta.date(tmp);
File newDir = new File(filename);
newDir.mkdir();
} catch (IOException ee) {
// TODO Auto-generated catch block
ee.printStackTrace();
}
}
and then I changed it to this:
public void copyPictures(){
SwingUtilities.invokeLater(new Thread(){
public void run(){
String name = "";
while(pictures.isEmpty() == f){
try {
File tmp = pictures.firstElement();
name = tmp.getName();
String filename = destination + Meta.date(tmp) + tmp.getName();
Path source = tmp.toPath();
File destFile = new File(filename);
Path destination = destFile.toPath();
Files.copy(source, destination, StandardCopyOption.COPY_ATTRIBUTES);
textArea.append("Copied " + name + "\n");
pictures.removeElementAt(0);
numberOfPicturesCopied++;
} catch(FileAlreadyExistsException faee){
textArea.append("Skipped " + name +": Picture Already In Computer\n");
} catch (NoSuchFileException ncfe){
File tmp = pictures.firstElement();
String filename = destination + Meta.date(tmp);
File newDir = new File(filename);
newDir.mkdir();
} catch (IOException ee) {
// TODO Auto-generated catch block
ee.printStackTrace();
}
}
}
});
}
with the same outcome. Any suggestions?
Also, is there any way to get the text to come in at the top of text area?

How to insert your text at the start is already answered. The other part of your question is the same as always ... you are performing heavy work on the Event Dispatch Thread, which is no longer able to perform repaints.
What you should do is perform the heavy work on a worker thread, and only update the UI on the EDT. You can for example use a SwingWorker, which is designed for this. Or even simpler, take your current code and with a few simple modifications
public void copyPictures(){
new Thread(){
public void run(){
while(pictures.isEmpty() == f){
try {
File tmp = pictures.firstElement();
final String name = tmp.getName();
String filename = destination + Meta.date(tmp) + tmp.getName();
Path source = tmp.toPath();
File destFile = new File(filename);
Path destination = destFile.toPath();
Files.copy(source, destination, StandardCopyOption.COPY_ATTRIBUTES);
SwingUtilities.invokeLater(
new Runnable(){
public void run(){
textArea.append("Copied " + name + "\n");
}
}
);
pictures.removeElementAt(0);
numberOfPicturesCopied++;
} catch(FileAlreadyExistsException faee){
textArea.append("Skipped " + name +": Picture Already In Computer\n");
} catch (NoSuchFileException ncfe){
File tmp = pictures.firstElement();
String filename = destination + Meta.date(tmp);
File newDir = new File(filename);
newDir.mkdir();
} catch (IOException ee) {
// TODO Auto-generated catch block
ee.printStackTrace();
}
}
}
}.run();
}
See how the work is done on a separate Thread yet the UI is updated on the EDT. More information can be found in the Swing Concurrency tutorial or on SO (keyword for your search is SwingWorker, which will results in a heap of examples as this is a daily question)

Not sure what you are asking, the title seems to be saying that the text isnt updating, but your question seems to indicate that is isnt being inserted where you want it to be...
If its the latter, use the insert method instead
textArea.insert("Copied " + name + "\n",0);
to put it at the top of the text area.

Related

Getting current jar file's name

I have this code which on the dev-environment return the information.
But when I run from the jar the code doesn't follow how it should.
The name of the jar is hardcoded and would like to get it's name, because versions vary.
private static String getManifestUrlForClass(Class<?> cl) throws URISyntaxException, IOException {
URL url = cl.getResource(cl.getSimpleName() + ".class");
String s = url.toString();
System.out.println("URL Path: " + url.getPath());
System.out.println("URL File: " + url.getFile());
String path = MYCLASS.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String revisionNumber = "";
String decodedPath = "";
JarFile jarfile = null;
try {
decodedPath = URLDecoder.decode(path, "UTF-8").replace("classes", "");
try {
jarfile = new JarFile(decodedPath + "MYJAR-ver.si.on.jar");
} catch (IOException e1) {
System.out.println("or Path to file cannot decode...");
e1.printStackTrace();
}
Manifest manifestFromJar = jarfile.getManifest(); //
System.out.println("Manifest from " + jarfile.getName().toString() + " = "
+ manifestFromJar.getMainAttributes().getValue("Revision-Number").toString());
revisionNumber = manifestFromJar.getMainAttributes().getValue("Revision-Number").toString();
} catch (IOException e) {
System.out.println(url.getFile().toString() + "is not jar");// TODO Auto-generated catch block
System.out.println("or Path to file cannot decode...");
e.printStackTrace();
}
return revisionNumber;
}
MYJAR will always be the same but the |ver.si.on| will most likely vary and hardcoding the name isn't a best practice.
What I want to do?
1. Get the MYJAR-ver.si.on.jar's location no matter where it is located
2. Use the location to access it's Manifest
3. Use the Manifest to extract revision number
4. Show the revision number in the ui
I'm new yet to java and don't understand it pretty well. I've read something about using "rsrc:" to get to the jar, or something similar to this https://stackoverflow.com/a/40680501/6756124 .

Running multiple Batch files from different threads Java

I have n number of thread getting created at run time according to the input source files present in a folder. For every thread, I have one common class which has all the functions present that are used by every thread. Every thing is working perfectly except the part where batch files are run.
I have main class which is creating thread(which is working perfectly fine). Then I am creating batch files with relevant contents( which is also running perfectly). After that, only 1(can be anyone, no specific pattern) thread is able to execute the batch file and not the others.
Code:
String batch_content = "echo off \n "
+ "powershell.exe -file "
+ utility_path + "convertCSVSwiss.ps1 " + fpath + filename + " -executionpolicy Unrestricted \n ";
String batch_name = "batch_" + fname +"_"+sdf.format(cal.getTime())+ ".bat";
Utils.createBatchFile(batch_content, bat_file_path, batch_name);
Utils.RunBatch(bat_file_path, batch_name,csv_file_path,fname);
Utils.createBatchFile is working fine which create a batch file with the batch content. But Utils.RunBatch seems to having some problem. Here is the code for RunBatch:
public static void RunBatch(String filepath, String filename,String csv_file_path,String fname) throws Exception {
try {
System.out.println("Started Program");
new File(csv_file_path + "\\" + fname).mkdir();
String filePath1 = filepath + filename;
System.out.println("Batch file running is " + filePath1);
Process p = Runtime.getRuntime().exec(new String[] { "cmd.exe", "/c", filePath1 });
p.getOutputStream().close();
p.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
My log file prints this:
Batch file running is C:\ER\ETL\bat files\batch_Sample_Data_10_40_16_12_40_37.bat
Batch file running is C:\ER\ETL\bat files\batch_ssd_10_40_16_12_40_37.bat
but it runs only the first one.
Any help would be appreciated.
P.S I am sorry if I missed any information that may be necessary to get this problem resolved. Please let me know and I can then edit my post.
EDIT:
Here is my code.
//main class to start new thread for every excel file present in the source directory
public class LoadData{
public static void main(String[] args) throws Exception{
try{
File folder = new File(fpath);
File[] listoffiles = folder.listFiles();
for (int i = 0; i < listoffiles.length; i++) {
if (listoffiles[i].isFile()) {
filename = listoffiles[i].getName();
c = filename.lastIndexOf(".");
absfilename = filename.substring(0, c);
System.out.println("File name with extension is "+filename);
System.out.println("File name is "+absfilename);
System.out.println("Starting thread for "+absfilename);
ConvertToCSV et = new ConvertToCSV();
et.fpath = fpath;
et.utility_path=utility_path;
et.filename=filename;
et.fname = absfilename;
et.bat_file_path =bat_file_path;
et.tpath =tpath;
et.csv_file_path=csv_file_path;
Thread t = new Thread(et);
t.start();
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
//class to create the batch file content
public class ConvertToCSV implements Runnable{
String fpath,utility_path,filename,fname,bat_file_path,tpath,csv_file_path;
try{
String batch_content = "echo off \n "
+ "powershell.exe -file "
+ path_to_powershell_script_to_convert_excel_into_csv + "convertCSVSwiss.ps1 " + path_and_name_to_the_excel_file " -executionpolicy Unrestricted \n ";
String batch_name = "batch_" + excel_file_name +"_"+sdf.format(cal.getTime())+ ".bat";
Utils.createBatchFile(batch_content, bat_file_path, batch_name);
Utils.RunBatch(bat_file_path, batch_name,csv_file_path,fname);
}
catch (Exception e) {
e.printStackTrace();
}
}
public class Utils{
//function to create the batch file
public static void createBatchFile(String batch_content, String path, String batch_name) throws IOException {
String p = path + batch_name;
File batfile = new File(p);
FileWriter fw = new FileWriter(batfile);
fw.write(batch_content);
fw.close();
}
//function to run the batch file
public static void RunBatch(String filepath, String filename,String csv_file_path,String fname) throws Exception {
try {
System.out.println("Started Program");
new File(csv_file_path + "\\" + fname).mkdir();
String filePath1 = filepath + filename;
System.out.println("Batch file running is " + filePath1);
Process p = Runtime.getRuntime().exec(new String[] { "cmd.exe", "/c", filePath1 });
p.getOutputStream().close();
p.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
}
EDIT2: I have added the run for ConvertTO CSV. My code is doing say 10 things, and 9 of them are working fine except running two batch files with different names from the same folder
public class ConvertToCSV implements Runnable{
String fpath,utility_path,filename,fname,bat_file_path,tpath,csv_file_path,pg_db_url,pg_db,pg_db_uid,pg_db_pwd,plpgsql_path,Log_Path;
SimpleDateFormat sdf = new SimpleDateFormat("dd_mm_yy_hh_mm_ss");
Calendar cal = Calendar.getInstance();
#Override
public void run() {
try {
runConvertToCSV(fpath,utility_path,filename,fname,bat_file_path,tpath,csv_file_path,plpgsql_path);
} catch (Exception e) {
e.printStackTrace();
}
}
private void runConvertToCSV(String fpath,String utility_path,String filename,String fname,String bat_file,String tpath,String csv_file_path,String plpgsql_path) throws Exception{try{
String batch_content = "echo off \n "
+ "powershell.exe -file "
+ path_to_powershell_script_to_convert_excel_into_csv + "convertCSVSwiss.ps1 " + path_and_name_to_the_excel_file " -executionpolicy Unrestricted \n ";
String batch_name = "batch_" + excel_file_name +"_"+sdf.format(cal.getTime())+ ".bat";
Utils.createBatchFile(batch_content, bat_file_path, batch_name);
Utils.RunBatch(bat_file_path, batch_name,csv_file_path,fname);
}
catch (Exception e) {
e.printStackTrace();
}
}
EDIT3#:
My guess was that maybe because all the batch files are trying to access the same powershell script, that is why it is not working. But then i created ps script for every batch file. Also, added error stream to the stdout to check if there is any error and this is what i am getting:
Standard Error:
The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
At C:\ER\ETL\ETL_SOURCE\convertCSVSwiss_Swiss_Sample_Data.ps1:24 char:2
+ $Worksheet.SaveAs($ExtractedFileName,6)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], COMException
+ FullyQualifiedErrorId : System.Runtime.InteropServices.COMException
there are number of same error at different line. NOTE: It is the same ps script for all the batch files, it runs only for one and not for others. and that one can be anyone(no pattern).
If i run the above batch file manually, then it succeeds.

How to show a progress bar while downloading in javafx

I am building a desktop app using javafx, I am downloading a file around 500 MB using ftp.
I need to show the progress bar with % while downloading is in progress.
I also need to give a option to cancel a ongoing downloading process.
This is my code to download file.
try {
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
success = ftpClient.changeWorkingDirectory(PATH + preset + "/" + file_to_download + offset);
System.out.println("Download Path:-" + PATH + preset + "/" + file_to_download + offset);
if (!success) {
System.out.println("Could not changed the directory to RIBS");
return;
} else {
System.out.println("Directory changed to RIBS");
}
FTPFile[] files = ftpClient.listFiles();
for (FTPFile file : files) {
if (file.getName().contains(".zip")) {
dfile = file.getName();
}
}
DirectoryChooser dirChooser = new DirectoryChooser();
File chosenDir = dirChooser.showDialog(tableView.getScene().getWindow());
System.out.println(chosenDir.getAbsolutePath());
OutputStream output;
output = new FileOutputStream(chosenDir.getAbsolutePath() + "/" + dfile);
int timeOut = 500;
ftpClient.setConnectTimeout(timeOut);
if (ftpClient.retrieveFile(dfile, output) == true) {
downloadButton.setDisable(true);
}
output.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You should make yourself familiar with Concurrency in JavaFX.
And you can find several examples about what you need on the web, e. g. ProgressBar and Background Processes.

How to upload file using java ?

Hello i m trying to upload file using java file.. but i don't get it.. i get file size=0 i'm providing here my java code. tell me why i cant upload on particular folder. i want to store my file in particular folder. i am trying to get file size, file name but i got the null value where am i wrong please tell me.
public void updateTesti(ActionRequest actionRequest,ActionResponse actionResponse) throws IOException, PortletException
{
//image upload logic
String folder_for_upload =(getPortletContext().getRealPath("/"));
//String folder=actionRequest.getParameter("uploadfolder");
realPath=getPortletContext().getRealPath("/");
logger.info("RealPath is" + realPath);
logger.info("Folder is :" + folder_for_upload);
try
{
logger.info("Admin is try to upload");
UploadPortletRequest uploadRequest = PortalUtil.getUploadPortletRequest(actionRequest);
if (uploadRequest.getSize("fileName") == 0) {
SessionErrors.add(actionRequest, "error");
}
String sourceFileName = uploadRequest.getFileName("fileName");
File uploadedFile = uploadRequest.getFile("fileName");
System.out.println("Size of uploaded file: " + uploadRequest.getSize("fileName"));
logger.info("Uploded file name is: " + uploadRequest.getFileName("fileName"));
String destiFolder=("/home/ubuntu/liferay/liferay-portal-6.1.1-ce-ga2/tomcat-7.0.27/webapps/imageUpload-portlet/image");
String newsourcefilename = (uploadRequest.getFileName("fileName"));
File newFile = new File(destiFolder +"/"+ newsourcefilename);
logger.info("New file name: " + newFile.getName());
logger.info("New file path: " + newFile.getPath());
InputStream in = new BufferedInputStream(uploadRequest.getFileAsStream("fileName"));
FileInputStream fis = new FileInputStream(uploadedFile);
FileOutputStream fos = new FileOutputStream(newFile);
byte[] bytes_ = FileUtil.getBytes(in);
int i = fis.read(bytes_);
while (i != -1) {
fos.write(bytes_, 0, i);
i = fis.read(bytes_);
}
fis.close();
fos.close();
Float size = (float) newFile.length();
System.out.println("file size bytes:" + size);
System.out.println("file size Mb:" + size / 1048576);
logger.info("File created: " + newFile.getName());
SessionMessages.add(actionRequest, "success");
}
catch (FileNotFoundException e)
{
System.out.println("File Not Found.");
e.printStackTrace();
SessionMessages.add(actionRequest, "error");
}
catch (NullPointerException e)
{
System.out.println("File Not Found");
e.printStackTrace();
SessionMessages.add(actionRequest, "error");
}
catch (IOException e1)
{
System.out.println("Error Reading The File.");
SessionMessages.add(actionRequest, "error");
e1.printStackTrace();
}
}
You need to do this to upload small files < 1kb
File f2 = uploadRequest.getFile("fileupload", true);
They are stored in memory only. I have it in my catch statement incase I get a null pointer - or incase my original file (f1.length) == 0
I have executed your code.It is working as per expectation.There might be something wrong in your jsp page.I am not sure but might be your name attribute is not same as the one which you are using in processAction(assuming that you are using portlet).Parameter is case sensitive,so check it again.
You will find more on below link.It has good explanation in file upload.
http://www.codeyouneed.com/liferay-portlet-file-upload-tutorial/
I went through a file upload code, and when i implement that in my local system what i got is, portlet is saving the file i upload in tomcat/webbapp/abc_portlet_project location, what i dont understand is from where portlet found
String folder = getInitParameter("uploadFolder");
String realPath = getPortletContext().getRealPath("/");
System.out.println("RealPath" + realPath +"\\" + folder); try {
UploadPortletRequest uploadRequest =
PortalUtil.getUploadPortletRequest(actionRequest);
System.out.println("Size: "+uploadRequest.getSize("fileName"));
if (uploadRequest.getSize("fileName")==0)
{SessionErrors.add(actionRequest, "error");}
String sourceFileName = uploadRequest.getFileName("fileName"); File
file = uploadRequest.getFile("fileName");
System.out.println("Nome file:" +
uploadRequest.getFileName("fileName")); File newFolder = null;
newFolder = new File(realPath +"\" + folder);
if(!newFolder.exists()){ newFolder.mkdir(); }
File newfile = null;
newfile = new File(newFolder.getAbsoluteFile()+"\"+sourceFileName);
System.out.println("New file name: " + newfile.getName());
System.out.println("New file path: " + newfile.getPath());
InputStream in = new
BufferedInputStream(uploadRequest.getFileAsStream("fileName"));
FileInputStream fis = new FileInputStream(file); FileOutputStream fos
= new FileOutputStream(newfile);

Java writing to a text file not working properly

The Java application that I support is logging some details in a flat file. the problem I face some times is that, the entry is very low compared to the previous day. This entry is most essential because our reports are generated based on the file. I went thro code for writing I couldn't figure out any issues. the method which is writing is sync method.
Any suggestions? I can also provide the code for you is you may need?
public synchronized void log (String connID, String hotline, String callerType,
String cli, String lastMenu, String lastInput,
String status, String reason)
{
//String absoluteFP = LOG_LOC + ls + this.getFilename();
//PrintWriter pw = this.getPrintWriter(absoluteFP, true, true);
try
{
pw.print (this.getDateTime ()+ ","+connID +","+hotline+","+callerType+","+ cli+"," + lastMenu + "," + lastInput + "," + status + "," + reason);
//end 1006
pw.print (ls);
pw.flush ();
//pw.close();
}
catch (Exception e)
{
e.printStackTrace ();
return;
}
}
private synchronized PrintWriter getPrintWriter (String absoluteFileName,
boolean append, boolean autoFlush)
{
try
{
//set absolute filepath
File folder = new File (absoluteFileName).getParentFile ();//2009-01-23
File f = new File (absoluteFileName);
if (!folder.exists ())//2009-01-23
{
//System.out.println ("Call Detailed Record folder NOT FOUND! Creating a new);
folder.mkdirs ();
//System.out.println ("Configure log folder");
this.setHiddenFile (LOG_LOC);//set tmp directory to hidden folder
if (!f.exists ())
{
//System.out.println ("Creating a new Call Detailed Record...");//2009-01-23
f.createNewFile ();//2009-01-23
}
}
else
{
if (!f.exists ())
{
//System.out.println ("Creating a new Call Detailed Record...");//2009-01-23
f.createNewFile ();//2009-01-23
}
}
FileOutputStream tempFOS = new FileOutputStream (absoluteFileName, append);
if (tempFOS != null)
{
return new PrintWriter (tempFOS, autoFlush);
}
else
{
return null;
}
}
catch (Exception ex)
{
ex.printStackTrace ();
return null;
}
}
/**
* Set the given absolute file path as a hidden file.
* #param absoluteFile String
*/
private void setHiddenFile (String absoluteFile)
{
//set hidden file
//2009-01-22, KC
Runtime rt = Runtime.getRuntime ();
absoluteFile = absoluteFile.substring (0, absoluteFile.length () - 1);//2009-01-23
try
{
System.out.println (rt.exec ("attrib +H " + "\"" + absoluteFile + "\"").getInputStream ().toString ());
}
catch (IOException e)
{
e.printStackTrace ();
}
}
private String getDateTime ()
{
//2011-076-09, KC-format up to milliseconds to prevent duplicate PK in CDR table.
//return DateUtils.now ("yyyy/MM/dd HH:mm:ss");
return DateUtils.now ("yyyy/MM/dd HH:mm:ss:SSS");
//end 0609
}
private String getFilename ()
{
///return "CDR_" + port + ".dat";//2010-10-01
return port + ".dat";//2010-10-01
}
public void closePW ()
{
if (pw != null)
{
pw.close ();
}
}
You've created a FileOutputStream, but aren't closing that stream. Close that stream and try again. That might be causing the problem.
Messages are getting logged sometime because the garbage collector kicks in at some intervals and closes the FileOutStream. This then allows messages to be logged again. You're getting the unreachable error since you have a return statement in both the if & else blocks. You'll have to take the PrintWriter and FileOutStreamWriter out of the getPrintWriter put it where you usually call the getPrintWriter(). Then you'll be able to close the streams correctly. getPrintWriter should only ensure file exists, so rename it to ensureFileExistance
If you can use Apache Common IO, try this:
public synchronized void log(String connID, String hotline, String callerType,
String cli, String lastMenu, String lastInput,
String status, String reason) {
String absoluteFP = LOG_LOC + ls + this.getFilename();
File file = new File(absoluteFP);
String message = this.getDateTime() + "," + connID + "," + hotline + "," + callerType + "," + cli + "," + lastMenu + "," + lastInput + "," + status + "," + reason;
try {
// note that you must explicitly add new line character if you want the line to end with newline
FileUtils.write(file, message + "\n", "UTF-8", true);
} catch (IOException ex) {
ex.printStackTrace ();
}
}
In Common IO 2.1, you can append a file that you are writting to. You can now get rid of the closePW and getPrintwriter and since the log method is synchronized, the file can be written one at a time from the same object. However, if you try to write the same file from different object at the same time, you will end up having overwritting problem.
Also, Common IO create the missing parent folder for you automatically. There is no need to explicitly check and create the folder.

Categories

Resources