Print title of 2nd last tab if multiple tabs are open - java

I was asked in an interview to print title of 2nd last tab if multiple tabs are open.
I tried this later:
LinkedHashSet<String> windows = (LinkedHashSet<String>) driver.getWindowHandles();
ArrayList<String> windowsList = new ArrayList<String>(windows);
int size = windowsList.size();
driver.switchTo().window(windowsList.get(size-2));
System.out.println(driver.getTitle());
The above one is not working correctly, but the below one is working:
driver.switchTo().window(windowsList.get(2));
System.out.println(driver.getTitle());
It is storing the parent window at 0th index but child windows in reverse order. Can someone explain?

WebDriver specification says:
The order in which the window handles are returned is arbitrary.
Even though RemoteWebDriver internally wraps the response with LinkedHashSet (no idea why) the order of what is coming from the WebDriver itself is not predictable.
I would say that since your browser is under your control you do know which tab you opened in which order hence you could keep some map that would associate a handle with the position of that actual tab.
Then you could pick the proper handle from that map by the position.

Could you please provide more valid information? Such as your error report or error log, otherwise I can't better understand the problem you are trying to understand, so I tried it myself, I hope it will help you. Here is the code I constructed with reference to your ideas:
public static void main(String[] args) {
TestDriver driver=new TestDriver("null title");
LinkedHashSet<String> windows = (LinkedHashSet<String>)
driver.getWindowHandles();
ArrayList<String> windowsList = new ArrayList<>(windows);
int size = windowsList.size();
String newTitle = windowsList.get(size - 2);
driver.switchTo().window(newTitle);
System.out.println("driver title:"+driver.getTitle());
System.out.println("window title:"+driver.switchTo().getTitle());
}
TestDriver:
class TestDriver{
public String title;
private TestWindow testWindow;
public TestDriver(String title) {
this.title = title;
}
public TestDriver(String title, TestWindow testWindow) {
this.title = title;
this.testWindow = testWindow;
}
public TestDriver(TestWindow testWindow) {
this.title=testWindow.title;
this.testWindow=testWindow;
}
public HashSet<String> getWindowHandles(){
LinkedHashSet<String> retLinkedHashSet = new LinkedHashSet<>(15);
for (int i = 0; i <15 ; i++) {
retLinkedHashSet.add(i+"");
}
return retLinkedHashSet;
}
/**
* switch
* For convenience, I don't use design patterns.
* #return
*/
public TestWindow switchTo() {
return new TestWindow(this);
}
public void window(String title){
this.title=title;
}
public String getTitle() {
return title;
}
}
TestWindow:
class TestWindow{
public String title;
private TestDriver testDriver;
public TestWindow(String title) {
this.title = title;
}
public TestWindow(TestDriver testDriver) {
this.title=testDriver.title;
this.testDriver = testDriver;
}
public TestDriver switchTo() {
return new TestDriver(this);
}
public void window(String title){
this.title=title;
}
public String getTitle() {
return title;
}
}
This is the first to use your idea, and the final output is as expected.
<div align=center><img src="https://i.stack.imgur.com/7tu2q.png"></div>
Next I'll give you the slightly tweaked code:
estDriver driver=new TestDriver("null title");
LinkedHashSet<String> windows = (LinkedHashSet<String>)
driver.getWindowHandles();
ArrayList<String> windowsList = new ArrayList<>(windows);
int size = windowsList.size();
/* String newTitle = windowsList.get(size - 2);
driver.switchTo().window(newTitle);*/
/**
* In the conversion I always create a new object for assignment.
* split a method,you can got a right question.
*/
String newTitle = windowsList.get(size - 2);
TestWindow testWindow = driver.switchTo();
System.out.println("driver title:"+driver.getTitle());
System.out.println("window title:"+driver.switchTo().getTitle());
}
}
Then you will find:
<div align=center><img src="https://i.stack.imgur.com/frIw0.png"></div>
So the real thing that might get you wrong might be in #link{
In method:switchTo()}, if your transition uses a newly created class, you cannot call it again when you finally output the result, which will cause your result to reset.
The information you gave may be too little for me and I may not be able to actually recover your mistakes, hope this helps.
enter image description here
enter image description here

Related

Exception when clicking JTree (null pointer exception)

so when i clicking the Messages tabPane containing the Jtree, this is the preview in my java swing which seems fine.
pict 1 (loading the message)
pict 2. (done)
when i click any of the checkboxes in the JTree it should be either loading(checking) or unloading(unchecking) the messages in the message list with the swingworker running to see the progress. But what happen is after i click the checkboxes (of any condition), yes the swingworker running and giving the loading/unloading progress, but after that, i get this:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException:
Cannot invoke "model.Message.getContents()" because "message" is null
and make the message lists is unclickable, which were clickable before i attempted to click the checkboxes in the JTree.
at the moment i dont need JTree in my purpose for learning swing, so I'm not really taking into account about this JTree lesson, but i need this to be fixed so i can keep go along with the tutorial. that's why i'm not quite sure which code are problematic and needed to put in this thread. So i'm very sorry if my question is not clear. if there still anything i have to put at this thread, please ask me i'll be happy to put it here.
this the class that mentioned in exception
public class MessagePanel extends JPanel implements ProgressDialogListener{
public MessagePanel(JFrame parent) {
messageListModel = new DefaultListModel();
messageList = new JList(messageListModel);
messageList.setCellRenderer(new MessageListRenderer());
messageList.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
Message message = (Message)messageList.getSelectedValue();
textPanel.setText(message.getContents());
}
});
}
this is the class and method that related with the above class
public class MessageListRenderer implements ListCellRenderer {
private JPanel panel;
private JLabel label;
private Color selectedColor,normalColor;
public MessageListRenderer() {
//some ui settings
}
#Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
Message message = (Message)value;
label.setText(message.getTitle());
panel.setBackground(cellHasFocus ? selectedColor: normalColor);
return panel;
}
}
===================
public class TextPanel extends JPanel{
public void setText(String text) {
textArea.setText(text);
}
}
===================
public class Message {
private String title,contents;
public Message(String title, String contents) {
super();
this.title = title;
this.contents = contents;
}
public String getTitle() {return title;}
public void setTitle(String title) {this.title = title;}
public String getContents() {return contents;}
public void setContents(String contents) {this.contents = contents;}
}
Your Message class constructor requires two parameters (of: String, String) in order to create an instance of Message. I have no clue what you are currently using to create you Message instances nor do I know what is storing those instances. You do need to keep track of them otherwise you will loose them to JVM Garbage Collection.
I think perhaps you may want to modify your Message Class a little so that you can internally (or externally) store your Message instances and easily access any one of those instances when required, for example:
public class Message {
// A List Interface object to hold Message instances.
private static java.util.List<Message> messageInstances = new java.util.ArrayList<>();
// The OS System's New-Line character to use for console writing.
private final static String ls = System.lineSeparator();
// Instance member variables
private String title;
private String contents;
/**
* Constructor #1
* Does Nothing but adds the instance to the messageInstances List!
* Relies on Setters to fill instance member variables.
*/
public Message() {
messageInstances.add((this));
}
/**
* Constructor #2
* Contains parameters of which the arguments will fill instance member
* variables listed within the Parameters list below.
*
* #param title (String) The Message Title.<br>
*
* #param contents (String) The message content related to the above title.
*/
public Message(String title, String contents) {
super();
this.title = title;
this.contents = contents;
messageInstances.add((this));
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContents() {
return contents;
}
public void setContents(String contents) {
this.contents = contents;
}
public static java.util.List<Message> getMessageInstances() {
return messageInstances;
}
/**
* Removes one (or more) Message instances from the messageInstances List.
* This method must be supplied at least one integer index value of the
* Message instance to remove otherwise a Warning is displayed within the
* console window. Several index values can be supplied providing they are
* delimited with a comma or all desired Message Instance index values to
* remove are supplied within a Single Dimensional int[] Array.<br><br>
*
* <b>Valid uses of this class method:</b><pre>
*
* removeMessageInstance(0, 4, 2, 16);
*
* OR
*
* int[] indexes = {0, 4, 2, 16};
* removeMessageInstance(indexes);</pre>
*
* #param instanceIndexes
*/
public static void removeMessageInstance(int... instanceIndexes) {
int[] iIndex = null;
if (instanceIndexes.length == 0) {
System.err.println("Message.removeMessageInstance() method Warning!" + ls
+ "Require an index value of the Message Instance to remove!" + ls
+ "Ignoring Removal call!" );
return;
}
iIndex = new int[instanceIndexes.length];
System.arraycopy(instanceIndexes, 0, iIndex, 0, instanceIndexes.length);
for (int i = 0; i < iIndex.length; i++) {
if(iIndex[i] < 0 || iIndex[i] > messageInstances.size()) {
System.err.println("Message.removeMessageInstance() method Warning!" + ls
+ "The supplied Message Instance index value (" + iIndex[i] + ") is invalid!" + ls
+ "Ignoring Removal call for Message Instance at Index " + iIndex[i] + "!");
continue;
}
messageInstances.remove(iIndex[i]);
}
}
#Override
public String toString() {
return new StringBuilder("").append(title).append(" | ")
.append(contents).toString();
}
}
Do whatever it is you do to create Message instances.
Now, in your MessagePanel class within the ListSelectionListener:
public void valueChanged(ListSelectionEvent e) {
String title = messageList.getSelectedValue().toString(); // toString() may not be required.
List<Message> messages = Message.getMessageInstances();
for (Message msg : messages) {
if (msg.getTitle().equalsIgnoreCase(title)) {
textPanel.setText(msg.getContents());
break;
}
}
}

Finding an element in an Array using ONLY If statement

I made a post earlier about a similar topic. However, I thought I would clarify something and change my question.
So this project I am doing is confusing me. I am only 5 weeks in and the question is asking me to create a method that returns a title of a photo in an array of photos. each photo has a title. This is the code:
public class Album {
private String albumtitle;
private ArrayList<Photo> photos;
/**
* This constructor should initialize the
* instance variables of the class.
*/
public Album(String title) {
this.albumtitle = title;
photos = new ArrayList<>();
}
/** When passed a title, this method should
* return the first Photo object in the album with
* a matching title. If there is no such object, it
* should return null.
*
* #param title A title to search for
* #return A Photo object, or null
*/
public Photo searchByTitle(String title) {
//TODO enter code here
}
}
Now, my lecturer said not to use for loops as the project is from chapter 1 to 4 (chapter 5 is for loops/iterations)
https://lms.uwa.edu.au/bbcswebdav/pid-1134902-dt-content-rid-16529804_1/courses/CITS1001_SEM-2_2018/lectures/BooksReadJournal.java.pdf
This is an example of what the lecturer did with a program about books without using for loops. However, notice it has (int index) as a parameter and then uses String title = bookTitles.get(index)
My point is, how do I do it without using for loop? I don't want them to feel as I have copied off the internet something we haven't learned.
Thanks,
If you are limited to avoid use the for-loop and use the if-else only, the recursive call is an alternative:
public Photo searchByTitle(String title) {
return searchByIndex(title, 0);
}
private Photo searchByIndex(String title, int index) {
if (index < photos.size()) { // Has next? If yes ...
Photo next = photos.get(index); // Get next
if (!title.equals(next.getPhotoName())) { // Does the title match? If not...
return searchByIndex(title, ++index); // Check the next one
} else return next; // Otherwise you found it
} return null; // ... if no next, return null
}
I assume the Photo class has a field String photoName accessible with a getter which is about to be compared with the String title.
Implement Comparable on Photo that returns true if the title is the same.
Construct a temporary Photo object with the given type.
Leverage the indexOf method on ArrayList to find index of Album with the Photo title.
Use get(int) to get the Album.
I've implemented the code from the comments above.
The idea here is to build a temporary object in the searchByTitle method and passing it to the List.indexOf method having the Photo class that overrides Object.equals.
public class Album {
class Photo {
private String title;
public Photo(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
#Override
public boolean equals(Object anObject) {
return title.equals(((Photo)anObject).getTitle());
}
}
private String albumtitle;
private ArrayList<Photo> photos;
/**
* This constructor should initialize the
* instance variables of the class.
*/
public Album(String title) {
this.albumtitle = title;
photos = new ArrayList<>();
}
/** When passed a title, this method should
* return the first Photo object in the album with
* a matching title. If there is no such object, it
* should return null.
*
* #param title A title to search for
* #return A Photo object, or null
*/
public Photo searchByTitle(String title) {
Photo tmp = new Photo(title);
int index = photos.indexOf(tmp);
if (index >= 0)
return photos.get(index);
return null;
}
}
This is a very basical implementation of equals which doesn't take into account null argument and its type.
You can bring another ArrayList of String which keeps names of photo titles. Then in search function search with photo title in String arrayList. If find an index then return the Photo object of that index from photoTitles, as you are inserting in both arrayList in same order.
public class Album {
private String albumtitle;
private ArrayList<Photo> photos;
private ArrayList<String> photoTitles;
public Album(String title) {
this.albumtitle = title;
photos = new ArrayList<>();
photoTitles = new ArrayList<>();
}
public Photo searchByTitle(String title) {
int index = photoTitles.indexOf(title);
if(index >= 0) {
return photos.get(index);
}
return null;
}
}
Just because I like the recursion idea but using it with an index search on a List is not optimal, let's use an iterator instead. The recursive method will simply check if there is one value to take, check and call again until we find the value or reach the end.
//Just hide the used of an iterator
public static Photo getFirstWithTitle(List<Photo> list, String value){
return getFirstWithTitle(list.iterator(), value);
}
//recursive method
private static Photo getFirstWithTitle(Iterator<Photo> it, String value){
if(it.hasNext()){
Photo p = it.next();
return p.getTitle().equals(value)?
p
: getFirstWithTitle(it, value);
} else
return null;
}
You can use built in binarySearch and a comparator. Probably the most elegant way and how I usually do it
public Photo searchByTitle(String title) {
Photo item = null
Comparator<Photo> comparator = new Comparator<Photo>() {
public int compare(Photo it1, Photo it2) {
return it1.getTitle().compareTo(it2.getTitle());
}
};
Collections.sort(photos, comparator); //This should go after you set the items, ie. you sort it once
int index = Collections.binarySearch(photos, comparator);
if (index >= 0) {
item = photos.get(index);
}
return item
}
Using Java you don't even need a 'if' statement. This can be achieved through this:
public Photo searchByTitle(String title) {
return photos.stream().filter(photo -> title.
equals(photo.getTitle())).findAny().get();
}
p.s: I did not have access to your enunciate question (the link provided)

List<Enum> contains String

I have a list of enums like the below -
List<Status> statusList;
Status is defined as below
enum Status { YES , NO , MAYBE }
The list contains
Status stat = Status.YES;
statusList.add(stat);
I have a variable
Status statusVar = Status.YES;
I am trying to a comparison like below but it is not working as I guess it is comparing the references. The below returns false. Can you please suggest a solution?
statusList.contains(statusVar)
EDIT: Below is the code that is not working. Status is string not Enum
import java.util.ArrayList;
import java.util.List;
public class Test {
private enum Status {
YES , NO , MAYBE
}
public static void main (String[] args){
List<Status> statusList = new ArrayList<Status>();
String status = "YES";
statusList.add(Status.YES);
if(statusList.contains(status)){
System.out.println(" Yes ");
} else {
System.out.println(" No ");
}
}
}
If you are performing a contains, it will be much more efficient if you use an EnumSet
Set<Status> status = EnumSet.of(Status.YES);
assert status.contains(Status.YES);
However, List<Status> will also work.
You are right it does compare the reference, but this will only fail if you have
multiple ClassLoaders and the Class Status is actually different.
you create new instances of the Status which you can do using Unsafe.allocateInstance(Status.class)
What is more likely is you are not testing what you think you are and the situation isn't exactly as you have described.
private enum Status {
YES , NO , MAYBE
;
public Status getByName(String name){
for (Status st : Status.values()) {
if (st.toString().equals(name)){
return st;
}
}
return null;
}
}
try this!
You could add a function toString() and contains() as helpers:
private enum Status {
YES("Yes") , NO ("Yes") , MAYBE("Yes");
private final String label;
/**
* Instantiates a new Status.
* #param label the label
*/
private Status (final String label) {
this.label = label;
}
#Override
public String toString() {
return label;
}
public static boolean contains(final String test) {
for (final Status value : Status.values()) {
if (value.toString().equals(test)) {
return true;
}
}
return false;
}
}
enum Status { YES , NO , MAYBE }
public static void main(String[] args) {
List<Status> lista = new ArrayList<>();
lista.add(Status.YES);
Status stat = Status.YES;
System.out.println(lista.contains(Status.YES));//true
System.out.println(lista.contains(stat));//true
}
I made this code and print both ways and it worked perfectly
or
you remembered to instantiate the variable statusList

building a test program in java

Hello I am new to Java and NetBeans and am in Advanced classes in which my classes are 5 weeks long, so it is a lot to learn a new code language in 5 weeks. Anyways I have an assignment to Create a class named Movie that holds a movie name and rating. Provide methods to get and set both the movie name and rating. Create a class named TestMovie that creates three Movie instances with different values for name and rating and prints the information about each movie. I have done the code and it is passing the build fine but my professor wants a screen shot of the program working and running but I can't get NetBeans to bring that up. The chapter on building the test project was ripped out of my book. Can I get some help or pointers here is the code I have done:
package movie;
/**
*
* #author Jason
*/
public class Movie {
String movieRating;
public Movie(String rated, String mtitle) {
this.mrating = rated;
this.title = mtitle;
}
public void setRating(String Rating) {
movieRating = Rating;
}
// Get the rating
public String getRating() {
return movieRating;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
#Override
public String toString() {
return "Movie" + " title=" + getTitle() + " rating=" + getRating();
}
public static void main(String args[]) {
Movie mv = new Movie("", "");
mv.toString();
}
private String title;
private String mrating;
}
You can just run a test on the console, that is, create a MovieTest class with only a main method and create three instances/objects of Movie (Movie m1, m2, m3; OR Movie[] movies;). Assign them values either in the constructor or with the set methods then print them out with the method print or println in System.out.
Something along the lines of:
public class MovieTest {
public static void main(String[] args) {
Movie[] movies = new Movie[] {new Movie("R1", "T1"), new Movie("R2", "T2"), new Movie("R3", "T3)";
for (Movie i : movies) {
System.out.println(i.toString());
}
}
}
Then end by screenshooting the results.
As an alternative to the other answers suggesting printing the output to the console, with the Netbeans' UI editor you can easily create a window with a label showing the result, which makes it slightly more fancy.
You can get details on how to this here. Here's an image from that page:
The full working code is here. As you can see, it's just a few extra lines.
Your application prints no output, because you invoke toString(), but you don't print the result of it.
An example to create 3 Movie instances with data,
print them out, and then make a screenshot of your console app.
public static void main(String args[]) {
List<Movie> movieList = new ArrayList<Movie>(3);
Movie mv1 = new Movie("very Good", "Testfilm 1");
movieList add(mv1);
mv1 = new Movie("good", "Testfilm 2");
movieList add(mv1);
mv1 = new Movie("not good", "Testfilm 2");
movieList add(mv1);
for (Movie m : movieList) {
System.out.println(m.toString());
}
}

Java Object Array Foreach Method Access

After developing in PHP for a long time I have decided to step into Java. Comfortable in OOP methodology and all that, I'm trying to start off at that point within java, but I'm getting hung up on passing out my arraylist object into a for statement to be printed back out using the Item class methods.
HelloInvetory.java
package helloInventory;
import java.util.Arrays;
public class HelloInventory {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Object InvetoryItems;
Inventory inv = new Inventory();
inv.createItemObj(101, "camera", "Used camera that I bought off of a homeless guy.", 500);
InvetoryItems = inv.getAllInventoryItems();
for(Object item : InvetoryItems){
System.out.println(item.getItemName());
}
System.out.println("Done");
}
}
Inventory.java
package helloInventory;
import java.util.*;
/**
* Tracks and maintains all items within the inventory
* #author levi
*
*/
public class Inventory {
List<Object> InventoryItems = new ArrayList<Object>();
/*
* create object from Items class
* and insert into Object[] array.
*/
public void createItemObj(int sku, String name, String descriptor, float price) {
Items item = new Items();
item.setSku(sku);
item.setItemName(name);
item.setItemDescription(descriptor);
item.setItemPrice(price);
this.setInventoryItems(item);
}
public Object getAllInventoryItems() {
//return InventoryItems;
return this.InventoryItems.toArray();
}
public void setInventoryItems(Object inventoryItems) {
//InventoryItems.add(inventoryItems);
this.InventoryItems.add(inventoryItems);
}
}
Items.java
package helloInventory;
/**
* Class object to hold each item details
* #author levi
*
*/
public class Items {
int sku;
String itemName;
String itemDescription;
float itemPrice;
public int getSku() {
return sku;
}
public void setSku(int sku) {
this.sku = sku;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public String getItemDescription() {
return itemDescription;
}
public void setItemDescription(String itemDescription) {
this.itemDescription = itemDescription;
}
public float getItemPrice() {
return itemPrice;
}
public void setItemPrice(float itemPrice) {
this.itemPrice = itemPrice;
}
}
Where I am stuck is within the HelloInventory.java
for(Object item : InvetoryItems){
System.out.println(item.getItemName());
}
IDE (Eclipse) gives me the error "Can only iterate over an array or an instance of java.lang.Iterable". Is there something extra I need, or I'm I going around this totally the wrong way in Java? Correct example would be helpful.
Best,
Levi
You have a very strange architecture here my friend. You shouldn't be using generic Objects everywhere, but the actual types. First thing:
public Object getAllInventoryItems() {
//return InventoryItems;
return this.InventoryItems.toArray();
}
Why not just return the List itself?
public List<Item> getAllInventoryItems() {
return this.InventoryItems;
}
Also change this:
List<Item> InventoryItems = new ArrayList<Item>();
and this:
public void setInventoryItems(Item inventoryItems) {
this.InventoryItems.add(inventoryItems);
}
Now iterating the List is smooth sailing:
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Item> InvetoryItems;
Inventory inv = new Inventory();
inv.createItemObj(101, "camera", "Used camera that I bought off of a homeless guy.", 500);
InvetoryItems = inv.getAllInventoryItems();
for(Item item : InvetoryItems){
System.out.println(item.getItemName());
}
System.out.println("Done");
}
Btw, I changed Items to Item out of habit. A class name should indicate a single entity so by convention it's singular.
Now don't take this the wrong way, but you may have got off on the wrong foot with Java, so I highly recommend this reading: http://www.mindview.net/Books/TIJ/ This worked for me when I was starting with Java, maybe others can suggest some good sources as well.
Ok, two things. One is that Tudor is absolutely right, it's best to use the classes you're expecting directly, not Objects, and stylistically his points are accurate too.
Two is that if you really have to use a list of object, you'll need to cast back from object to whatever type it is that you're expecting to receive.
List<Object> list = inv.getAllInventoryItems();
for (Object item : list){
System.out.println((Items) item).getItemName();
}
However, I wouldn't recommend doing this as it effectively takes what should be a compile-time error and makes it a RunTime error (if the class cannot be cast).

Categories