Enclose try-catch in a public method and invoke when needed - java

How to enclose try-catch in a public method and invoke when needed.
I have try-catch in one screen code. I want to invoke it from another screen by calling a method to it that stands public(to the entire application).
Is it possible ? If so how.
Please guide.
Re edits:
As seen in the below code, second tab pane implementation has been shown,please ignore the syntactic differences one may find with native java(This has been implemented for Blackberry JDE). Implementation constructs remain the same hence please overlook the differences and suggest a logical solution to the problem being faced.
// setup the second tab
vfm = new VerticalFieldManager(
Field.USE_ALL_HEIGHT | Field.USE_ALL_WIDTH |
Manager.VERTICAL_SCROLL | Manager.NO_HORIZONTAL_SCROLL );
//Initialize grid for publishing results
grid.add(new LabelField("Name")
{
public void paint(Graphics graphics)
{
graphics.setColor(Color.CYAN);
super.paint(graphics);
}
});
grid.add(new LabelField("Total")
{
public void paint(Graphics graphics)
{
graphics.setColor(Color.CYAN);
super.paint(graphics);
}
});
grid.setColumnPadding(100);
grid.setRowPadding(20);
//TRY CATCH STARTS HERE
try
{
//Open or create the database
Database db = DatabaseFactory.openOrCreate("database1.db");
Statement statementG55 = db.createStatement("CREATE TABLE IF NOT EXISTS GTemp4(gname TEXT,gbal INTEGER)");
statementG55.prepare();
statementG55.execute();
statementG55.close();
Statement statementG56 = db.createStatement("SELECT gname,gbal FROM GTemp4 ORDER BY ROWID DESC");
statementG56.prepare();
statementG56.execute();
Cursor c = statementG56.getCursor();
//Get to the row of grid
for (int i =1; i < grid.getRowCount(); i++)
{
System.out.println("Inside for first loops");
//Get to the column of grid
for (int j = 0; j < grid.getColumnCount() ; j++)
{
System.out.println("Inside for second loops");
//Get to the row of temp4 table
while(c.next())
{
System.out.println("Inside while");
Row r;
r = c.getRow();
for (int k = 1; k >=0; k--)
{
System.out.println("Inside for loops");
if(k==0)
{
System.out.println("Retrieving Names");
grid.insert(new LabelField(r.getString(k))
{
public void paint(Graphics graphics)
{
graphics.setColor(Color.GOLD);
super.paint(graphics);
}
},i,j);
}
else
{
System.out.println("Retrieving other values");
String p = "" + r.getObject(k);
grid.insert(new LabelField(p)
{
public void paint(Graphics graphics)
{
graphics.setColor(Color.GOLD);
super.paint(graphics);
}
},i,j);
}
grid.setBackground(BackgroundFactory.createLinearGradientBackground(Color.MIDNIGHTBLUE,Color.STEELBLUE,Color.MIDNIGHTBLUE,Color.STEELBLUE));
}
System.out.println("Exiting while");
}
System.out.println("Exiting sec for");
break;
}
System.out.println("Exiting first for");
break;
}
statementG56.close();
db.close();
}
catch(Exception e)
{
System.out.println( e.getMessage() );
e.printStackTrace();
}
vfm.add(grid);
nullFld = new NullField( Field.FOCUSABLE );
hfm = new HorizontalFieldManager();
hfm.add( nullFld );
hfm.add( myLbl );
pane = new Pane( hfm, vfm );
model.addPane( pane );
A big thanks to everyone below who have made a suggestion.

Your question is still cryptic. I am assuming that you have some code which does some searching and then, it publishes the results to some JPanel called pane2. What you want is that once the Search button is pressed, you call the code.
You could have a method like so:
public void doSomeSearching(...) throws Exception //This will allow you to remove the try/catch block from within the method and be able to catch any exceptions in the layer above.
{
//Do the searching
//Update panel2
}
Then, what you need to do is to add an action listener to your button. This will allow the code to be executed once the button is clicked. (You can find more information on ActionListeners here).
JButton btnSearch = new JButton("Search");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e)
{
try
{
doSomeSearching();
}
catch (Exception e)
{
//Do something when exception is raised.
}
}
});
This should allow you to trigger the search functionality when you click the button and handle any exceptions which should arise.
EDIT:
another try-catch included within pane2 to publish(It keeps running from the start,i.e,doesnt wait for action listener of search button to be executed)`
Having something loop indefinitely is something which should be ideally avoided since this consumes CPU cycles while basically doing nothing. This usually increases the resources your application consumes and might also cause your GUI to hang. If I where you I would have some method which updates panel2 which you than call once you have done your searching.
That being said, you could have some intermediary variable, such as a string which contains whatever you need to print and your search method continuously updates this intermediary variable.

This approach is not recommended.
Instead of placing a generic surrounding try-catch block around your method, you should consider adding the "throws" clause to the declaration of each method you want to handle this way, and then handle all those exception in a higher layer.

Related

Do I use a SwingWorker?

While my code sends http calls I want it to alter the JLabel on a window (basically showing approximately how much time is left before the http calls end). I have been looking into SwingWorkers due to another question I asked here, but I'm not sure how I use it. The code I am writing basically has a loop to send the calls, each time timing how long it takes to run the call, calculates the approximate time left and then sends this to the JLabel (NB the JLabel is in a different instantiated object).
Most SwingWorker examples show a function continuing in the background that is not affected by the worker thread (e.g. a counter based entirely on time rather than being altered by the code). If this is the case then isn't the alteration of the JLabel just part of the worker thread as it the code runs through new loop -> calculate time & make call -> alter JLabel? I'm probably wrong but then how do I have the JLabel altered by the code rather than a independent thread?
One of my issues was that when I initially set my code up there was nothing changing in the JLabel.
Here is my code:
package transcription.windows;
import javax.swing.*;
import java.awt.*;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
public class PleaseWaitWindow {
private JLabel pleaseWaitJLabel = new JLabel("Please wait");
private GridBagConstraints containerGbc = new GridBagConstraints();
private Container contentPaneContainer = new Container();
private JFrame pleaseWaitJFrame;
public JLabel getPleaseWaitJLabel() {
return pleaseWaitJLabel;
}
public JFrame setPleaseWaitWindow() {
pleaseWaitJFrame = new JFrame();
contentPaneContainer = setContentPane();
pleaseWaitJFrame.setContentPane(contentPaneContainer);
pleaseWaitJFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
pleaseWaitJFrame.setTitle("");
pleaseWaitJFrame.setSize(350, 150);
pleaseWaitJFrame.setLocationRelativeTo(null);
pleaseWaitJFrame.setVisible(true);
return pleaseWaitJFrame;
}
private Container setContentPane() {
containerGbc.insets.bottom = 1;
containerGbc.insets.top = 2;
containerGbc.insets.right = 1;
containerGbc.insets.left = 1;
containerGbc.weightx = 1;
containerGbc.weighty = 1;
contentPaneContainer.setLayout(new GridBagLayout());
contentPaneContainer.setSize(800, 700);
setPleaseWaitJLabel();
return contentPaneContainer;
}
private void setPleaseWaitJLabel() {
containerGbc.gridx = 2;
containerGbc.gridy = 5;
containerGbc.gridwidth = 2;
containerGbc.gridheight = 1;
contentPaneContainer.add(pleaseWaitJLabel, containerGbc);
}
public void setJLabelDisplay(String displayTime) {
pleaseWaitJLabel.setText(displayTime);
}
public void closeWindow() {
pleaseWaitJFrame.dispose();
}
}
Method that is part of the ServiceUpload class:
public String cuttingLoop(String mpBase64Piece, String jobName, String email) {
Integer numberOfPiecesMinusEnd = (int) Math.ceil(mpBase64Piece.length() / 500000.0);
List<String> base64List = new ArrayList<>();
for (int i = 0; i < numberOfPiecesMinusEnd; i++) {
if (mpBase64Piece.length() >= 500000) {
base64List.add(mpBase64Piece.substring(0, 500000));
mpBase64Piece = mpBase64Piece.substring(500000);
}
}
base64List.add(mpBase64Piece);
pleaseWaitWindow = new PleaseWaitWindow();
pleaseWaitWindow.setPleaseWaitWindow();
for (int n = 0; n < base64List.size(); n++) {
numberOfLoopsLeft = numberOfPiecesMinusEnd - n;
Stopwatch stopwatch = null;
String tag;
Stopwatch.createStarted();
if (base64List.get(n) != null) {
if (n == 0) {
tag = "start";
} else if (n == base64List.size() - 1) {
tag = "end";
} else {
tag = "middle";
}
stopwatch = Stopwatch.createStarted();
response = providerUpload.executeUploadHttp(base64List.get(n), jobName, tag, email);
stopwatch.stop();
}
long oneLoopTime = stopwatch.elapsed(TimeUnit.SECONDS);
pleaseWaitWindow.setJLabelDisplay(numberOfLoopsLeft*oneLoopTime+" seconds remaining");
LOGGER.info("complete");
}
pleaseWaitWindow.closeWindow();
return response;
}
One of my issues was the code did not show the 'JLabel' when a 'SwingWorker' isn't used with the above code.
It's best you split up your code into areas of responsibilities. Let's go with three: 1. the worker (ie the upload); 2. the display (ie the JLabel update); 3. integration of the two (the first two are independent of each other, so you'll need something to tie them together).
Abstracting from the actual work, you can use standard interfaces. The first one is just a Runnable, ie not taking any parameters and not returning anything. The second one is a Consumer<String> because it takes a String (to display) but doesn't return anything. The third will be your main control.
Let's start with the control because that's simple:
Consumer<String> display = createDisplay();
Runnable worker = createWorker();
CompletableFuture.runAsync(worker);
This will start the worker in a separate Thread which is what it sounds like you want.
So here's your uploader:
Consumer<String> display = // tbd, see below
Runnable worker = () -> {
String[] progress = {"start", "middle", "finish"};
for (String pr : progress) {
display.accept(pr);
Thread.sleep(1000); // insert your code here
}
}
Note that this worker actually does depend on the consumer; that is somewhat "unclean", but will do.
Now for the display. Having defined it as a Consumer<String>, it's abstract enough that we can just print the progress on the console.
Consumer<String> display = s -> System.out.printf("upload status: %s%n", s);
You however want to update a JLabel; so the consumer would look like
Consumer<String> display = s -> label.setText(s);
// for your code
s -> pleaseWaitWindow.getPleaseWaitLabel().setText(s);
Your actual question
So if you do that, you will notice that your label text doesn't get updated as you expect. That is because the label.setText(s) gets executed in the thread in which the worker is running; it needs to be inserted in the Swing thread. That's where the SwingWorker comes in.
The SwingWorker has a progress field which is what you can use for your labels; it also has a doInBackground() which is your actual upload worker thread. So you end up with
class UploadSwingWorker {
public void doInBackground() {
for(int i = 0; i < 3; i++) {
setProgress(i);
Thread.sleep(1000); // again, your upload code
}
}
}
So how does that update your label? The setProgress raises a PropertyChangeEvent you can intercept; this done using a PropertyChangeListener with the signature
void propertyChange(PropertyChangeEvent e)
This is a functional interface, so you can implement this with a lambda, in your case
String[] displays = {"start", "middle", "finish"};
updateLabelListener = e -> {
int index = ((Integer) e.getNewValue()).intValue(); // the progress you set
String value = displays[index];
label.setText(value);
}
and you can add it to the SwingWorker using
SwingWorker uploadWorker = new UploadSwingWorker();
uploadWorker.addPropertyChangeListener(updateLabelListener);
uploadWorker.execute(); // actually start the worker
Simpler
Note that I myself have never used a SwingWorker this way. The much simpler way to get around the problem that the GUI is not updated from within your worker thread is to call the GUI update using SwingUtilities.invokeLater().
Coming back to the initial Consumer<String> I brought up, you can do
Consumer<String> display = s -> SwingUtilities.invokeLater(
() -> pleaseWaitWindow.getPleaseWaitLabel().setText(s)
);
and that should do. This allows you to keep your worker in the more abstract Runnable and use the usual scheduling mechanisms to run it (ExecutorService.submit() or CompletableFuture.runAsync() for example), while still allowing to update the GUI on a similarly simple level.

Boolean expression should be evaluated at runtime in a timer, reacting to changes in the swing gui

Here is what I am trying to do: I have a swing gui with two JFrames. The first has a JCheckBox and the second displays some text. Also the second has a javax.swing.Timer that is waiting for the checkbox in the first frame to be clicked. Once it is clicked, some more text is to be displayed. It works if I have only one condition (click the checkbox) and the condition is directly in the if-statement, like this:
javax.swing.Timer timer = new javax.swing.Timer(100, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if ( otherGUI.jCheckBox.isSelected() ){
//add some text to second JFrame
timer.stop();
}
}
});
Now for the twist: This should happen not only once, but multiple times. There is an ArrayList of timers, each with its own text and condition, one starting after the other. My problem is: If I store the conditions as strings in an ArrayList, they seem to be evaluated once at the start of the programme, so the condition from above stays false, even when I click the checkbox. Here is my actual code:
SomeGUI gui = new SomeGUI();
ArrayList<javax.swing.Timer> timer = new ArrayList<javax.swing.Timer>();
ArrayList<String> text = new ArrayList<String>();
ArrayList<String> cond = new ArrayList<String>();
text.add("some text");
cond.add("gui.jCheckBox.isSelected()");
text.add("some more text");
cond.add(new Condition("true"));
//etc.
for ( int i = 0; i < text.size() - 1; i++ ){
int j = i;//not sure why this trick is necessary. i doesn't work later on
timer.add( new javax.swing.Timer(100, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
boolean bool = false;
try{
bool = Boolean.parseBoolean( cond.get(j) );
}
catch(Exception ex){}
if ( bool ){
addText(p, text.get(j+1));
timer.get(j).stop();
timer.get(j+1).start();
}
}
}));
}
timer.get(0).start();
I already tried an ArrayList<Boolean> for the conditions to the same effect. The code above just represents my present state of trial and error.
I hope that I could make clear what I am trying to achieve. So how can I store boolean expressions in a list/array and have them evaluated in an if-statement again and again at runtime and not only once when the programme is started?
There is no simple "evaluation" of strings in Java. It is possible, but really not "java style". See Convert String to Code
One other option would be that your strings represent method names (which exist on a well known object); then you could use reflection to invoke that method based on the provided string. But also, pretty ugly.

Get text from JRadioButton that isn't part of a ButtonGroup

My program is a GUI. I have this method where when a button is clicked. It populates the next screen with JRadioButtons dynamically.
private void setExamButtonActionPerformed(java.awt.event.ActionEvent evt)
{
if(evt.getActionCommand().equals("Set Exam"))
{
CardLayout cL = (CardLayout)cardPanels.getLayout();
cL.show(cardPanels, "setExamPanel");
}
try
{
//InputStream code
String theMessage = myObject.getMessage();
String delims = "(?=(0*([0-9]{1,2}|100)))";
String[] questions = theMessage.split(delims);
System.out.println(Arrays.toString(questions));
for (int j = 1; j < questions.length; j++)
{
settingQuestionBoxes = new JCheckBox(questions[j]);
settingQuestionTextField = new JTextField("");
jPanel1.add(settingQuestionBoxes);
jPanel1.add(settingQuestionTextField);
jPanel1.revalidate();
jPanel1.repaint();
}
//close streams and socket code
}
catch(Exception e)
{
System.out.println(e);
}
}
Then I have this other method from another screen where the data that is populated from the previous method goes to.
private void setExamQuestionButtonActionPerformed(java.awt.event.ActionEvent evt)
{
if(evt.getActionCommand().equals("Set Exam Question"))
{
ArrayList<JToggleButton> settingQuestionBoxes = new ArrayList<JToggleButton>();
for(JToggleButton questions: settingQuestionBoxes)
{
if(questions.isSelected())
{
System.out.println(questions.getActionCommand());
}
}
CardLayout cL = (CardLayout)cardPanels.getLayout();
cL.show(cardPanels, "instructorPanel");
}
}
So basically when i call this System.out.println(questions.getActionCommand()) I'm trying to see the text from the JRadiobutton that was clicked on.
Right now when I run the program and select a button. Nothing happens.
Put the buttons into a List<JToggleButton> such as an ArrayList<JToggleButton> and then iterate through the list when the information is needed.
for (JToggleButton btn : myButtonList) {
if (btn.isSelected() {
String actionCommand = btn.getActionCommand();
// use the actionCommand here
}
}
Note that JToggleButton is the parent class for JRadioButton and using it would allow you to add JRadioButtons, JCheckBoxes, and JToggleButtons to the list. Since your JRadioButton is not part of a ButtonGroup, perhaps you should be using a JCheckBox instead.
Edit
You now have posted this code, stating it doesn't work:
// Section (A)
ArrayList<JToggleButton> settingQuestionButton = new ArrayList<JToggleButton>();
// Section (B)
for(JToggleButton questions: settingQuestionButon)
{
if(questions.isSelected())
{
System.out.println(questions.getActionCommand());
}
}
Is this code, both (A) and (B), all together in your program? If so, it would make sense that it doesn't work. You should have (A) in a constructor or some set up method. You should follow (A) with code that creates your JRadioButtons or JCheckBoxes, that sets their actionCommand String, that places them in the GUI, and that adds them to the ArrayList.
The part (B) code, the enhanced for loop would need to be in code that is called in response to an event, perhaps in a JButton or radio button's ActionListener.
Please check out this information and fill us in on the details. Please consider creating and posting an sscce illustrating your problem for us.
Edit 2
Your code is confusing in that you appear to have two completely variables of different types with the exact same name, and you appear to be assuming that this will give the variable magical properties that will allow it to know what it's "twin" might be doing. Java doesn't work that way, and in fact variable names are not nearly all that important or smart to allow them any such functionality. Rather your code must be smart.
I'm assuming that more than one of your JCheckBoxes will be checked, and that you want to check which ones are checked at some point in your program. If so, then in your class you should have a List or ArrayList field, something like
private List<JToggleButton> questionsList = new ArrayList<JToggleButton>();
This way this field will available throughout the class.
Then where you create your JCheckBoxes, you add them to this list:
private void setExamButtonActionPerformed(java.awt.event.ActionEvent evt)
{
if(evt.getActionCommand().equals("Set Exam"))
{
CardLayout cL = (CardLayout)cardPanels.getLayout();
cL.show(cardPanels, "setExamPanel");
}
try
{
String theMessage = myObject.getMessage();
String delims = "(?=(0*([0-9]{1,2}|100)))";
String[] questions = theMessage.split(delims);
for (int j = 1; j < questions.length; j++)
{
settingQuestionBox = new JCheckBox(questions[j]); // *** renamed to make more sense
settingQuestionBox.setActionCommand(questions[j]); // **** add actionCommand String
questionsList.add(settingQuestionBox); // ****** add JCheckBox to List
settingQuestionTextField = new JTextField("");
jPanel1.add(settingQuestionBox);
jPanel1.add(settingQuestionTextField);
jPanel1.revalidate();
jPanel1.repaint();
}
//close streams and socket code
}
catch(Exception e)
{
// System.out.println(e);
e.printStackTrace(); // ***** more informative
}
}
Then elsewhere in your code
setExamQuestionButtonActionPerformed(java.awt.event.ActionEvent evt)
{
if(evt.getActionCommand().equals("Set Exam Question"))
{
// ArrayList<JToggleButton> settingQuestionBoxes = new ArrayList<JToggleButton>();
for(JToggleButton questions: questionsList)
{
if(questions.isSelected())
{
System.out.println(questions.getActionCommand());
}
}
CardLayout cL = (CardLayout)cardPanels.getLayout();
cL.show(cardPanels, "instructorPanel");
}
}
And of course you'll need to take care that the ActionListener is added to a button

Creating multiple JCheckBox with multiple ActionListener

I made this sample below to simulate multiple JCheckBox creation and its Action Listener.
int global=0;
//some code
JCheckBox[] checkBox = new JCheckBox[2];
for(int i = 0; i <=1; i++){
checkBox[i] = new JCheckBox(strings[i]);
panel.add(checkBox[i]);
checkBox[i].addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent evt) {
if (evt.getStateChange() == ItemEvent.SELECTED){
JOptionPane.showConfirmDialog(null, "Message"+global);
}
}
});
global++;
}
What I'm not getting is that my output for the Dialog is always "Message 2". In my logic if I'm declaring one AddItemListener for each checkBox, I should recieve two different dialogs for each checked box, such as "Message 1" and "Message 2". What am I doing wrong here? How to handle this please?
Thanks in advance
When showConfirmDialog() is first called global has already value 2. If you want different message for each check-box try putting global++ (will increment at each call) right before JOptionPane.showConfirmDialog(null, "Message"+global); and this will make it more clear to you.
if I'm declaring one AddItemListener for each checkBox, I should
recieve two different dialogs for each checked box, such as "Message
1" and "Message 2"
Why do you think you should get two (different) invocations of listener method per checkbox if you know that you have only one listener per checkbox?
One of the more possible solutions could be to implement your own ItemListener which has stored the message (or just number) to be shown in its instance variable.
global is nowhere related to the JChekcbox objects that you are creating in your code. So , Whenever itemStateChanged is called by the application, It is reading the latest value of global which is 2. To achieve whatever you are looking for you should change your code in this way:
for(int i = 0; i <=1; i++){
checkBox[i] = new JCheckBox(strings[i]);
panel.add(checkBox[i]);
checkBox[i].addActionCommand(String.valueOf(i+1));
checkBox[i].addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent evt) {
if (evt.getStateChange() == ItemEvent.SELECTED){
JOptionPane.showConfirmDialog(null, "Message"+((JCheckBox)evt.getSource()).getActionCommand());
}
}
});
global++;
}
In your code global is increased by 1 at each iteration of the loop. Value of global is 2 after loop exits that is why you have "Message 2". If these numbers represent the location in the array then I would try:
#Override
public void itemStateChanged(ItemEvent evt) {
int loc = indexInArray(evt.getItem(),checkBox);
if (evt.getStateChange() == ItemEvent.SELECTED){
JOptionPane.showConfirmDialog(null, "Message"+global);
}
}
});
You can implement a simple search in the method indexInArray:
public int indexInArray(Object []objects, Object obj){
for(int i = 0 ; i < objects.length; i++){
if(objects[i] == obj){
return i;
}
}
return -1;
}

java - JProgressBar while method is running

The Find() method is a sample of my method that makes a search of a word into some files.
I call it from a Button_Start mouseclicked event.
Here is my code:
public void Find (String word) {
List_files_directories (directory.getAbsolutePath(), files);
// print list
textpane.append(java.awt.Color.cyan, "Files in the choosen directory\n");
for (int j=0; j<files.size(); j++) {
if (files.get(j) != null)
textpane.append( java.awt.Color.PINK, "\n" + files.get(j) );
}
// from listarray to array
String[] array_files = new String[files.size()];
array_files = files.toArray(array_files);
int j;
for (j=0; j<array_files.length; j++) {
if (array_files[j] != null) {
if (array_files[j].contains("1")) {
function1 ( array_files[j], word );
}
else if ( array_files[j].contains("2") )
{
function2 ( array_files[j], word);
}
else if ( array_files[j].contains("3") )
{
function3 ( array_CARTELLE[j], word );
}
}
}
}
private void Button_StartMouseClicked(java.awt.event.MouseEvent evt) {
java.util.Timer().schedule(
new java.util.TimerTask() {
#Override
public void run() {
Find(word_from_textfield);
}
},
10
);
}
I need to add 2 things:
I'd like to make a JProgressBar while Find() method is running.
In this case I need to adopt a standard to set set the bar progress
i.e. based on the files list length, I don't know.
I'd like to set WAIT_CURSOR while Find() method is running, so until
progress bar reaches 100%.
I tried this for my request 1):
public void doWork() {
Worker worker = new Worker();
worker.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
ProgressBar1.setValue((Integer) evt.getNewValue());
}
}
});
worker.execute();
}
public class Worker extends SwingWorker<Object, Object> {
#Override
protected Object doInBackground() throws Exception {
for (int index = 1; index <= 1000; index++) {
int progress = Math.round(((float) index / 1000) * 100f);
setProgress(progress);
Thread.sleep(100);
}
return null;
}
}
In this I call doWork() at the beginning of my Find() method.
The problem is that I don't know how to synchronize my method duration and the progress bar length.
Besides I don't know if it's the best way to reach my aim.
Could you please help me giving an example according to my code/situation?
Thanks
edit: here is my goal: My method prints on a JTextPane ( textpane.append() ) all files from the user directory, after that it search a word in each file.
I want to use a JProgressBar while it's printing on the JTextPane and it has to be synchronized with the process duration.
If it's possibile the print has to be timed:
Example:
// Set Mouse cursor to Wait Status
// execute Find():
// the JProgressBar has to follow this progress of the print on JTextPane.
Files in the choosen directory:
file1
// print on JTextPane after 1 second
file2
// print on JTextPane after 1 second
file3
// print on JTextPane after 1 second
word found in file1!
// print on JTextPane after 1 second
word not found in file2
// print on JTextPane after 1 second
word found in file3
// print on JTextPane after 1 second
// restore mouse cursor to default
What's publish()? I don't understand what I have to do.
The methods publish() and process() let the SwingWorker reliably communicate interim results from the background thread to the event dispatch thread (EDT). In this example, process() displays the current result of a long-running calculation; in this related example, process() also updates a chart's data model.
Addendum: As #mKorbel notes, you can leverage generic type checking by using a more specific type, e.g. SwingWorker<Double, Double>.
I think you need to integrate the work done by Find() into the SwingWorker. Then you could set your progress bar after processing each file.
#Override
protected Object doInBackground() throws Exception {
for (int j=0; j<files.size(); j++) {
if (files.get(j) != null)
textpane.append( java.awt.Color.PINK, "\n" + files.get(j) );
}
// from listarray to array
String[] array_files = new String[files.size()];
array_files = files.toArray(array_files);
int j;
for (j=0; j<array_files.length; j++) {
if (array_files[j] != null) {
if (array_files[j].contains("1")) {
function1 ( array_files[j], word );
}
else if ( array_files[j].contains("2") )
{
function2 ( array_files[j], word);
}
else if ( array_files[j].contains("3") )
{
function3 ( array_CARTELLE[j], word );
}
// THIS IS THE NEW BIT
setProgress((int)(100 * (float) j / files.size()));
}
}

Categories