Append data as I progress instead of do it at a time - java

I'm coding a swing App. Here the tasks are to download the file from a given URL and then get the counts of them. The program works with no issues/errors.
The problem is I've a testarea in my frame, when file 1 is downloaded I want the text area to show downloaded file 1 and when file 2 is done downloaded file 1 and so on...
Currently in my program the message is displayed but all at once. I mean if I've 10 files, it shows.
downloaded file 1
downloaded file 2
.
.
.
.
.
downloaded file 10
But this is shown only after all the 10 files are downloaded. To see if there is any other problem, I've added sysout just below the textarea code. And to my surprise, sysouts are printed 10 times, I mean each time a file is processed, this is triggered, but the textarea is appended with all the data at a time.
Below are my codes.
GuiForPDFs
import java.awt.BorderLayout;
public class GuiForPDFs extends JFrame {
private JPanel contentPane;
private JTextField srcTextField;
private JTextArea textArea;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GuiForPDFs frame = new GuiForPDFs();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
FileDownloadTest downloadTest = new FileDownloadTest();
public GuiForPDFs() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 552, 358);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
srcTextField = new JTextField();
srcTextField.setBounds(10, 26, 399, 20);
contentPane.add(srcTextField);
srcTextField.setColumns(10);
JButton srcBtn = new JButton("Source Excel");
srcBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser fChoose = new JFileChooser();
if (fChoose.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
srcTextField.setText(fChoose.getSelectedFile().getAbsolutePath());
} else {
System.out.println("No Selection");
}
}
});
textArea = new JTextArea();
textArea.setEditable(false);
textArea.setBounds(10, 106, 516, 203);
contentPane.add(textArea);
srcBtn.setBounds(419, 25, 107, 23);
contentPane.add(srcBtn);
JButton dNcButton = new JButton("Process");
dNcButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
downloadTest.fileDownloadTest(srcTextField.getText(), textArea);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
dNcButton.setBounds(212, 70, 89, 23);
contentPane.add(dNcButton);
}
}
FileDownloadTest
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.JTextArea;
import org.apache.commons.io.FileUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class FileDownloadTest {
public void fileDownloadTest(String src, JTextArea textArea) throws IOException, InterruptedException {
String path = src;
FileInputStream fin = new FileInputStream(new File(path));
XSSFWorkbook workbook = new XSSFWorkbook(fin);
XSSFSheet sheet = workbook.getSheetAt(0);
int rows = sheet.getPhysicalNumberOfRows();
System.out.println("rows are " + rows);
XSSFCell cell;
// Make sure that this directory exists
String dirName = src.substring(0, src.lastIndexOf("\\"));
File f = new File(dirName);
if (!f.exists()) {
f.mkdir();
}
System.out.println(f.getAbsolutePath() + " is Directory Name " + src + " is the file");
for (int i = 1; i < rows; i++) {
XSSFCell url = sheet.getRow(i).getCell(0);
String URLString = url.toString();
cell = sheet.getRow(i).getCell(7);
String fileName = URLString.substring(URLString.lastIndexOf("/") + 1);
int pageNumbers = downloadFiles(dirName, url.toString().replace("http", "https"));
if (cell == null) {
cell = sheet.getRow(i).createCell(1);
}
cell.setCellType(Cell.CELL_TYPE_NUMERIC);
cell.setCellValue(pageNumbers);
FileOutputStream fileOut = new FileOutputStream(path);
workbook.write(fileOut);
fileOut.close();
textArea.append("downloaded " + fileName + "\n");
System.out.println("Done");
}
workbook.close();
fin.close();
}
public static int downloadFiles(String dirName, String urlString) {
System.out.println("Downloading \'" + urlString + "\' PDF document...");
String fileName = urlString.substring(urlString.lastIndexOf("/") + 1);
System.out.println(fileName + " is file name");
try {
saveFileFromUrlWithJavaIO(dirName + "\\" + fileName, urlString);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Downloaded \'" + urlString + "\' PDF document...");
int pageNumber = 0;
try {
pageNumber = getNoOfPages(dirName + "\\" + fileName);
} catch (IOException e) {
e.printStackTrace();
}
return pageNumber;
}
public static int getNoOfPages(String fileName) throws IOException {
PDDocument document = PDDocument.load(new File(fileName));
int numberOfPages = document.getNumberOfPages();
return numberOfPages;
}
public static void saveFileFromUrlWithJavaIO(String fileName, String fileUrl)
throws MalformedURLException, IOException {
BufferedInputStream in = null;
FileOutputStream fout = null;
try {
in = new BufferedInputStream(new URL(fileUrl).openStream());
fout = new FileOutputStream(fileName);
byte data[] = new byte[1024];
int count;
while ((count = in.read(data, 0, 1024)) != -1) {
fout.write(data, 0, count);
}
} finally {
if (in != null)
in.close();
if (fout != null)
fout.close();
}
}
public static void saveFileFromUrlWithCommonsIO(String fileName, String fileUrl)
throws MalformedURLException, IOException {
FileUtils.copyURLToFile(new URL(fileUrl), new File(fileName));
}
}
please let me know How can I fix this.
Thanks

The above comments are correct, you are on the EDT when adding text to the TextArea. This is because you are calling downloadTest.fileDownloadTest from the dNcButton ActionListener implementation.
It's good practice to get off the EDT is you have a long running operation to perform, and downloading a file is often given as as example of the sort of thing you don't want to do on the EDT.
There are lots of resources online as to how to get off the EDT, including many on this great site;
On Event Dispatch Thread---want to get off of it
Make thread run on non EDT (event dispatch thread) thread from EDT

As with the other comments, you need to keep only UI related tasks on the EDT. Otherwise if your user is downloading 100 files the UI will lock up until the download task is finished. SwingWorker is the perfect class to do this for Swing applications. Here is a quick example:
// Run your FileDownloadTest inside a SwingWorker
// or have the class extend SwingWorker
new SwingWorker<Void, String>() {
#Override
protected Void doInBackground() throws Exception {
//Perform downloading here (done off the EDT)
//Call publish(downloadedFileName) to be sent to the process method()
return null;
}
#Override
protected void process(List<String> chunks) {
// Modify textArea (done on the EDT)
StringBuilder downloadedFiles = new StringBuilder();
for (String fileName : chunks) {
downloadedFiles.append("downloaded" + fileName + "\n");
}
textArea.setText(downloadedFiles);
}
#Override
protected void done() {
//Anything you want to happen after doInBackground() finishes
}
}.execute();

Related

Why isn't my image downloading when I use a SwingWorker but downloads when I don't?

I'm creating a progress bar to monitor an image download. The image download doesn't work — it generates a file measuring 0 bytes in size. If I move my code to a standalone class without a SwingWorker, the image download works. I've played with this for a while and I still don't know what I'm doing wrong. The two code blocks are identical. Any tips would be much appreciated!
Image download with SwingWorker (take note of doInBackground):
package download_progress_bar;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.beans.*;
import java.net.*;
import java.io.*;
public class ProgressBar implements ActionListener, PropertyChangeListener {
private JFrame frame;
private JPanel gui;
private JButton button;
private JProgressBar progressBar;
private SwingWorker<Void, Void> worker;
private boolean done;
public ProgressBar() {
done = false;
customizeFrame();
createMainPanel();
createProgressBar();
createButton();
addComponentsToFrame();
}
private void customizeFrame() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void createMainPanel() {
gui = new JPanel();
gui.setLayout(new BorderLayout());
}
private void createProgressBar() {
progressBar = new JProgressBar(0, 100);
progressBar.setStringPainted(true); // renders a progress string
}
private void createButton() {
button = new JButton("Start download");
button.addActionListener(this);
}
/**
* Invoked when user clicks the button.
*/
public void actionPerformed(ActionEvent evt) {
button.setEnabled(false);
// NOTE: Instances of javax.swing.SwingWorker are not reusable,
// so we create new instances as needed
worker = new Worker();
worker.addPropertyChangeListener(this);
worker.execute();
}
class Worker extends SwingWorker<Void, Void> {
/*
* Main task. Executed in worker thread.
*/
#Override
protected Void doInBackground() throws MalformedURLException {
// Create a URL object for a given URL
String src = "https://lh3.googleusercontent.com/l6JAkhvfxbP61_FWN92j4ulDMXJNH3HT1DR6xrE7MtwW-2AxpZl_WLnBzTpWhCuYkbHihgBQ=s640-h400-e365";
URL url = new URL(src);
// Open connection on the URL object
try {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Always check response code first
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
System.out.println(responseCode);
// Open input stream from connection
BufferedInputStream in = new BufferedInputStream(connection.getInputStream());
// Open output stream for file writing
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("cat.jpg"));
int bytesRead = - 1;
int totalBytesRead = 0;
int percentCompleted = 0;
while ((bytesRead = in.read()) != -1) {
out.write(bytesRead);
totalBytesRead += bytesRead;
percentCompleted = totalBytesRead * 100 / connection.getContentLength();
System.out.println("..." + percentCompleted);
this.setProgress(percentCompleted);
}
// Close streams
out.close();
in.close();
}
} catch (IOException ex) {
System.out.println(ex);
this.setProgress(0);
cancel(true);
}
return null;
}
/*
* Executed in event dispatching thread
*/
#Override
protected void done() {
button.setEnabled(true);
if (!isCancelled()) {
System.out.println("File has been downloaded successfully!");
} else {
System.out.println("There was an error in downloading the file.");
}
}
}
/**
* Invoked when task's progress property changes.
*/
public void propertyChange(PropertyChangeEvent evt) {
System.out.println(evt);
// NOTE: By default two property states exist: "state" and "progress"
if (evt.getPropertyName().equals("progress")) {
int progress = (Integer) evt.getNewValue();
progressBar.setValue(progress);
System.out.println(String.format(
"Completed %d%% of task.\n", progress));
}
}
private void addComponentsToFrame() {
gui.add(progressBar, BorderLayout.CENTER);
gui.add(button, BorderLayout.SOUTH);
frame.add(gui);
frame.pack();
}
public void activate() {
frame.setVisible(true);
}
}
Image download with standalone Downloader class (take note of download):
package download_progress_bar;
import java.net.*;
import java.io.*;
public class Downloader {
public static void main(String[] args) throws IOException {
download();
}
public static void download() throws IOException {
// Create a URL object for a given URL
String src = "https://lh3.googleusercontent.com/l6JAkhvfxbP61_FWN92j4ulDMXJNH3HT1DR6xrE7MtwW-2AxpZl_WLnBzTpWhCuYkbHihgBQ=s640-h400-e365";
URL url = new URL(src);
// Open connection on the URL object
try {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Always check response code first
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
System.out.println(responseCode);
// Open input stream from connection
BufferedInputStream in = new BufferedInputStream(connection.getInputStream());
// Open output stream for file writing
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("test.jpg"));
int bytesRead = - 1;
int totalBytesRead = 0;
int percentCompleted = 0;
while ((bytesRead = in.read()) != -1) {
out.write(bytesRead);
totalBytesRead += bytesRead;
percentCompleted = totalBytesRead * 100 / connection.getContentLength();
System.out.println("..." + percentCompleted);
}
// Close streams
out.close();
in.close();
}
} catch (IOException ex) {
System.out.println(ex);
}
}
}
You should call get() in done(). If doInBackground throws an exception, then get() will throw an ExecutionException whose cause is the exception from doInBackground.
Something like this:
#Override
protected void done() {
button.setEnabled(true);
try {
if (!isCancelled()) {
get();
System.out.println("File has been downloaded successfully!");
return;
}
} catch (InterruptedException x) {
x.printStackTrace();
} catch (ExecutionException x) {
// This should print an IllegalArgumentException
// if me theory (explained below) is correct.
x.getCause().printStackTrace();
}
System.out.println("There was an error in downloading the file.");
}
My theory is that the issue is related to this line:
totalBytesRead += bytesRead;
Since bytesRead is the return value of InputStream.read(), it's actually a byte of data, not the number of bytes read. This doesn't have an obvious effect on the I/O, but it corrupts the value of percentCompleted. This ends up passing a value which is greater than 100 to setProgress which throws an exception. The line should be totalBytesRead++; instead.
You can verify my theory with the aforementioned modification to done().

How can I embed microsoft word in java Form?

I want to read a word document with the help of microsoft word but that would be limited to my java form . The document will be opened in java form with the help of microsoft word .
Like the following picture , I want to develop something :
User can edit the doc according to their need . But when they want to save the document , the document will be saved in a remote machine .
I can open the word document with the help of microsoft word by the following code :
try {
/* if (Desktop.isDesktopSupported()) {
Desktop.getDesktop().open(new File("E:\\finger.docx"));
}*/
Process p = Runtime.getRuntime()
.exec("rundll32 url.dll,FileProtocolHandler E:\\finger.docx");
p.waitFor();
System.out.println("Done.");
} catch (IOException ioe) {
ioe.printStackTrace();
}
catch (InterruptedException ex) {
Logger.getLogger(JavaFromWord.class.getName()).log(Level.SEVERE, null, ex);
}
But I do not know how can I embed the word viewer in JForm . Please help me .
I have succeeded to do this job . The following code helps me a lot to do it .
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.ole.win32.OLE;
import org.eclipse.swt.ole.win32.OleClientSite;
import org.eclipse.swt.ole.win32.OleFrame;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import com.connect.DBConnectionHandler;
public class SWTMenuExample {
static OleClientSite clientSite;
static OleFrame frame;
static File file;
static Shell shell;
static KeyListener keyListener;
static Display display;
public static void main(final String[] args) {
display = new Display();
shell = new Shell(display);
shell.setSize(800, 600);
shell.setText("Word Example");
shell.setLayout(new FillLayout());
try {
frame = new OleFrame(shell, SWT.NONE);
// esto abre un documento existente
// clientSite = new OleClientSite(frame, SWT.NONE, new
// File("Doc1.doc"));
// esto abre un documento en blanco
// clientSite = new OleClientSite(frame, SWT.NONE, "Word.Document");
addFileMenu(frame);
System.out.println(" I am in run method ");
} catch (final SWTError e) {
System.out.println("Unable to open activeX control");
display.dispose();
return;
}
keyListener = new KeyListener() {
public void keyReleased(KeyEvent paramKeyEvent) {
}
public void keyPressed(KeyEvent paramKeyEvent) {
// TODO Auto-generated method stub
if (((paramKeyEvent.stateMask & SWT.CTRL) == SWT.CTRL)
&& (paramKeyEvent.keyCode == 's')) {
JOptionPane.showMessageDialog(null,
"ctrl+s is pressed down initial ",
"Warning Message", JOptionPane.WARNING_MESSAGE);
if (file != null) {
clientSite.save(file, true);
fileSave();
JOptionPane.showMessageDialog(null,
"ctrl+s is pressed down", "Warning Message",
JOptionPane.WARNING_MESSAGE);
} else
JOptionPane.showMessageDialog(null, "File is null",
"Warning Message", JOptionPane.WARNING_MESSAGE);
}
}
};
display.addFilter(SWT.KeyDown, new Listener() {
public void handleEvent(Event e) {
if (((e.stateMask & SWT.CTRL) == SWT.CTRL)
&& (e.keyCode == 's')) {
System.out.println("From Display I am the Key down !!"
+ e.keyCode);
}
}
});
final Color green = display.getSystemColor(SWT.COLOR_GREEN);
final Color orig = shell.getBackground();
shell.addKeyListener(new KeyListener() {
public void keyReleased(KeyEvent e) {
if (((e.stateMask & SWT.CTRL) == SWT.CTRL)
&& (e.keyCode == 's')) {
shell.setBackground(orig);
System.out.println("Key up !!");
}
}
public void keyPressed(KeyEvent e) {
if (((e.stateMask & SWT.CTRL) == SWT.CTRL)
&& (e.keyCode == 's')) {
shell.setBackground(green);
System.out.println("Key down !!");
}
}
});
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
static void addFileMenu(OleFrame frame) {
final Shell shell = frame.getShell();
Menu menuBar = shell.getMenuBar();
if (menuBar == null) {
menuBar = new Menu(shell, SWT.BAR);
shell.setMenuBar(menuBar);
}
MenuItem fileMenu = new MenuItem(menuBar, SWT.CASCADE);
fileMenu.setText("&File");
Menu menuFile = new Menu(fileMenu);
fileMenu.setMenu(menuFile);
frame.setFileMenus(new MenuItem[] { fileMenu });
MenuItem menuFileCreate = new MenuItem(menuFile, SWT.CASCADE);
menuFileCreate.setText("Create File");
menuFileCreate.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
fileCreate();
}
});
MenuItem menuFileOpen = new MenuItem(menuFile, SWT.CASCADE);
menuFileOpen.setText("Open File");
menuFileOpen.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
fileOpen();
}
});
MenuItem menuFileSave = new MenuItem(menuFile, SWT.CASCADE);
menuFileSave.setText("Save File");
menuFileSave.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
if (file != null) {
clientSite.save(file, true);
fileSave();
}
}
});
MenuItem menuFileClose = new MenuItem(menuFile, SWT.CASCADE);
menuFileClose.setText("Close File");
menuFileClose.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
if (clientSite != null) {
clientSite.dispose();
file = null;
}
}
});
}
static void fileCreate() {
if (clientSite != null)
clientSite.dispose();
if (file != null)
file.delete();
String fileName = JOptionPane
.showInputDialog("Please input the name of you file: ");
if (fileName != null) {
if (fileName.trim().equals("")) {
JFrame frame = new JFrame(
"JOptionPane showMessageDialog example");
JOptionPane.showMessageDialog(frame,
"File Name must have some value", "Warning Message",
JOptionPane.WARNING_MESSAGE);
} else {
Connection conn = DBConnectionHandler.getConnection();
PreparedStatement pstmt;
try {
pstmt = conn
.prepareStatement("insert into FILEDATA(PR_KEY, FILENAME, FILEDATA) values (seq_file.nextval,?, EMPTY_BLOB())");
pstmt.setString(1, fileName + ".docx");
pstmt.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
static void fileOpen() {
List<String> FileName = new ArrayList<String>();
try {
Connection conn = DBConnectionHandler.getConnection();
Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery("select FILENAME from FILEDATA");
while (rset.next())
FileName.add(rset.getString(1));
System.out.println("List Size "+FileName.size());
if (clientSite != null)
clientSite.dispose();
shell.setVisible(false);
if (file != null)
file.delete();
SWTMenuExample swtClass = new SWTMenuExample();
NewJFrame form = new NewJFrame(FileName, clientSite, shell, frame,
swtClass);
form.setVisible(true);
form.setSize(400, 400);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*
* FileDialog dialog = new FileDialog(shell, SWT.OPEN);
* dialog.setFilterExtensions(new String[] { "*.docx" }); String
* fileName = dialog.open(); if (fileName != null) { if (clientSite !=
* null) clientSite.dispose(); file = new File(fileName); clientSite =
* new OleClientSite(frame, SWT.NONE, "Word.Document", file);
* clientSite.addKeyListener(keyListener);
* clientSite.doVerb(OLE.OLEIVERB_INPLACEACTIVATE); }
*/
}
void fileOpenFromDrive(File happyFile) {
file = happyFile;
display.asyncExec(new Runnable() {
#Override
public void run() {
shell.setVisible(true);
if (clientSite != null)
clientSite.dispose();
clientSite = new OleClientSite(frame, SWT.NONE,
"Word.Document", file);
clientSite.addKeyListener(keyListener);
clientSite.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);
shell.addListener(SWT.Close, new Listener() {
public void handleEvent(Event event) {
if (file != null)
file.delete();
shell.dispose();
}
});
}
});
}
static void fileSave() {
try {
FileInputStream fis = new FileInputStream(file);
Connection conn = DBConnectionHandler.getConnection();
PreparedStatement pstmt = conn
.prepareStatement("update FILEDATA set FILEDATA = ? where FILENAME = ?");
pstmt.setBinaryStream(1, fis, (int) file.length());
pstmt.setString(2, file.getName());
pstmt.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
It will open docx as like in the following picture :
As others have pointed out, this sounds a lot like an XY problem—meaning, you have already decided that the best solution is using Microsoft Word, so you are asking how to embed Microsoft Word instead of asking about your actual goal, which appears to be incorporating formatted text in a user interface.
A good way to do this is with a JEditorPane containing HTML content:
import java.awt.EventQueue;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
public class HtmlPane {
static void show() {
JEditorPane content = new JEditorPane("text/html",
"<p>" +
"The process of finger enrollment is now to be done in database." +
" Previously it was done in file template." +
" There are several reasons behind this:" +
"<ol>" +
"<li>" +
"Time:<br>" +
"--------" +
"<p>" +
"The process of verification in file template based method takes" +
" 6.9 s on average. On the other hand, in database based method," +
" it takes only 3.5 s." +
"<p>" +
"The code for determining time is as follows:" +
"<blockquote>" +
"<pre>" +
"Dim StartTime, Elapsed Time\n" +
"StartTime = Timer\n" +
"ElapsedTime = Timer.CheckTime\n" +
"</pre>" +
"</blockquote>" +
"</ol>");
content.setEditable(false);
JFrame frame = new JFrame("finger");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new JScrollPane(content));
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> show());
}
}
(Note: The Swing HTML renderer only supports HTML 3.2.)
If you aren’t familiar with HTML, I advise you to learn it. Basic HTML is very easy to write. Plus, you need to know basic HTML to be an effective Java programmer, because professional development requires writing javadoc, and all javadoc is in HTML.
Actaully, you can't show any not-your-project-frames in your java gui application, it is actaully unreal - you can only show java frames in JInternalFrame

.zip file isn't deleted but neither throw any exception

I've created an app with utilities I usually use on my pc (like sending shutdown to cmd.exe) and as some friends asked me to give it to them I was trying to add an update system that checks for updates on a server to make it easier that their version is always updated.
The thing is that I've been over the net searching any solution but all of them just tell to use .close() and my file has it right after stop needing it. When I run it everything works fine and there are no exceptions thrown, so I just dunno what can be wrong.
Whole class:
public class Main_Gui extends JFrame {
private Thread worker;
private final String root = "update/";
private JTextArea outText;
private JButton cancel;
private JButton launch;
private JScrollPane sp;
private JPanel pan1;
private JPanel pan2;
private String zipFile = "Actualización.zip";
private String path = "http://ritsu.hol.es/url.html";
private String TITLE = "RitsUtilities | Actualizador";
public Main_Gui() {
initComponents();
outText.setText("Conectando con el servidor...");
download();
}
private void initComponents() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
setTitle(TITLE);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
pan1 = new JPanel();
pan1.setLayout(new BorderLayout());
pan2 = new JPanel();
pan2.setLayout(new FlowLayout());
outText = new JTextArea();
sp = new JScrollPane();
sp.setViewportView(outText);
launch = new JButton("Ejecutar RitsUtilities");
launch.setEnabled(false);
launch.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String[] run = { "java", "-jar", "RitsUtilities.jar" };
try {
Runtime.getRuntime().exec(run);
} catch (Exception ex) {
ex.printStackTrace();
}
System.exit(0);
launch();
}
});
pan2.add(launch);
cancel = new JButton("Salir");
cancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
pan2.add(cancel);
pan1.add(sp, BorderLayout.CENTER);
pan1.add(pan2, BorderLayout.SOUTH);
add(pan1);
pack();
setSize(500, 400);
setLocationRelativeTo(null);
}
private void download() {
worker = new Thread(new Runnable() {
public void run() {
try {
downloadFile(getDownloadLinkFromHost());
unzip();
copyFiles(new File(root), new File("").getAbsolutePath());
cleanup();
launch.setEnabled(true);
outText.setText(outText.getText() + "\n¡Actualización completada con éxito!");
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "Ha ocurrido un error al descargar y descomprimir la actualización.", "Error 1", JOptionPane.WARNING_MESSAGE);
}
}
});
worker.start();
}
private void launch() {
String[] run = { "java", "-jar", "update app.jar" };
try {
Runtime.getRuntime().exec(run);
} catch (Exception ex) {
ex.printStackTrace();
}
System.exit(0);
}
private void cleanup() {
outText.setText(outText.getText() + "\nLimpiando archivos temporales...");
remove(new File(root));
new File(root).delete();
}
private void remove(File f) {
File[] files = f.listFiles();
for (File ff : files) {
if (ff.isDirectory()) {
remove(ff);
ff.delete();
} else {
ff.delete();
}
}
}
private void copyFiles(File f, String dir) throws IOException {
File[] files = f.listFiles();
for (File ff : files) {
if (ff.isDirectory()) {
new File(dir + "/" + ff.getName()).mkdir();
copyFiles(ff, dir + "/" + ff.getName());
} else {
copy(ff.getAbsolutePath(), dir + "/" + ff.getName());
}
}
}
public void copy(String srFile, String dtFile) throws FileNotFoundException, IOException {
File f1 = new File(srFile);
File f2 = new File(dtFile);
InputStream in = new FileInputStream(f1);
OutputStream out = new FileOutputStream(f2);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
private void unzip() throws IOException {
int BUFFER = 2048;
BufferedOutputStream dest = null;
BufferedInputStream is = null;
ZipEntry entry;
ZipFile zipfile = new ZipFile(zipFile);
Enumeration e = zipfile.entries();
(new File(root)).mkdir();
while (e.hasMoreElements()) {
entry = (ZipEntry) e.nextElement();
outText.setText(outText.getText() + "\nExtrayendo: " + entry);
if (entry.isDirectory())
(new File(root + entry.getName())).mkdir();
else {
(new File(root + entry.getName())).createNewFile();
is = new BufferedInputStream(zipfile.getInputStream(entry));
int count;
byte data[] = new byte[BUFFER];
FileOutputStream fos = new FileOutputStream(root + entry.getName());
dest = new BufferedOutputStream(fos, BUFFER);
while ((count = is.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, count);
}
dest.flush();
dest.close();
is.close();
}
}
}
private void downloadFile(String link) throws MalformedURLException, IOException {
URL url = new URL(link);
URLConnection conn = url.openConnection();
InputStream is = conn.getInputStream();
long max = conn.getContentLength();
outText.setText(outText.getText() + "\n" + "Descargando archivo...\nTamaño de la actualización(comprimida): " + max + " Bytes");
BufferedOutputStream fOut = new BufferedOutputStream(new FileOutputStream(new File(zipFile)));
byte[] buffer = new byte[32 * 1024];
int bytesRead = 0;
int in = 0;
while ((bytesRead = is.read(buffer)) != -1) {
in += bytesRead;
fOut.write(buffer, 0, bytesRead);
}
fOut.flush();
fOut.close();
is.close();
outText.setText(outText.getText() + "\n¡Descarga completada!");
}
private String getDownloadLinkFromHost() throws MalformedURLException, IOException {
URL url = new URL(path);
InputStream html = null;
html = url.openStream();
int c = 0;
StringBuilder buffer = new StringBuilder("");
while (c != -1) {
c = html.read();
buffer.append((char) c);
}
return buffer.substring(buffer.indexOf("[url]") + 5, buffer.indexOf("[/url]"));
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Main_Gui().setVisible(true);
}
});
}
}
EDIT: changed private String zipFile = "Actualización.zip"; to private String zipFile = "Update.zip"; but still just deleting temp files/directories but not that "Update.zip" folder that the app downloads.
The File#delete() method you are using doesn't throw an error if the file can't be deleted, it returns false. This is documented in the Javadoc, together with an alternative solution (emphasize mine):
Deletes the file or directory denoted by this abstract pathname. If this pathname denotes a directory, then the directory must be empty in order to be deleted.
Note that the Files class defines the delete method to throw an IOException when a file cannot be deleted. This is useful for error reporting and to diagnose why a file cannot be deleted.
Finally it's working, just added a forced delete on run() inside download() so now my code looks like
public void run() {
try {
downloadFile(getDownloadLinkFromHost());
unzip();
copyFiles(new File(root), new File("").getAbsolutePath());
cleanup();
launch.setEnabled(true);
+ System.gc();
+ File tmpf = new File(zipFile);
+ tmpf.deleteOnExit();
outText.setText(outText.getText() + "\n¡Actualización completada con éxito!");
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "Ha ocurrido un error al descargar y descomprimir la actualización.", "Error 1", JOptionPane.WARNING_MESSAGE);
}
}
I'm pretty sure that there are way better ways to do this, but that one seems to work for me.
Thanks to everyone that answered and tried to help me. =D
I would suggest improving your remove(File f) method. Add some checks for the Boolean return value of ff.delete(), that will tell you if the file is actually being deleted or not.
Also, you could add some logs into that method, so you could debug what is actually doing, perhaps it's not seeing the files or something.
One last comment. You should make your code more modular. Create more abstractions and give each of them a simple task. That is the essence of Object Oriented Design. Then, you can program some JUnit tests for each object, and you can run the tests every time you make a change. I reccomend you give a look to this article on Cohesion

Downloading file/files in Java. Multithreading, this works?

First, everyone needs to know i'm relatively new to Java coding. To be more precise i'm completely new to Object Oriented Programming.
To the question.
I am trying to create a download class that updates a progress bar it was given to show its progress. And possibly anything else I decide to give it in the future to update.
The issue currently is that, in my head, this shouldn't work. I can do anything i want on the "main" method and the GUI is still responsive and quick. In my experience in past programming, this is not possible unless i thread the GUI. Why is this?
Since it works, is this ok to do it this way?
Class Main
package atomicElectronics;
import java.io.IOException;
import atomicElectronics.physical.AtomFrame;
import atomicElectronics.utility.Download;
public class Initial {
static AtomFrame atomLauncher;
public static void main(String[] args) {
atomLauncher = new AtomFrame();
atomLauncher.start();
System.out.println(Integer.MAX_VALUE);
Download theDownload = new Download();
theDownload.fileProgressBar(atomLauncher.progressBar);
try {
theDownload.exicute("http://download.videolan.org/pub/videolan/vlc/last/win64/vlc-2.1.3-win64.exe", "C:\\Users\\TrinaryAtom\\AppData\\Roaming");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// TODO Add Download Methods
// theDownload.updateBarTotal(JProgressBar);
// theDownload.updateLabelSpeed(String);
// theDownload.updateLabelTotal(String);
// theDownload.addFile(File);
// theDownload.addFiles(Files);
}
}
Class AtomFrame
package atomicElectronics.physical;
import javax.swing.JFrame;
import java.awt.FlowLayout;
import javax.swing.JProgressBar;
public class AtomFrame extends JFrame{
public JProgressBar progressBar;
private static final long serialVersionUID = 4010489530693307355L;
public static void main(String[] args){
AtomFrame testFrame = new AtomFrame();
testFrame.start();
}
public AtomFrame(){
initializeComponents();
}
public void initializeComponents(){
this.setSize(400, 400);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("Atom Launcher");
this.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
progressBar = new JProgressBar();
this.add(progressBar);
//this.pack();
}
public void start() {
this.setVisible(true);
}
public void close() {
this.dispose();
}
}
Class Download
package atomicElectronics.utility;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.swing.JProgressBar;
public class Download {
private static final int BUFFER_SIZE = 4096;
private JProgressBar fileProgressBar;
public Download() {
}
public void fileProgressBar(JProgressBar fileBar) {
fileProgressBar = fileBar;
}
public void exicute(String fileURL, String saveDir) throws IOException {
URL url = new URL(fileURL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
int responseCode = httpConn.getResponseCode();
// always check HTTP response code first
if (responseCode == HttpURLConnection.HTTP_OK) {
String fileName = "";
String disposition = httpConn.getHeaderField("Content-Disposition");
String contentType = httpConn.getContentType();
double contentLength = httpConn.getContentLength();
if (disposition != null) {
// extracts file name from header field
int index = disposition.indexOf("filename=");
if (index > 0) {
fileName = disposition.substring(index + 9,
disposition.length());
}
} else {
// extracts file name from URL
fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1,
fileURL.length());
}
System.out.println("Content-Type = " + contentType);
System.out.println("Content-Disposition = " + disposition);
System.out.println("Content-Length = " + contentLength);
System.out.println("fileName = " + fileName);
// opens input stream from the HTTP connection
InputStream inputStream = httpConn.getInputStream();
String saveFilePath = saveDir + File.separator + fileName;
// opens an output stream to save into file
FileOutputStream outputStream = new FileOutputStream(saveFilePath);
double totalRead = 0;
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
totalRead += bytesRead;
System.out.println((totalRead / contentLength) * 100);
fileProgressBar.setValue((int)((totalRead / contentLength) * 100));
}
outputStream.close();
inputStream.close();
System.out.println("File downloaded");
} else {
System.out.println("No file to download. Server replied HTTP code: " + responseCode);
}
httpConn.disconnect();
}
}
Suggestions:
Use a SwingWorker to do your background thread work.
Inside your SwingWorker, set its progress "bound" property via setProgress(int progress). The value should be between 1 and 100.
Don't have your SwingWorker/file downloader hold the JProgressBar or any Swing components.
Add a PropertyChangeListener to your SwingWorker and monitor changes in the progress property.
Never make your Swing fields (or most and and all fields) public. Limit access, and instead change object state via methods.
Read the tutorial Concurrency in Swing for the necessary details.
For example, the code below is a gross simplification and downloads no files, but should give you the idea:
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Random;
import javax.swing.*;
public class Initial {
static AtomFrame atomLauncher;
public static void main(String[] args) {
atomLauncher = new AtomFrame();
atomLauncher.start();
System.out.println(Integer.MAX_VALUE);
final Download theDownload = new Download();
theDownload.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent pcEvt) {
if ("progress".equals(pcEvt.getPropertyName())) {
int progress = theDownload.getProgress();
atomLauncher.setProgress(progress);
}
}
});
theDownload.execute();
}
}
class AtomFrame extends JFrame {
// ********* should be private!
private JProgressBar progressBar;
private static final long serialVersionUID = 4010489530693307355L;
public static void main(String[] args) {
AtomFrame testFrame = new AtomFrame();
testFrame.start();
}
public void setProgress(int progress) {
progressBar.setValue(progress);
}
public AtomFrame() {
initializeComponents();
}
public void initializeComponents() {
this.setSize(400, 400);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("Atom Launcher");
this.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
progressBar = new JProgressBar();
this.add(progressBar);
// this.pack();
}
public void start() {
this.setVisible(true);
}
public void close() {
this.dispose();
}
}
class Download extends SwingWorker<Void, Void> {
private static final long SLEEP_TIME = 300;
private Random random = new Random();
#Override
protected Void doInBackground() throws Exception {
int myProgress = 0;
while (myProgress < 100) {
myProgress += random.nextInt(10);
setProgress(myProgress);
try {
Thread.sleep(SLEEP_TIME);
} catch (InterruptedException e) {}
}
return null;
}
}

How to display shell command output on a jtextarea in java?

How to display shell command output on a jtextarea in java?
Kindly help
Thanks
You can get shell command output below snippet code, set jtextarea on while loop.
try {
String cmd = "java"; // Set shell command
Process child = Runtime.getRuntime().exec(cmd);
InputStream lsOut = child.getInputStream();
InputStreamReader r = new InputStreamReader(lsOut);
BufferedReader in = new BufferedReader(r);
// read the child process' output
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
// You should set JtextArea
}
} catch (Exception e) { // exception thrown
System.err.println("Command failed!");
}
You need to read the standard output as the process input stream and update the JTextArea using the event queue from another thread. See the example code below:
public class OutputDisplayer implements Runnable {
protected final JTextArea textArea_;
protected Reader reader_ = null;
public OutputDisplayer(JTextArea textArea) {
textArea_ = textArea;
}
public void commence(Process proc) {
InputStream in = proc.getInputStream();
reader_ = new InputStreamReader(in);
Thread thread = new Thread(this);
thread.start();
}
public void run() {
StringBuilder buf = new StringBuilder();
try {
while( reader_ != null ) {
int c = reader_.read();
if( c==-1 ) return;
buf.append((char) c);
setText( buf.toString() );
}
} catch ( IOException ioe ) {
buf.append("\n\nERROR:\n"+ioe.toString());
setText( buf.toString() );
} finally {
try {
reader_.close();
} catch ( IOException ioe ) {
ioe.printStackTrace();
}
}
}
private void setText(final String text) {
EventQueue.invokeLater(new Runnable() {
public void run() {
textArea_.setText(text);
}
});
}
}
In addition to my two links in my comments above, I created and used a TextAreaOutputStream that helps to redirect output stream data to a textarea:
import java.io.IOException;
import java.io.OutputStream;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class TextAreaOutputStream extends OutputStream {
private final JTextArea textArea;
private final StringBuilder sb = new StringBuilder();
private String title;
public TextAreaOutputStream(final JTextArea textArea, String title) {
this.textArea = textArea;
this.title = title;
sb.append(title + "> ");
}
#Override
public void flush() {
}
#Override
public void close() {
}
#Override
public void write(int b) throws IOException {
if (b == '\r')
return;
if (b == '\n') {
final String text = sb.toString() + "\n";
SwingUtilities.invokeLater(new Runnable() {
public void run() {
textArea.append(text);
}
});
sb.setLength(0);
sb.append(title + "> ");
}
sb.append((char) b);
}
}
import java.io.OutputStream;
import javax.swing.JTextArea;
/**
* This class extends from OutputStream to redirect output to a JTextArrea
* #author www.codejava.net
*
*/
public class CustomOutputStream extends OutputStream {
private JTextArea textArea;
public CustomOutputStream(JTextArea textArea) {
this.textArea = textArea;
}
#Override
public void write(int b) throws IOException {
// redirects data to the text area
textArea.append(String.valueOf((char)b));
// scrolls the text area to the end of data
textArea.setCaretPosition(textArea.getDocument().getLength());
}
}
/*
* 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.
*/
package guiconsoleoutput;
/**
*
* #author root
*/
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
public class TextAreaLogProgram extends JFrame {
/**
* The text area which is used for displaying logging information.
*/
private JTextArea textArea;
private JButton buttonStart = new JButton("Start");
private JButton buttonClear = new JButton("Clear");
private PrintStream standardOut;
public TextAreaLogProgram() {
super(" CONSOLE ");
textArea = new JTextArea(50, 10);
textArea.setEditable(false);
PrintStream printStream = new PrintStream(new CustomOutputStream(textArea));
// keeps reference of standard output stream
standardOut = System.out;
// re-assigns standard output stream and error output stream
System.setOut(printStream);
System.setErr(printStream);
// creates the GUI
setLayout(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.gridy = 0;
constraints.insets = new Insets(10, 10, 10, 10);
constraints.anchor = GridBagConstraints.WEST;
add(buttonStart, constraints);
constraints.gridx = 1;
add(buttonClear, constraints);
constraints.gridx = 0;
constraints.gridy = 1;
constraints.gridwidth = 2;
constraints.fill = GridBagConstraints.BOTH;
constraints.weightx = 1.0;
constraints.weighty = 1.0;
add(new JScrollPane(textArea), constraints);
// adds event handler for button Start
buttonStart.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
printLog();
}
});
// adds event handler for button Clear
buttonClear.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
// clears the text area
try {
textArea.getDocument().remove(0,
textArea.getDocument().getLength());
standardOut.println("Text area cleared");
} catch (BadLocationException ex) {
ex.printStackTrace();
}
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(480, 320);
setLocationRelativeTo(null); // centers on screen
}
/**
* Prints log statements for testing in a thread
*/
private void printLog() {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Time now is " + (new Date()));
System.out.println("lol ");
String s = null;
/*try {
// run the Unix "ps -ef" command
// using the Runtime exec method:
Process p = Runtime.getRuntime().exec("dir");
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
System.exit(0);
}
catch (IOException e) {
System.out.println("exception happened - here's what I know: ");
e.printStackTrace();
System.exit(-1);
}*/
try {
String cmd = "cmd /c ping 8.8.8.8"; // Set shell command
Process child = Runtime.getRuntime().exec(cmd);
InputStream lsOut = child.getInputStream();
InputStreamReader r = new InputStreamReader(lsOut);
BufferedReader in = new BufferedReader(r);
// read the child process' output
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
// You should set JtextArea
}
} catch (Exception e) { // exception thrown
System.err.println("Command failed!");
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
});
thread.start();
}
/**
* Runs the program
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TextAreaLogProgram().setVisible(true);
}
});
}
}

Categories