Java - Passing a button click from one class to the main class - java

Firstly I am sure there is an answer lurking in this site and I did try and look but all the methods I tried continuously failed. I am still quite new at programming in Java so go easy on me, because what you are about to witness is some incredibly bodged code!
I am trying to learn Selenium, but before I write tests I wanted to make a simple IDE that asks what browser you'd like to run and what test you'd like to run. So far I had it running fine in a pop up for the browser but that wasn't useful if I wanted to add more options. So I am now trying to create a Jframe in my main class containing other classes which contain the content of any buttons I wish to add. Here is where things go wrong.
I have a combo box, this takes in a string of possible browsers and you pick one. (That works)
There is also a button which can read the current choice in the combo box. However this button does not seem to be passing the information back to my main class. I will post the code below.
CLASS 1 (MAIN)
public class DynamicBrowsers {
public static void main(String[] args) {
BrowserBox b = new BrowserBox();
JFrame IDE = new JFrame("IDE");
IDE.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BrowserBox newContentPane = new BrowserBox();
IDE.setContentPane(newContentPane);
IDE.setPreferredSize(new Dimension(200, 100));
IDE.pack();
IDE.setVisible(true);
WebDriver driver = null;
if(b.browserValue == 0){
//driver=new FirefoxDriver();
System.out.println("No browser Selected");
}else if(b.browserValue == 1){
driver = new ChromeDriver();
System.out.println("FF!");
}else if(b.browserValue == 2){
driver = new ChromeDriver();
System.out.println("Chrome!");
}else if(b.browserValue == 3){
driver = new InternetExplorerDriver();
System.out.println("IE!");
}
}
}
CLASS 2 (combo box and button)
public class BrowserBox extends JPanel {
public String browserPick;
String[] browsers = {"Please Select a Browser","Mozilla", "Chrome", "IE"};
public int browserValue = 0;
JButton runButton = new JButton("Run Test");
public JComboBox browserPicker = new JComboBox(browsers);
public BrowserBox() {
add(runButton);
add(browserPicker);
ActionListener cbActionListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent listChoice) {
String s = (String) browserPicker.getSelectedItem();//get the selected item
switch (s) {//check for a match
case "Please Select a Browser":
System.out.println(browserPick);
break;
case "Mozilla":
browserPick = "Mozilla";
System.out.println("Could have been a worse choice than " + browserPick);
break;
case "Chrome":
browserPick = "Chrome";
System.out.println("Good choice picking " + browserPick);
break;
case "IE":
browserPick = "IE";
System.out.println("For some reason you chose " + browserPick);
break;
default:
browserPick= "Please Select a Browser";
System.out.println("No match selected, defaulting too " + browserPick);
break;
}
}
};
ActionListener bActionListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent runClicked) {
if (browserPick == "Mozilla"){
browserValue = 1;
System.out.println("FF clicked " + browserValue);
}
else if (browserPick == "Chrome"){
browserValue = 2;
System.out.println("Chrome clicked " + browserValue);
}
else if (browserPick == "IE"){
browserValue = 3;
System.out.println("IE clicked " + browserValue);
}
}
};
browserPicker.addActionListener(cbActionListener);
runButton.addActionListener(bActionListener);
}
}
I imagine I am implementing it all wrong. I kind of feel like I should have made the button a seperate class or in the main class, but I'm unsure. If anyone could point me in the right direction, point out what I'm doing wrong and if possible offer a simple fix that would be great.
Thank you,
Farrell

There are a couple of things wrong here.
You declare two vars of type BrowserBox -- you use one and test the other (b and newContentPane).
You also use "==" to test whether one string is equal to another. That won't work in the general case; you need to use "String".equals(value) or some other form of the equals() method.
Good luck.

Unbelievable, It seems I had forgotten to capitalise the C in chrome at one point in a string compare and that is what cost me 2 hours of my life lol.
Thank you all for the input, now that I've worked out what was wrong I'm going to go back and try make it more object orientated by having only the JFrame in the main class. Ty again

Related

How to track mouse clicks as input in Java swing

I'm working on a personal project where I'm trying to create Simon game in Java. It is essentially a memory game where the user has to repeat the sequence the computer generates. So, I created a basic CLI version of the game and now I'm looking to give it a GUI. I haven't worked with Java Swing before so I'm having some trouble replicating the same behavior in GUI form.
The structure of the CLI version looked something like this:
public static void main(String[] args) {
GameContext simon = new GameContext();
simon.start();
while (!simon.getRoundEndState()) {
simon.playSequence();
simon.pickColour();
}
}
Here's what the playSequence() method looks like. It essentially generates a number between 0 and 3 and keeps adding one number to the array each round if the player gets the previous one right.
public void playSequence() {
int rand = getRandomNumber(4);
computerSequence.add(rand);
for(int i:computerSequence) {
System.out.println(i);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
gameContext.setState(gameContext.getHumanPlayingState());
}
pickColour() method that asks the user for the pattern and checks if the pattern matches the one generated by the computer.
public void pickColour() {
boolean roundWon = true;
for(int i=0; i<gameContext.getSequence().size();i++){
Scanner input = new Scanner(System.in);
Integer userInput = input.nextInt();
if(userInput == gameContext.getSequence().get(i)) {
continue;
}
else {
System.out.println("Input mismatched the sequence");
roundWon = false;
break;
}
}
if (roundWon == true) {
score++;
gameContext.setState(gameContext.getComputerPlayingState());
} else {
gameContext.setRoundEndState(true);
System.out.println("Your score is: " + score);
gameContext.setState(gameContext.getInLobbyState());
}
}
Please note that I'm using the state pattern here and hence the change in states. I got the first part working where I need to light up the colors after the computer generates the the sequence. So now, playSequence() looks something like this:
public void playSequence() {
int rand = getRandomNumber(4);
computerSequence.add(rand);
gameContext.setState(gameContext.getHumanPlayingState());
}
And I added a mouse listener to the start button which looks something like this:
btnStart.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent me) {
simon = new GameContext();
simon.start();
while (!simon.getRoundEndState()) {
simon.playSequence();
for(int i : simon.getSequence()) {
lightPanels(i);
Timer timer = new Timer(1000, e -> {
darkenPanels(i);
});
timer.setRepeats(false);
timer.start();
}
simon.pickColour();
}
}
});
I have 4 JPanels that now act as the input buttons. How do I change simon.pickColour() so that instead the asking the user for the correct sequence like it did in the CLI version, it would register the clicks made in the JPanels as the input.
It essentially generates a number between 0 and 3 and keeps adding one number to the array each round if the player gets the previous one right.
and
I have 4 JPanels that now act as the input buttons.
Why have 4 panels. Just have one panel that contains 4 buttons. You would then add an ActionListener to the button (not a MouseListner) to handle the clicking of the button.
The buttons would be created with code like:
for (int i = 1; i <= 4; i++)
{
JButton button = new JButton("" + i);
button.addActionListener(...);
panel.add( button );
}
The ActionListener code would then get the text of the button and add the text to an ArrayList to track the order the the buttons that have been clicked.
A working example of this approach of sharing an ActionListener for all the buttons can be found here: https://stackoverflow.com/a/33739732/131872. Note the "action command" will default from the text that is set on the button.

JComboBox DropDown list is not displayed

this might be a duplicate of JComboBox popup menu not appearing , but as it is a rather old question and not been active for quite some time, plus all the answers were not solutions, that helped with my problem. Thus I decided to create a new question.
The Problem is as follows:
I got an application of a prior colleque, that does not work at my company anymore. Now I tried adding a JComboBox to a JPanel. The JCombobox is displayed as expected, but it behaves in the same way as described by Seth in his question:
1) The first click on the expand button does nothing. The second click highlights the contents of the box, but the popup still doesn't appear.
2) Once I've clicked the button and given it focus, up/down keystrokes cycle through the entries correctly.
I have broken down the code to what I think is the minimum of needed programming, to have the problem occur. (As one comment in the mentioned question mentioned to provide SSCCE, which never happened).
Now here is the code I can provide:
public static class CreateProjectDialog extends JFrame {
private Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
public CreateProjectDialog() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
int SZ_INCR = 1;
// Passe Fontgröße an Resolution an:
if (size.width > 1920) {
SZ_INCR = 2;
}
// Initialize Glass Layer
final JPanel panelGlass = (JPanel) getGlassPane();
panelGlass.setLayout(null);
panelGlass.setVisible(true);
private static JPanel licBorrowPanel = null;
licBorrowPanel = new JPanel();
licBorrowPanel.setBounds(0, 20, 1000, 500);
licBorrowPanel.setVisible(false);
licBorrowPanel.setBackground(Color.WHITE);
panelGlass.add(licBorrowPanel);
}
public static void main(String[] args) {
hauptFrame = new CreateProjectDialog();
}
public static void licenceBorrowDialog() {
int mainWidth = hauptFrame.getSize().width;
int mainHeight = hauptFrame.getSize().height;
// pick a Date
JComboBox dayList = new JComboBox();
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
Calendar calToday = Calendar.getInstance();
Date dayToday = calToday.getTime();
int weekDay = calToday.get(Calendar.DAY_OF_WEEK);
String weekDayName = "";
for (int i = 1; i <= 22; i++){
dayToday.setDate(dayToday.getDate()+1);
weekDay = dayToday.getDay();
weekDayName = translateWeekDay(weekDay);
dayList.addItem(i + " day(s) until " + weekDayName + " " + df.format(dayToday));
}
dayList.setOpaque(true);
dayList.setSelectedIndex(2);
dayList.setBounds(mainWidth / 2 - (125*SZ_INCR), (165*SZ_INCR), (250*SZ_INCR), (100*SZ_INCR));
licBorrowPanel.add(dayList);
dayList.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
int numberOfDays;
JComboBox dl = (JComboBox)e.getSource();
numberOfDays = dl.getSelectedIndex()+1;
labelSelectedDate.setText("<HTML><BODY><b>Count of days: </b>" + numberOfDays + "</HTML></BODY>");
}
});
}
//Translate weekday int to name
public static String translateWeekDay(int day){
String retDay;
switch (day) {
case 0: retDay = "Monday";
break;
case 1: retDay = "Truesday";
break;
case 2: retDay = "Wednesday";
break;
case 3: retDay = "Thursday";
break;
case 4: retDay = "Friday";
break;
case 5: retDay = "Saturday";
break;
case 6: retDay = "Sunday";
break;
default: retDay = "Invalid day";
break;
}
return retDay;
}
}
I tried popoulating with more items (as proposed by jluzwick) to see, if the DropDown is simply hidden behind anything, but no.
I definitely have never used getRootPane() instead of getContentPane(), as suspected by Sehtim.
There is also JCombobox is not displayed , where the accepted answer is to set the setVisible(true) to the end of the constructor. I tried that and it did not change any behaviour in my case.
The question I need an answer to, is: How do I make the DropDown list visible, to enable the user to easily choose an entry?
Thanks MadProgrammer for the hint regarding the code not compiling - I found a solution and will provide it here for anyone having a similar issue.
The problem was a result of mixing heavy weight and light weight components (awt / swing).
This resulted in the light weight popup being used, which was then probably occluded by other components and thus not visible.
The solution ( if the mix of both heavy and light weight has to stay ) is to disable the light weight popup forcing the application to use a backup popup. This is done by replaceing the following line:
dayList.setSelectedIndex(2);
With this line:
dayList.setLightWeightPopupEnabled (false);
I found the solution here:
http://de.comp.lang.java.narkive.com/t2GPS9vy/jcombobox-poppt-nicht-auf

How do I use the information from an option pane in an if statement

I'm trying to figure out how to assign a name/title to the options used in an option pane so that I can use them in an if-statement. Here's the code I have so far:
int i = 0;
while(i<1){
JFrame frame = new JFrame();
String[] options = new String[2];
options[0] = new String("Peat");
options[1] = new String("Repeat");
JOptionPane.showOptionDialog(frame.getContentPane(),"Peat and Repeat were walking on a bridge\nPeat fell off, "
+ "who was left?","", 0,JOptionPane.INFORMATION_MESSAGE,null,options,null);
}
What would you recommend I do next to finish this "joke"?
I think what you mean by your question is how do you determine what option was selected by the user? JOptionPane.showOptionDialog returns the index of the selected option. So you can do something like:
import javax.swing.*;
public class Example {
public static void main(String[] args) {
String[] options = {"Peat", "Repeat"};
int selectedOption = JOptionPane.showOptionDialog(null,"Peat and Repeat were walking on a bridge\nPeat fell off, who was left?","", JOptionPane.DEFAULT_OPTION,JOptionPane.INFORMATION_MESSAGE,null,options,null);
if(selectedOption == 0) System.out.println("Peat selected");
else System.out.println("Repeat selected");
}
}
When the user selects "Peat" it will print "Peat selected".
When they selected "Repeat" it will print "Repeat selected"

Changing text size of the text someone using my program sees?

Glad to be on this very helpful website. I have a problem with my Java program that will probably either be an easy fix, or impossible to fix.
You know how when you run a program that's open in NetBeans, it shows the output within the NetBeans application? I am trying to create a program that allows anybody who puts it on their computer to execute it, even if they have not installed an IDE like NetBeans or Eclipse. And when somebody executes my program, I want it to show the same thing as when I run it in NetBeans, with the same output and everything. The program doesn't use a GUI or anything like that. I managed to create an executable .jar file with the "Clean and build project" option, and I made a .bat file that successfully executes the program. This should achieve my goal of allowing anyone to run it. When I start up the .bat file, it works, and shows a white-text-black-background screen that runs the program exactly as it ran while in NetBeans.
The problem is that when I run the program (with the .bat file), the text is too small... I've tried looking everywhere for a solution to this, but I could only find discussion about how to make things work with GUIs, or other more complicated things than what my program needs. I am willing to work with GUI stuff if it is necessary, but I don't think it will help, due to what a GUI is. From my understanding, a GUI is not one big thing, but is a user interface composed of smaller parts (such as pop-up input prompts and scroll bars) that are each made by the programmer. I don't need any fancy scroll bars etc., I just need my program to execute like it does when ran in NetBeans (pretty sure this is called the console), and I need to change the text size of the program text when it executes.
I greatly appreciate any help, even if you aren't sure if it will work or not. If the answer requires a lengthy explanation and you don't feel like explaining, that's okay; just tell me what I'd have to learn to figure this out and I can research it if necessary.
I just created one. Try using this one and tell us if it helped or not.
EDIT Added a JTextField to read data. It is more advanced code than the previous one, since it uses concurrency. I tried to make it simple, these are the functions you can use:
MyConsole (): Constructor. Create and show the console
print (String s): Print the s String
println (String s) Print the s String and add a new line
read (): Makes you wait untill the user types and presses Enter
closeConsole (): Closes the console
Here is the code:
public class MyConsole implements ActionListener {
private JFrame frame;
private JTextArea myText;
private JTextField userText;
private String readText;
private Object sync;
/*
* Main and only constructor
*/
public MyConsole() {
// Synchronization object
sync = new Object();
// Create a window to display the console
frame = new JFrame("My Console");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 200);
frame.setLocationRelativeTo(null);
frame.setResizable(true);
frame.setContentPane(createUI());
frame.setVisible(true);
}
/*
* Creates user interface
*/
private Container createUI() {
// Create a Panel to add all objects
JPanel panel = new JPanel (new BorderLayout());
// Create and set the console
myText = new JTextArea();
myText.setEditable(false);
myText.setAutoscrolls(true);
myText.setBackground(Color.LIGHT_GRAY);
// This will auto scroll the right bar when text is added
DefaultCaret caret = (DefaultCaret) myText.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
// Create the input for the user
userText = new JTextField();
userText.addActionListener(this);
panel.add(new JScrollPane(myText), BorderLayout.CENTER);
panel.add(userText, BorderLayout.SOUTH);
return panel;
}
/*
* Waits until a value is typed in the console and returns it
*/
public String read(){
print("==>");
synchronized (sync) {
try {
sync.wait();
} catch (InterruptedException e) {
return readText = "";
}
}
return readText;
}
/*
* Prints s
*/
public synchronized void print(String s){
// Add the "s" string to the console and
myText.append(s);
}
/*
* Prints s and a new line
*/
public synchronized void println(String s){
this.print(s + "\r\n");
}
/*
* Close the console
*/
public void closeConsole(){
frame.dispose();
}
#Override
public void actionPerformed(ActionEvent e) {
// Check if the input is empty
if ( !userText.getText().equals("") ){
readText = userText.getText();
println(" " + readText);
userText.setText("");
synchronized (sync) {
sync.notify();
}
}
}
}
Here is how to use it (an example). It just asks your age and writes something depending on your input:
public static void main(String[] args) {
MyConsole console = new MyConsole();
console.println("Hello! (Type \"0\" to exit)");
int age = 1;
do{
console.println("How old are you ?");
String read = console.read();
try {
age = Integer.valueOf(read);
if ( age >= 18){
console.println("Wow! " + age + " ? You are an adult already!");
}else if ( age > 0 ){
console.println("Oh! " + age + " ? You are such a young boy!");
}else if (age == 0){
console.println("Bye bye!");
}else{
console.println("You can't be " + age + " years old!");
}
}catch (Exception e) {
console.println("Did you write any number there ?");
}
} while ( age != 0 );
console.closeConsole();
}
And here is a image:

Return a String from a JButton press Action Listener?

I've been trying for a while to get a JButton I have to return a string and I have it working to an extent however it only works when i'm using the System.out.println() method.
My Relevant Code:
private String answer;
public void inputDataButton(JButton inButton)
{
inButton.addActionListener(new Action1());
}
public String returnAnswer()
{
return answer;
}
private void fileAnswer(String inString)
{
answer = new String(inString);
}
public class Action1 implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String sub = JOptionPane.showInputDialog("Input The Date");
fileAnswer(sub);
}
}
With my Main controlling it:
public class test
{
protected static JTextField text;
public static void main(String[] args)
{
javaUI base = new javaUI("Date Killer", 800, 800);
JLabel label = new JLabel("Place Holder");
base.addLabel(label, 1, 0, false);
JButton button = new JButton("Press Here");
base.addButton(button, 0, 0, false);
String str = "EMPTY";
base.inputDataButton(button);
while (str == "EMPTY")
{
str = base.returnAnswer();
}
System.out.println(str + " TEST");
label.setText(str + "SETTED");
}
}
JavaUI is simply another class with simplifies the entire JFrame and Jpanel setup for Labels, Buttons etc.
Anyways, heres my problem. In the main class, in the while statement, str is successfully set to the string if I have a System.out.println() statement directly after.
This obviously makes quite a mess of the terminal as it repeates "EMPTY" 100+ times until the button is pressed.
However if I remove that statement, nothing is obviously printed out, but str is never set to the str either.
I've been messing around with this for quite a while (New to all java UI stuff, mainly just worked in the calculations part of things) and I've yet to find a working solution that doesn't make a mess of my terminal. Thanks for all the Help!!!
Cail
1) It's a little strange to use a loop to "wait" for the action to happen. You can watch your cpu usage and it could be dead if it loops forever.
2) Also, the method will return no matter whether your button is clicked -- Before the action happens, the method returns a null string according to your code. And in your main method, str == "EMPTY" soon becomes false after the first round. Then you'll see "null TEST" on your screen.
Try to put the code after while loop into actionPerformed method or fileAnswer method and delete the loop:
public void actionPerformed(ActionEvent e)
{
String sub = JOptionPane.showInputDialog("Input The Date");
System.out.println(sub + " TEST");
label.setText(sub + "SETTED");
}
Also, I am not sure why you call answer = new String(inString). If you want to assign it to another variable, you only need to call answer = inString since String is unmodifiable. And in this case, you don't to do this.

Categories

Resources