What is first argument in 'JOptionPane.showConfirmDialog() here? - java

Here is the below code snippet, where i would like to display the dialog using JOptionPane.showConfirmDialog() by setting its parent as resultsTablePanel:
public class SearchResultsTablePanel extends JPanel{...}
public class DefaultSearchListener{
private SearchResultsTablePanel resultsTablePanel = null;
public void f(X x) {
int response = JOptionPane.showConfirmDialog(
resultsTablePanel,
"hai",
"Warning", JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE);
if (response == JOptionPane.NO_OPTION) {
// do something
} else if (response == JOptionPane.YES_OPTION) {
// do something
} else if (response == JOptionPane.CLOSED_OPTION) {
// do something
}
}
}
My question:
For java swing api JOptionPane.showConfirmDialog(),
Do i need to pass resultsTablePanel as first argument?
or
Do i need to pass JOptionPane.getframeforcomponent(resultsTablePanel) as first argument?

It doesn't really matter.
As part of the processing, JOptionPane invokes getWindowForComponent on the argument before passing it through to the underlying JDialog (which is slightly more general).
As for the implicit question "What's the difference anyway?", well this has to do with modality. Here I would urge you to read Oracle's guide to modality.
JOptionPane uses the default modality type for JDialog, which is the Application-modal from the guide above. This means that the dialog will block input to all windows in the application, except windows that have the dialog as the parent. Hence, if you open 2 dialogs that have the same parent - you're in trouble, but if one has the other as the parent - then the child has controls and will transfer them to their parent once closed.

Related

Is there a way to update a variable outside a method that is used as a parameter in said method?

I have 62 check boxes on 2 different panels.
30 of them on each panel are for selecting PC names while 1 on each selects all.
So on each of those 60 that are just selecting items I have this code:
private void HP04ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
setComponent(HP04, blrS,all_blr);
HP04 is the name of a checkbox for one of the PCs, blrS is the name of an int that counts how many checkboxes are selected(there is another int for the boxes on the other panel), all_blr is the name of the checkbox that selects all on the blr panel.
This is the method I used:
public void setComponent(javax.swing.JCheckBox component, int room,javax.swing.JCheckBox all)
{
System.out.println("Inside Component: "+component.isSelected()); //testing to see if the method is actually being called
if (component.isSelected()){ //if checkbox is checked
room++; //records how many boxes are checked
if (room == 30)
{
all.setSelected(true);//autochecks "all" check box if all PCs are selected
}
if (!messagearea.getText().equals(""))
{
sendb.setEnabled(true);//if any boxes are checked and the message area is populated, enable the button
}
}
else
{
room--;//records how many boxes are checked
all.setSelected(false);//unchecks the "all" check box if not all of them are checked
if (room == 0)
{
sendb.setEnabled(false);//disables button if no PCs are selected to be messaged
}
}
System.out.println(room); //testing int updates based on UI changes
}
Now the problem is room is only fetching the value of whatever variable is put in that parameter and then room itself is being modified. So in the example setComponent(HP04, blrS,all_blr); blrS is never changed.
I know the code inside the method works, it worked before I decided to cut down on code by using a method, as before I had the code inside the method in the actionperformed for every checkbox before hand... Like this:
private void HP04ActionPerformed(java.awt.event.ActionEvent evt) {
if (HP04.isSelected()){
blrS++;
if (blrS == 30)
{
all_blr.setSelected(true);
}
if (!messagearea.getText().equals(""))
{
sendb.setEnabled(true);
}
}
else
{
blrS--;
all_blr.setSelected(false);
if (blrS == 0)
{
sendb.setEnabled(false);
}
}
System.out.println(blrS);
}
It's just understanding how parameters and methods works that is tripping me up.
It feels obvious that what I'm doing shouldn't work, room is a variable inside the method... But how do I change that?
Solution found:
"Why not return room from the method, and assign it to the variable when you call it? blrS = setComponent(HP04, blrS, all_blr);"
– Rob Spoor (in the comments to this post)

Trying to delete from the grid under certain condition

private void delete() {
if(customer.getStatus() == status.toString("Not Contacted")) {
service.delete(customer);
myUI.updateList();
setVisible(false);
}else {
Notification.show("you cannot delete this");
}
The error I get says "The method toString() in the type object is not applicable for the arguments (string)"
What I want to do is to let the delete function work only if the status is NotContacted.
What you want is
if(customer.getStatus() == status.toString().equals("Not Contacted")) {...}
Though you should want to give status a proper type to make a type-safe comparison. I suggest looking up on Enums (https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html) so that your code becomes something like
if(customer.getStatus() == Status.NOT_CONTACTED)) {...}

JPanel not visible

I've been having a problem with my program that has been driving me crazy and I cannot understand why this is happening. I have a GUI that when the "Add" button is pressed, a new system listing appears (Which is a class called SystemPanel that extends JPanel and cotains system details, which is created and then put into the Frame's main panel.)
To put it shortly, when I try to add a new SystemPanel, it does not appear for whatever reason. I have code using JSch that connects to the system and verifies whether its processes are online or not, but the line of code that does this is after the creation of the SystemPanel. It is only after the code for testing the processes of the system are executed that the SystemPanel becomes visible, and I can't understand why this is the case. Here is the code for adding a new SystemPanel:
public void actionPerformed(ActionEvent e) {
//If the "Add" button is pressed
if (e.getActionCommand() == "Add") {
PopupWindow popup = new PopupWindow(this);
popup.setVisible(true);
String[] results = popup.getResults();
if (results[0] != null && results[1] != null && results[2] != null && results[3] != null && results[4] != null) {
SystemPanel newSystem = new SystemPanel(this, results[0], results[1], results[2], results[3], results[4]);
systemsPanel.add(newSystem);
revalidate();
systemsList.add(newSystem);
System.out.println("Did the stuff");
boolean[] status = SystemChecker.checkOnline(results[0], results[1], results[2], results[3]);
}
}
}
The PopupWindow is a custom JDialog that allows the user to enter the required information which is returned in a String array and is used to create a new SystemPanel. The checkOnline function grabs the user's inputs and uses them to connect to the system and determine whether the processes are working or not, and returns the results into a boolean array, true for working, false for not.
What's even weirder is that I have another part of my program that reads from an .ini file to obtain existing systems and then creates SystemPanels based on the data that it reads. Through this method, the SystemPanels are added the way I want and work perfectly for some reason, even though the code for adding the panels is hardly any different. Code:
for (int i = 0; i < systems.size(); i++) {
SystemPanel newSystem = new SystemPanel(this, systems.get(i)[0], systems.get(i)[1], systems.get(i)[2], systems.get(i)[3], systems.get(i)[4]);
systemsPanel.add(newSystem);
revalidate();
systemsList.add(newSystem);
}
for (int i = 0; i < lineNum; i++) {
boolean[] status = SystemChecker.checkOnline(systems.get(i)[0], systems.get(i)[1], systems.get(i)[2], systems.get(i)[3]);
systemsList.get(i).updateIcons(status);
}
This code grabs the details from the file and then makes the SystemPanels based on those details. Here, all of the SystemPanels are added and show up before the connection is tested, which is what I want to happen when I add one normally.
Why is it that the SystemPanel doesn't appear until the connection is tested, even though the code for displaying the SystemPanel is executed before the connection test? Any help would be greatly appreciated, thanks.
Try it of the current event queue handling, on which actionPerformed is done.
public void actionPerformed(ActionEvent e) {
EventQueue.invokeLater(() -> { ... your code here ... });
}
Also you cannot add the same component to two parents, every component object has a single parent (container).
(Java 8 notation)

How to simplify long list of similar if statements?

I work as an automation engineer for my company. Recently, I wrote a piece of code that my manager absolutely would not accept.
I was asked to write some scripts for test cases involving different pieces of the GUI. The part of the code my manager would not accept was an if/else statement meant to check the current language of the prompt in the GUI.
I've been instructed to use Sikuli, and as such, it is very important that I know what language the application is currently set to so my scripts can click the correct buttons (which change depending on the language).
My thoughts were that the code iterates through the if/else statement and then points to the correct button. Example: The if/else statement determines that the "ok" button is currently the Suomi translation, so it will than click the correct button.
Here is an example of my code:
switch (button) {
case "ok":
if (s.exists("imagerepo/language/catalan_ok.png") != null) {
s.click("imagerepo/language/catalan_ok.png");
} else if (s.exists("imagerepo/language/suomi_ok.png") != null) {
s.click("imagerepo/language/suomi_ok.png");
} else if (s.exists("imagerepo/language/italian_ok.png") != null) {
s.click("imagerepo/language/italian_ok.png");
} else if (s.exists("imagerepo/language/portuguese_ok.png") != null) {
s.click("imagerepo/language/portuguese_ok.png");
} else if (s.exists("imagerepo/language/english_ok.png") != null) {
s.click("imagerepo/language/english_ok.png");
} else if (s.exists("imagerepo/language/dutch_ok.png") != null) {
s.click("imagerepo/language/dutch_ok.png");
} else if (s.exists("imagerepo/language/spanish_ok.png") != null) {
s.click("imagerepo/language/spanish_ok.png");
} else if (s.exists("imagerepo/language/french_ok.png") != null) {
s.click("imagerepo/language/french_ok.png");
} else if (s.exists("imagerepo/language/latina_ok.png") != null) {
s.click("imagerepo/language/latina_ok.png");
} else if (s.exists("imagerepo/language/chinese_ok.png") != null) {
s.click("imagerepo/language/chinese_ok.png");
}
break;
...etc..
My only gripe with the above code is that it is pretty ugly. Functionally it does exactly what I'd like it to, 100% of the time.
EDIT: I figure that having a switch that adapts to the potentially changing button would be better than having 10 switches for the same button. Arguably, against what I just said, if I'm writing the scripts, I will always know what language the system is going to be in.
If this is an example of poor code, what could I do instead to determine which "form" of the button I need to press?
It would be worth noting now that the answer I'm looking for does not actually pertain to testing at all, but rather, how do I optimally perform the function of that if/else block above?
Something like:
String[] languages = {
"catalan_ok.png",
"suomi_ok.png",
//...
}
for (String base : languages) {
String file = String.format("imagerepo/language/%s", base);
if (s.exists(file) != null) {
s.click(file);
break;
}
}
perhaps? Not tested.
I'm assuming that this is for internationalization so you could use a properties file for each language and then get the image path like this
ResourceBundle bundle = ResourceBundle.getBundle( "messages", userLocale );
s.click(bundle.getString("image"));

Find all modal dialogs belonging to a frame

I need to be able to tell if there are any modal dialogs open in my application. Is there any way to do this?
Solution
Alright, so based on the accepted answer, this is what I came up with do accomplish what I needed:
Window[] wins : myMainFrame.getOwnedWindows();
for(Window w : wins) {
if(w instanceof JDialog) {
JDialog jd = (JDialog)w;
if(jd.isModal() && jd.isVisible()) {
// back out of current operation (return null in my case)
return null;
}
}
Perhaps calling Window's getOwnedWindows() is what you're looking for, and all class that derive from Window will have this method, including JFrame and JDialog.
But I agree that more context would help!

Categories