I have two functions for actualy lookng for element that appear after sometime (something around 7 sec) so I tried to do it with expected conditions - visibility / presence of element with time duration of 10 sec and I got error that the element is not appear eventhough I saw it in other hand I did function :
public SafeModeScreen validateSafeModeScreen(){
boolean flag = false;
while(!flag) {
try {
System.out.println("The name is :" +driver.findElement(safeModeScreen).getAttribute("name"));
System.out.println("The screen height is :" + driver.findElement(safeModeScreen).getSize().getHeight());
System.out.println("The screen width is :" + driver.findElement(safeModeScreen).getSize().getWidth());
flag = true;
}
catch (Exception e){
}
}
Assert.assertTrue(flag, "Safe mode screen didn't appear");
return this;
}
the other function is:
public void waitForElementToBeVisible(By element, int delay) {
wait = new WebDriverWait(driver, delay);
wait.until(ExpectedConditions.visibilityOfElementLocated(element));
wait = new WebDriverWait(driver, 30);
}
and that worked, what is the difference between them that the while worked?
Thank you
Related
my exercise is composed of an SharedResource with an array, a NumberGenerator Class and a SumClass.
2 Threads of NumberGenerator and 2 Threads of SumClass.
I have to insert numbers in the array from the SharedResource with both threads of NumberGenerator Class.
This part is done correctly.
My problem is in the run method of the NumberGenerator Class.
These Threads must read alternatively the index of the array, the first thread, lets call it H1, read the index 0-2-4-6... even index, the another one, H2, odd index... But when 1 thread is running the other must wait.
So the output should be something like this:
Array:[10,35,24,18]
Thread name: H1 - Number:10
Thread name: H2 - Number:35
Thread name: H1 - Number:24
Thread name: H2 - Number:18
My problem resides in the notify and wait methods. When I call the wait method, it automatically stop both Threads even when a notifyAll is present.
I need to just use 1 method, I cant use a evenPrint method and an OddPrint method for example.
Code of my class:
public class SumatoriaThread extends Thread{
String name;
NumerosCompartidos compartidos; // Object that contains the array.
double sumatoria; //Parameter used to sum all the numbers
static int pos = 0; // pos of the object
static int threadOrder = 0; //just a way to set the order of the Threads.
int priority; //Value of the priority
public SumatoriaThread(NumerosCompartidos compartidos, String name){
this.name = name;
this.compartidos = compartidos;
sumatoria = 0;
priority = threadOrder;
threadOrder++;
System.out.println("Hilo " + this.name + " creado.");
}
public void run() {
//Array Length
int length = this.compartidos.length();
int i = 0;
while (pos < length) {
//Don't actually know if this is correct.
synchronized (this) {
//Just to be sure that the first Thread run before the second one.
if (priority == 1) {
try {
priority = 0;
//Call a wait method until the next notify runs.
this.wait();
} catch (InterruptedException ex) {
Logger.getLogger(SumatoriaThread.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
//Even numbers
if (pos % 2 == 0) {
System.out.println("Nombre Thead: " + Thread.currentThread().getName() + " valor numero: " + this.compartidos.getValor(pos));
pos++;
//To activate the Thread which is waiting.
this.notifyAll();
try {
//Then I set to wait this one.
this.wait();
} catch (Exception ex) {
ex.printStackTrace();
}
} else {
System.out.println("Nombre Thead: " + Thread.currentThread().getName() + " valor numero: " + this.compartidos.getValor(pos + 1));
pos++;
this.notifyAll();
try {
this.wait();
} catch (InterruptedException ex) {
Logger.getLogger(SumatoriaThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
}
}
cannot print values from the merged lists as it is throwing me null!
List<WebElement> DateTime2 = driver.findElements(By.xpath(""));
driver.findElement(By.xpath("")).click();
List<WebElement> DateTime3 = driver.findElements(By.xpath(""));
List<WebElement> DateTime = new ArrayList<>(DateTime2);
DateTime.addAll(DateTime3);
Thread.sleep(2000);
System.out.println("This is for testing the list " +
DateTime.get(2).getText());
System.out.println("This is for testing the list " +
DateTime.get(30).getText());
i expect output to be printed date and time
Here's an example of some code I use (though I changed it a bit for this example. This is usually a part of a class that extends another.)
int sanitycount= 0;
int ec_Timeout = 10; //seconds to wait for list...
public void RunAction(WebDriver driver, String in_xpath)
{
try
{
wait = new WebDriverWait(driver, ec_Timeout);
List<WebElement> found_elements = new ArrayList<>();
found_elements = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath(in_xpath)));
if (!found_elements.isEmpty())
{
// store this array, return an array from function
// or loop through array and add items to more global array..
}
}
catch (Exception e)
{
if (e.getClass().getCanonicalName().equals("org.openqa.selenium.StaleElementReferenceException"))
{
//need to do it again, not finished loading
System.out.println("*****************Stale caught-redoing");
sanitycount++;
if (sanitycount<ec_Timeout * 2)
{
RunAction(driver, in_xpath);
}
System.out.println (e.toString());
}
else
{
System.out.println (e.toString());
}
}
}
RunAction(your_driver, your_xpath);
//set sanitycount back to zero if you run again...
I am using ScheduledExecutorService, Semaphore and ScheduledFuture to write a rate limiting function, simply put, when a client reaches the limit, server will return error 429 with "msg please try after %d second".
I use scheduledFuture.getDelay(TimeUnit.SECONDS) to get value of %d. For the first or second attempts, it acts normal, i.e. allow access unit reach the limit and showing how many seconds to wait afterward. Then getDelay starts showing negative value. Does it mean the ScheduledExecutorService not working properly?
following is the snippet
public RateLimiter(int permits, long durationInMillis){
this.semaphore = new Semaphore(permits);
this.permits = permits;
this.durationInMillis = durationInMillis;
scheduleReplenishment();
}
public boolean allowAccess() {
return semaphore.tryAcquire();
}
public long nextReplenishmentTime() {
return scheduledFuture.getDelay(TimeUnit.SECONDS);
}
public void stop() {
scheduler.shutdownNow();
}
public void scheduleReplenishment() {
scheduledFuture = scheduler.schedule(() -> {
semaphore.release(permits - semaphore.availablePermits());
}, durationInMillis, TimeUnit.MILLISECONDS);
}
If the task has done, the getDelay(TimeUnit) will be negative. To show it, I add two parameters to scheduleReplenishment(), and change getReplenishmentTime() to printReplenishmentTime().
Note1: If you create a Future<>, and replace one with another, you should care about the deleted one...
Note2: If you want test Future<> and Semaphore, don't release the allocated resources immediately.
private final ConcurrentSkipListMap<String, ScheduledFuture<?>> scheduledFutures
= new ConcurrentSkipListMap<>();
private final AtomicInteger counter = new AtomicInteger();
public void printReplenishmentTime() {
scheduledFutures.forEach((name, f) -> {
final long delay = f.getDelay(TimeUnit.SECONDS);
System.out.println(name + " delay " + delay);
});
}
/**
* try acquire one permit once from {#code semaphore},
* then wait {#code waitInMillis}, until all permits used.
*
* #param waitInMillis after successfully used one permit, wait
* #param permits all permits to use, best if permits #gt; 2
*/
public void scheduleReplenishment(final long waitInMillis, final int permits) {
final String name = "future" + counter.getAndIncrement();
scheduledFutures.put(name, scheduler.schedule(() -> {
try {
for (int permit = permits; 0 < permit;) {
final boolean ack = semaphore.tryAcquire(1);
System.out.println(name + " " + (ack ? "acquire" : "not acquire")
+ " one, but need " + permit);
if (ack) {
permit--;
}
if (0 < permit) {
try {
Thread.sleep(waitInMillis);
} catch (final InterruptedException e) {
System.out.println(name + " interrupted, exiting...");
return;
}
}
}
System.out.println(name + " done");
} finally {
semaphore.release(permits - permit);
}
// BAD CODE: semaphore.availablePermits() for debugging purposes
// only, maybe 0 release...
// semaphore.release(permits - semaphore.availablePermits());
}, durationInMillis, TimeUnit.MILLISECONDS));
}
scheduler.schedule() is a one time go function, that's why it shows negative getDelay() value.
I am building a Java Swing Memory Game. The idea is to click on the first card, it changes the image from a baseImage to another image. When the second card is clicked, it is supposed to do the same thing, wait for a few seconds, then reset everything back to base if they don't match or keep them flipped over if they do.
Right now, if they do not match, the second card never changes the image. Below is the relevant code. It should be noted that if they do match, the image shows and all is right and good in the world.
public void cardClickHandler(ActionEvent ae) {
JButton card = new JButton();
card = (JButton) ae.getSource();
// disable the card that was clicked
card.setEnabled(false);
// behavior for first card clicked
if (clickCounter == 0) {
firstCardClicked = card;
img = new ImageIcon("images2/img" + firstCardClicked.getName() + ".jpg");
firstCardClicked.setDisabledIcon(img);
System.out.println("Button " + firstCardClicked.getName() + " clicked!");
clickCounter++;
}
// behavior for second card clicked
else {
secondCardClicked = card;
img = new ImageIcon("images2/img" + secondCardClicked.getName() + ".jpg");
secondCardClicked.setDisabledIcon(img);
System.out.println("Button " + secondCardClicked.getName() + " clicked!");
clickCounter--;
}
// behavior if two cards have been clicked and they match
if (firstCardClicked.getName().equals(secondCardClicked.getName()) && clickCounter == 0) {
// player turn control and scoring
if (p1Turn) {
p1NumScore++;
p1Score.setText(Integer.toString(p1NumScore));
scorePanel.revalidate();
System.out.println("Good job Mike, got a pair!");
p1Turn = !p1Turn;
}
else {
p2NumScore++;
p2Score.setText(Integer.toString(p2NumScore));
scorePanel.revalidate();
System.out.println("Good job Peanut, got a pair!");
p1Turn = !p1Turn;
}
}
// behavior if two cards have been clicked and they do not match
else if (!(firstCardClicked.getName().equals(secondCardClicked.getName())) && clickCounter == 0) {
// keep cards flipped for a few seconds
try {
System.out.println("Before Sleep"); // testing
Thread.sleep(2000);
System.out.println("After Sleep"); // testing
}
catch (Exception e) {
e.printStackTrace();
}
// enable the cards and reset images
firstCardClicked.setEnabled(true);
firstCardClicked.setIcon(baseImage);
secondCardClicked.setEnabled(true);
secondCardClicked.setIcon(baseImage);
// change turns
p1Turn = !p1Turn;
System.out.println("Keep Playing");
}
}
It looks as though there were a few problems working at the same time. Thread.sleep() was causing havoc in conjunction with the .setEnabled(true) commands. The state of the objects were in question so I needed to clear them at the end of the code. There are some known issues with .setDisabledIcon() method that many posts here say require a .setIcon() to preceed it. Here is the fixed code that works with the javax.swing.Timer being used.
public void cardClickHandler(ActionEvent ae)
{
// method variables
JButton card = (JButton) ae.getSource();
boolean clearState = false;
// behavior for first card clicked
if (isFirstCard)
{
firstCardClicked = card;
// a known issue with "setDisabledIcon()" required the "setIcon()" method
firstCardClicked.setIcon(new ImageIcon("images2/img" + firstCardClicked.getName() + ".jpg"));
firstCardClicked.setDisabledIcon(new ImageIcon("images2/img" + firstCardClicked.getName() + ".jpg"));
// disable the flipped card
firstCardClicked.setEnabled(false);
// indicate the next card clicked is the second card
isFirstCard = false;
}
// behavior for second card clicked
else
{
secondCardClicked = card;
// a known issue with "setDisabledIcon()" required the "setIcon()" method
secondCardClicked.setIcon(new ImageIcon("images2/img" + secondCardClicked.getName() + ".jpg"));
secondCardClicked.setDisabledIcon(new ImageIcon("images2/img" + secondCardClicked.getName() + ".jpg"));
// disable the flipped card
secondCardClicked.setEnabled(false);
// indicate the next card clicked is the first card again
isFirstCard = true;
// indicate to the system both cards have been clicked and can clear objects
clearState = true;
}
// behavior if two cards have been clicked and they match
if (isFirstCard && firstCardClicked.getName().equals(secondCardClicked.getName()))
{
// player turn control and scoring
if (p1Turn)
{
p1NumScore++;
p1Score.setText(Integer.toString(p1NumScore));
scorePanel.revalidate();
p1Turn = !p1Turn;
}
else
{
p2NumScore++;
p2Score.setText(Integer.toString(p2NumScore));
scorePanel.revalidate();
p1Turn = !p1Turn;
}
}
// behavior if two cards have been clicked and they do not match
else if (isFirstCard && !(firstCardClicked.getName().equals(secondCardClicked.getName())) )
{
// enable the cards and reset images
firstCardClicked.setIcon(BASE_IMAGE);
secondCardClicked.setIcon(BASE_IMAGE);
// change turns
p1Turn = !p1Turn;
}
if (clearState)
{
javax.swing.Timer timer = new javax.swing.Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent ae) {
firstCardClicked.setEnabled(true);
secondCardClicked.setEnabled(true);
isFirstCard = true;
firstCardClicked = null;
secondCardClicked = null;
}
});
// Normally the timer's actionPerformed method executes repeatedly. Tell it only to execute once.
timer.setRepeats(false);
// Start the timer.
timer.start();
}
}
So I'm starting to get really interested about Threads and how it works, Kinda amazing how it works but I just learned about it today and trying to make a program to work. So im trying to make a clock that gives me in a Jlabel a current clock which is right now and a Textfield where I enter the time by myself. so what I want to do is it should start by showing me the time, when pressing the button "Set time" it should change the time as I entered and go from there as a clock.
So my problem right now is that whenever I press the Set time now it changes for a second and then turn back to the current clock again. and I don't really know how to stop the first thread when pressing Set time (Which starts the second Thread)
However I think this is kinda simple but fun to work with,
EDIT: I Also found out that I will have a problem by counting when entering a own "clock". My code:
public Clock() {
initialize();
Thread1();
}
.......
JButton btnSetTime = new JButton("Set time");
btnSetTime.setBounds(474, 262, 89, 23);
frame.getContentPane().add(btnSetTime);
btnSetTime.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(e.getSource() == btnSetTime) {
Thread2();
}
}
});
}
public void Thread2() {
Thread t2 = new Thread() {
public void run() {
try {
for(;;) {
int hour = Integer.parseInt(tfhour.getText());
int minute = Integer.parseInt(tfminute.getText());
int second = Integer.parseInt(tfsecond.getText());
lblKlockan.setText(hour + ":" + minute + ":" + second);
sleep(1000);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};t2.start();
}
public void Thread1() {
Thread t1 = new Thread() {
public void run() {
try {
for(;;) {
Calendar cal = Calendar.getInstance();
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
int second = cal.get(Calendar.SECOND);
lblKlockan.setText(hour + ":" + minute + ":" + second);
sleep(1000);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};t1.start();
}
}
So as I can see, the int hour = Integer.parseInt(tfhour.getText()); will probably not count as a Clock if I change to my own clock later on if i'm right? In that case, How can I fix it?
I hope I have all my problems out here in the post and I hope anyone here is willing to help me aswell :)
EDIT:
To make it easier to see:
EDIT PART 3:0
You have to define a global variable to stop the thread 1, when the thread 2 starts. Here is an example,
//define a variable that controls the thread 1
static boolean clockSet = false;
Now thread 1 is written such as it runs only when the clockSet is false, that is clock not set by a click.
Thread t1 = new Thread(){
public void run(){
while(!clockSet){
Calendar cal = Calendar.getInstance();
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
int second = cal.get(Calendar.SECOND);
lblKlockan.setText(hour + ":" + minute + ":" + second);
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
In your thread 2, set the clockSet to true, so the thread 1 will stop. I see you are just displaying the value entered, but not setting those on a Calendar object. So create a Calendar object in thread 2, set the user defined values, and increment the time after every second of sleep.
Thread t2 = new Thread(){
public void run(){
clockSet = true;
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(tfhour.getText()));
cal.set(Calendar.MINUTE, Integer.parseInt(tfminute.getText()));
cal.set(Calendar.SECOND, Integer.parseInt(tfsecond.getText()));
while(true){
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
int second = cal.get(Calendar.SECOND);
lblKlockan.setText(hour + ":" + minute + ":" + second);
try {
sleep(1000);
cal.add(Calendar.SECOND, 1);
} catch (InterruptedException e) {
e.printStackTrace();}
}
}
};
Have fun..!
Sure, you see the code
try {
for(;;) {
int hour = Integer.parseInt(tfhour.getText());//this one
int minute = Integer.parseInt(tfminute.getText());//and this one
int second = Integer.parseInt(tfsecond.getText());//and this too
lblKlockan.setText(hour + ":" + minute + ":" + second);
sleep(1000);
}
you are setting hour, minute & second each and every time inside the for loop. So the clock is reseting.
Make them to get initialize only once, i.e. take them out of the loop.
Further this code
for(;;) {
Calendar cal = Calendar.getInstance();
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
int second = cal.get(Calendar.SECOND);
lblKlockan.setText(hour + ":" + minute + ":" + second);
sleep(1000);
}
is making your timer work as clock and not a timer because after 1 sec. the hour, minute & second are set to the values according to the time you get from Calendar.
Due to this your code will work as a clock that show the current time.
In my opinion you don't need the second thread at all. What I would do in this case is create three Int fields, hour-, minute- and second-offset, which you change when the button is pressed to, for example, hourOffset = Calendar.HOUR_OF_DAY - Integer.parseInt(tfhour.getText())%24; (example for the hours). Than you just need to add the offset to the time in thread1, which allways works since you start with 0 as offset.