Buttons within buttons in java GUI - java
I want to create buttons within buttons in java gui, so I have a bunch of buttons and within those buttons there's more buttons but whenever I try to make a for-loop for those buttons nothing happens. Here is my code
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.ImageIcon;
import java.net.URL;
import java.awt.Dimension;
import javax.swing.JOptionPane;
import java.awt.*;
import javax.swing.ImageIcon;
import java.awt.Dimension;
public class Elements extends JPanel implements ActionListener {
JButton c_one[] = new JButton[4];
JButton c_two[] = new JButton[4];
JButton c_three[] = new JButton[4];
JButton c_four[] = new JButton[4];
JButton THINGY [] = new JButton[1];
// buttons for column one row 0
JButton btn1 = new JButton("Nicosia");
JButton btn2 = new JButton("Mumbai");
JButton btn3 = new JButton("Dubait");
JButton btn4 = new JButton("Romania");
// buttons for column one row 1
JButton btna = new JButton("semihemidemisemiquaver ");
JButton btnb = new JButton("semidemiquaver");
JButton btnc = new JButton("qaver");
JButton btnd = new JButton("stop note");
// button column one row 2
JButton btne = new JButton("23 ");
JButton btnf = new JButton("27");
JButton btng = new JButton("72");
JButton btnh = new JButton("4");
// button colooum one row 3
JButton btnE = new JButton("Pinky");
JButton btnF = new JButton("Cotten Candy");
JButton btnG = new JButton("Lady");
JButton btnH = new JButton(" The Other Tide.");
// button column two row 0
JButton btn10 = new JButton("\tEverything about you");
JButton btn20 = new JButton("All about the thing in the janitors closet");
JButton btn30 = new JButton("If Dubait is real or not");
JButton btn40 = new JButton("12");
// button column two row 1
JButton btn00 = new JButton("$63,645, ");
JButton btn01 = new JButton("$120 000");
JButton btn02 = new JButton("$15");
JButton btn03 = new JButton("$64 200");
// button column two row 2
JButton btn04 = new JButton("True ");
JButton btn05 = new JButton("False");
// button column two row 3
JButton btnaa = new JButton("\tMr. Penny");
JButton btnbb = new JButton("Mr. Dime");
JButton btncc = new JButton("Mr. Nickel");
JButton btndd = new JButton("Mr.Dollar");
// button column three row 1
JButton btn06 = new JButton("\tDr. Harold Shipman");
JButton btn07 = new JButton("Jesse James.");
JButton btn08 = new JButton("Pablo Escobar");
JButton btn09 = new JButton("Al Capone");
// button column three row 2
JButton btnaaa = new JButton("\tTrue");
JButton btnbbb = new JButton("False");
JButton btnddd = new JButton("Only in the bladder");
// button column three row 3
JButton btnEE = new JButton("20% ");
JButton btnFF = new JButton("6 to 9%,");
JButton btnGG = new JButton("11-17%");
JButton btnHH = new JButton("34%");
// button column three row 4
JButton question11 = new JButton("Does stretching delay muscle soreness");
JButton btn12 = new JButton("Stretching before or after exercise does NOT reduce muscle soreness ");
JButton btn13 = new JButton("Stretching before or after exercise DOES reduce soreness");
// JPanel.setBackground(Color.YELLOW);
int PE = 0;
GridBagConstraints constraints = new GridBagConstraints(); // this variable will set the coordinates of each button
String icon[] = { "ont.jpg", "oet.jpg", "cm.jpg","riddles.jpg","stw.jpg" };
public Elements() {
setLayout(new GridBagLayout());
constraints.insets = new Insets(5, 5, 5, 5); // borders
for (int k = 0; k < (c_one.length); k++) {
c_one[k] = new JButton();
constraints.gridx = 0;
++constraints.gridy;
c_one[k].setIcon(
new ImageIcon(new ImageIcon(icon[0]).getImage().getScaledInstance(150, 100, java.awt.Image.SCALE_SMOOTH)));
add(c_one[k], constraints);
c_one[k].addActionListener(this);
}
constraints.gridy = -1; // setting the gridy to be negative one so the loop will iterate starting at
// gridy = 0
for (int j = 0; j < (c_two.length); j++) {
c_two[j] = new JButton();
constraints.gridx = 1;
++constraints.gridy;
c_two[j].setIcon(
new ImageIcon(new ImageIcon(icon[1]).getImage().getScaledInstance(150, 100, java.awt.Image.SCALE_SMOOTH)));
add(c_two[j], constraints);
c_two[j].addActionListener(this);
}
// gridy = 0;
constraints.gridy = -1;
for (int m = 0; m < (c_three.length); m++) {
c_three[m] = new JButton();
constraints.gridx = 2;
++constraints.gridy;
c_three[m].setIcon(
new ImageIcon(new ImageIcon(icon[2]).getImage().getScaledInstance(150, 100, java.awt.Image.SCALE_SMOOTH)));
add(c_three[m], constraints);
c_three[m].addActionListener(this);
}
constraints.gridy = -1; // setting the gridy to be negative one so the loop will iterate starting at
// gridy = 0
for (int j = 0; j < (c_four.length); j++) {
c_four[j] = new JButton();
constraints.gridx = 3;
++constraints.gridy;
c_four[j].setIcon(
new ImageIcon(new ImageIcon(icon[3]).getImage().getScaledInstance(150, 100, java.awt.Image.SCALE_SMOOTH)));
add(c_four[j], constraints);
c_four[j].addActionListener(this);
}
constraints.gridy = -1; // setting the gridy to be negative one so the loop will iterate starting at
// gridy = 0
for (int j = 0; j < (THINGY.length); j++) {
THINGY[j] = new JButton();
constraints.gridx = 6;
++constraints.gridy;
THINGY[j].setIcon(
new ImageIcon(new ImageIcon(icon[4]).getImage().getScaledInstance(150, 100, java.awt.Image.SCALE_SMOOTH)));
add(THINGY[j], constraints);
THINGY[j].addActionListener(this);
}
JButton pointsEarned = new JButton("Points Earned");
constraints.fill = GridBagConstraints.VERTICAL;
constraints.ipady = 20;
constraints.gridx = 3;
constraints.gridy = 0;
constraints.anchor = GridBagConstraints.PAGE_START;
add(pointsEarned, constraints);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == c_one[0]) {
System.out.println(" For 200 points. What is the capital of Cyprus?");
JFrame frame = new JFrame("200");
JPanel panel = new JPanel();
panel.setBounds(55, 55, 400, 200);
panel.setBackground(Color.BLUE);
JButton question1 = new JButton("For 200 points. What is the capital of Cyprus?");
question1.setBounds(50, 100, 160, 80);
question1.setBackground(Color.ORANGE);
panel.add(question1);
btn2.setBounds(50, 100, 80, 30);
btn2.setBackground(Color.ORANGE);
btn1.setBounds(50, 100, 80, 30);
btn1.setBackground(Color.ORANGE);
panel.add(btn1);
panel.add(btn2);
btn3.setBounds(50, 100, 80, 30);
btn3.setBackground(Color.ORANGE);
panel.add(btn3);
btn4.setBounds(50, 100, 80, 30);
btn4.setBackground(Color.ORANGE);
panel.add(btn4);
frame.add(panel);
frame.setSize(535, 250);
frame.setLayout(null);
frame.setVisible(true);
} else if (e.getSource() == c_one[1]) {
System.out
.println("For 400 points. What is a note that is played for half the duration of a thirty second note?");
JFrame frame2 = new JFrame("400");
JPanel panel = new JPanel();
panel.setBounds(55, 55, 400, 200);
panel.setBackground(Color.BLUE);
JButton question2 = new JButton("In music, a hundred twenty-eighth note is known as?");
question2.setBounds(50, 100, 160, 80);
question2.setBackground(Color.ORANGE);
panel.add(question2);
btna.setBounds(50, 100, 80, 30);
btna.setBackground(Color.ORANGE);
btnb.setBounds(50, 100, 80, 30);
btnb.setBackground(Color.ORANGE);
panel.add(btna);
panel.add(btnb);
btnc.setBounds(50, 100, 80, 30);
btnc.setBackground(Color.ORANGE);
panel.add(btnc);
btnd.setBounds(50, 100, 80, 30);
btnd.setBackground(Color.ORANGE);
panel.add(btnd);
frame2.add(panel);
frame2.setSize(535, 250);
frame2.setLayout(null);
frame2.setVisible(true);
}
if (e.getSource() == c_one[2]) {
JFrame frame3 = new JFrame("600");
JPanel panel = new JPanel();
panel.setBounds(55, 55, 400, 200);
panel.setBackground(Color.BLUE);
JButton question3 = new JButton("How many times was Caesar stabbed by his senators?");
question3.setBounds(50, 100, 160, 80);
question3.setBackground(Color.ORANGE);
panel.add(question3);
btne.setBounds(50, 100, 80, 30);
btne.setBackground(Color.ORANGE);
btnf.setBounds(50, 100, 80, 30);
btnf.setBackground(Color.ORANGE);
panel.add(btne);
panel.add(btnf);
btng.setBounds(50, 100, 80, 30);
btng.setBackground(Color.ORANGE);
panel.add(btng);
btnh.setBounds(50, 100, 80, 30);
btnh.setBackground(Color.ORANGE);
panel.add(btnh);
frame3.add(panel);
frame3.setSize(535, 250);
frame3.setLayout(null);
frame3.setVisible(true);
} else if (e.getSource() == c_one[3]) {
JFrame frame4 = new JFrame("800");
JPanel panel = new JPanel();
panel.setBounds(55, 55, 400, 200);
panel.setBackground(Color.BLUE);
JButton question4 = new JButton("Louisiana is home to a rare pink dolphin named:");
question4.setBounds(50, 100, 160, 100);
question4.setBackground(Color.ORANGE);
panel.add(question4);
btnE.setBounds(50, 100, 80, 30);
btnE.setBackground(Color.ORANGE);
btnF.setBounds(50, 100, 80, 30);
btnF.setBackground(Color.ORANGE);
panel.add(btnE);
panel.add(btnF);
btnG.setBounds(50, 100, 80, 30);
btnG.setBackground(Color.ORANGE);
panel.add(btnG);
btnH.setBounds(50, 100, 80, 30);
btnH.setBackground(Color.ORANGE);
panel.add(btnH);
frame4.add(panel);
frame4.setSize(535, 250);
frame4.setLayout(null);
frame4.setVisible(true);
}
// array 2
if (e.getSource() == c_two[0]) {
JFrame frame = new JFrame("200");
JPanel panel = new JPanel();
panel.setBounds(55, 55, 400, 200);
panel.setBackground(Color.BLUE);
JButton question1 = new JButton("What do teachers know?");
question1.setBounds(50, 100, 160, 80);
question1.setBackground(Color.ORANGE);
panel.add(question1);
btn10.setBounds(50, 100, 80, 30);
btn10.setBackground(Color.ORANGE);
btn20.setBounds(50, 100, 80, 30);
btn20.setBackground(Color.ORANGE);
panel.add(btn10);
panel.add(btn20);
btn30.setBounds(50, 100, 80, 30);
btn30.setBackground(Color.ORANGE);
panel.add(btn30);
btn40.setBounds(50, 100, 80, 30);
btn40.setBackground(Color.ORANGE);
panel.add(btn40);
frame.add(panel);
frame.setSize(535, 250);
frame.setLayout(null);
frame.setVisible(true);
} else if (e.getSource() == c_two[1]) {
System.out.println("Who is my physics teacher");
JFrame frame2 = new JFrame("400");
JPanel panel = new JPanel();
panel.setBounds(55, 55, 400, 200);
panel.setBackground(Color.BLUE);
JButton question2 = new JButton("Who is my physics teacher?");
question2.setBounds(50, 100, 160, 80);
question2.setBackground(Color.ORANGE);
panel.add(question2);
btnaa.setBounds(50, 100, 80, 30);
btnaa.setBackground(Color.ORANGE);
btnbb.setBounds(50, 100, 80, 30);
btnbb.setBackground(Color.ORANGE);
panel.add(btnaa);
panel.add(btnbb);
btncc.setBounds(50, 100, 80, 30);
btncc.setBackground(Color.ORANGE);
panel.add(btncc);
btndd.setBounds(50, 100, 80, 30);
btndd.setBackground(Color.ORANGE);
panel.add(btndd);
frame2.add(panel);
frame2.setSize(535, 250);
frame2.setLayout(null);
frame2.setVisible(true);
}
if (e.getSource() == c_two[2]) {
JFrame frame4 = new JFrame("600");
JPanel panel = new JPanel();
panel.setBounds(55, 55, 400, 200);
panel.setBackground(Color.BLUE);
JButton question4 = new JButton("How much do teachers get payed on average");
question4.setBounds(50, 100, 160, 100);
question4.setBackground(Color.ORANGE);
panel.add(question4);
btn00.setBounds(50, 100, 80, 30);
btn00.setBackground(Color.ORANGE);
btn01.setBounds(50, 100, 80, 30);
btn01.setBackground(Color.ORANGE);
panel.add(btn00);
panel.add(btn01);
btn02.setBounds(50, 100, 80, 30);
btn02.setBackground(Color.ORANGE);
panel.add(btn02);
btn03.setBounds(50, 100, 80, 30);
btn03.setBackground(Color.ORANGE);
panel.add(btn03);
frame4.add(panel);
frame4.setSize(535, 250);
frame4.setLayout(null);
frame4.setVisible(true);
} else if (e.getSource() == c_two[3]) {
JFrame frame3 = new JFrame("800");
JPanel panel = new JPanel();
panel.setBounds(55, 55, 600, 800);
panel.setBackground(Color.BLUE);
JButton question3 = new JButton("For every 10 Canadian teachers, at least 4 have endured violence from students");
question3.setBounds(50, 100, 160, 180);
question3.setBackground(Color.ORANGE);
panel.add(question3);
btn04.setBounds(50, 100, 80, 30);
btn04.setBackground(Color.ORANGE);
btn05.setBounds(50, 100, 80, 30);
btn05.setBackground(Color.ORANGE);
panel.add(btn04);
panel.add(btn05);
frame3.add(panel);
frame3.setSize(800, 500);
frame3.setLayout(null);
frame3.setVisible(true);
}
// array 3
if (e.getSource() == c_three[0]) {
JFrame frame = new JFrame("200");
JPanel panel = new JPanel();
panel.setBounds(55, 55, 400, 200);
panel.setBackground(Color.BLUE);
JButton question1 = new JButton("The most prolific modern serial killer is:");
question1.setBounds(50, 100, 160, 80);
question1.setBackground(Color.ORANGE);
panel.add(question1);
btn06.setBounds(50, 100, 80, 30);
btn06.setBackground(Color.ORANGE);
btn07.setBounds(50, 100, 80, 30);
btn07.setBackground(Color.ORANGE);
panel.add(btn06);
panel.add(btn07);
btn08.setBounds(50, 100, 80, 30);
btn08.setBackground(Color.ORANGE);
panel.add(btn08);
btn09.setBounds(50, 100, 80, 30);
btn09.setBackground(Color.ORANGE);
panel.add(btn09);
frame.add(panel);
frame.setSize(535, 250);
frame.setLayout(null);
frame.setVisible(true);
} else if (e.getSource() == c_three[1]) {
JFrame frame2 = new JFrame("400");
JPanel panel = new JPanel();
panel.setBounds(55, 55, 400, 200);
panel.setBackground(Color.BLUE);
JButton question2 = new JButton("Urine is sterile\t");
question2.setBounds(50, 100, 160, 80);
question2.setBackground(Color.ORANGE);
panel.add(question2);
btnaaa.setBounds(50, 100, 80, 30);
btnaaa.setBackground(Color.ORANGE);
btnbbb.setBounds(50, 100, 80, 30);
btnbbb.setBackground(Color.ORANGE);
panel.add(btnaaa);
panel.add(btnbbb);
btnddd.setBounds(50, 100, 80, 30);
btnddd.setBackground(Color.ORANGE);
panel.add(btnddd);
frame2.add(panel);
frame2.setSize(535, 250);
frame2.setLayout(null);
frame2.setVisible(true);
}
if (e.getSource() == c_three[2]) {
JFrame frame4 = new JFrame("600");
JPanel panel = new JPanel();
panel.setBounds(55, 55, 400, 200);
panel.setBackground(Color.BLUE);
JButton question4 = new JButton("The Amazon rainforest provides ___% of Earth's oxygen. ");
question4.setBounds(50, 100, 160, 100);
question4.setBackground(Color.ORANGE);
panel.add(question4);
btnEE.setBounds(50, 100, 80, 30);
btnEE.setBackground(Color.ORANGE);
btnFF.setBounds(50, 100, 80, 30);
btnFF.setBackground(Color.ORANGE);
panel.add(btnEE);
panel.add(btnFF);
btnGG.setBounds(50, 100, 80, 30);
btnGG.setBackground(Color.ORANGE);
panel.add(btnGG);
btnHH.setBounds(50, 100, 80, 30);
btnHH.setBackground(Color.ORANGE);
panel.add(btnHH);
frame4.add(panel);
frame4.setSize(535, 250);
frame4.setLayout(null);
frame4.setVisible(true);
} else if (e.getSource() == c_three[3]) {
JFrame frame3 = new JFrame("800");
JPanel panel = new JPanel();
panel.setBounds(55, 55, 600, 800);
panel.setBackground(Color.BLUE);
question11.setBounds(50, 100, 160, 180);
question11.setBackground(Color.ORANGE);
panel.add(question11);
btn12.setBounds(50, 100, 80, 30);
btn12.setBackground(Color.ORANGE);
btn13.setBounds(50, 100, 80, 30);
btn13.setBackground(Color.ORANGE);
panel.add(btn12);
panel.add(btn13);
frame3.add(panel);
frame3.setSize(800, 300);
frame3.setLayout(null);
frame3.setVisible(true);
}
}
}
Here is a screenshot of my code:
And a picture of the buttons
I want it to say your correct or something after a button is clicked so for example in the second screenshot there's a button labelled Nicosia its btn1 so I want btn 1 to do thatthat, I tried an if else but it didn't work; I did if(e.getSource()==btn1){System.out.println("correct")}
So, having spent way more time with your code then I might have liked to, the basic answer to your question is - use a ActionListener, check which button was pressed and validate the answer to the question.
About here you should be screaming at me "YES, BUT HOW!?", which is where your actual question begins.
The problem is, you've coupled the data (question/options/answers) to the UI in such away that it's simply not easy to for you do to. Instead, you need to decouple the data (question/options/answer) from the UI, so that the UI becomes much more dumb (and re-usable) and relies on the model/data to tell it what it needs to know.
The follow answer makes use of:
Dependency injection
Observer pattern
Single responsibility principle
Information hiding (AKA encapsulation)
software engineering principles. It aims to decouple the "model" (actually models) from the UI in such away that you actually only ever need 3 panels to present ALL the data (the question panel gets dynamically re-used)
Let's start with some basic data...
public interface Question {
public int getPoints();
public String getPrompt();
public String[] getOptions();
public boolean isCorrect(String answer);
}
public interface Quiz {
public int getScore();
public String[] getCatagories();
public Question[] getQuestionsForCatagory(String category);
public boolean didAnswerQuestion(Question question, String answer);
}
(nb: It's possible to "hide" the isCorrect method in the Question through a second interface or implementation, but I figured by the time I get to the end of this, you're head would already be spinning)
Ok, so these define the basic, contractual, requirements we need to be able to build a "quiz"
It should be noted that it could be possible to add an observer to the Quiz which could generate notifications when the score changes, but I'm going to leave that to you 😉
The intention of using interface like this is to the hide the implementation detail. This means we could source the quiz information from a file (like a XML and/or JSON) or from a database or even some kind of cloud service.
Speaking of implementations, let's start with something simple
public class DefaultQuiz implements Quiz {
private Map<String, List<Question>> questions = new HashMap<>();
private int score;
public void add(String category, Question[] questions) {
this.questions.put(category, Arrays.asList(questions));
}
#Override
public boolean didAnswerQuestion(Question question, String answer) {
if (question.isCorrect(answer)) {
score += question.getPoints();
return true;
}
return false;
}
#Override
public int getScore() {
return score;
}
#Override
public String[] getCatagories() {
Set<String> keys = questions.keySet();
return keys.toArray(new String[keys.size()]);
}
#Override
public Question[] getQuestionsForCatagory(String category) {
List<Question> values = questions.get(category);
return values.toArray(new Question[values.size()]);
}
public static Quiz build() {
DefaultQuiz quiz = new DefaultQuiz();
quiz.add("Oddly Niche Topics", new Question[]{
new DefaultQuestion(200, "What is the capital of Cyprus?", new String[]{"Nicosia", "Mumbai", "Dubait", "Romania"}, 0),
new DefaultQuestion(400, "What is a note that is played for half the duration of a thirty second note?", new String[]{"demisemiquaver", "semidemiquaver", "qaver", "stop note"}, 0),
new DefaultQuestion(600, "How many times was Caesar stabbed by his senators?", new String[]{"23", "27", "72", "4"}, 0),
new DefaultQuestion(800, "Louisiana is home to a rare pink dolphin named?", new String[]{"Pinky", "Cotten Candy", "Lady", "The Other Tide."}, 0),
});
quiz.add("Ominously Enough Teachers", new Question[]{
new DefaultQuestion(200, "What do teachers know?", new String[]{"Everything about you", "All about the thing in the janitors closet", "If Dubait is real or not", "12"}, 0),
new DefaultQuestion(400, "Who is my physics teacher?", new String[]{"Mr. Penny", "Mr. Dime", "Mr. Nickel", "Mr. Dollar"}, 0),
new DefaultQuestion(600, "How much do teachers get payed on average?", new String[]{"$63,645", "$120,000", "$15", "$64,200"}, 0),
new DefaultQuestion(800, "For every 10 Canadian teachers, at least 4 have endured violence from students?", new String[]{"True", "False"}, 0),
});
quiz.add("Common Miconceptions", new Question[]{
new DefaultQuestion(200, "The most prolific modern serial killer is?", new String[]{"Everything about you", "All about the thing in the janitors closet", "If Dubait is real or not", "12"}, 0),
new DefaultQuestion(400, "Urine is sterile?", new String[]{"Mr. Penny", "Mr. Dime", "Mr. Nickel", "Mr. Dollar"}, 0),
new DefaultQuestion(600, "The Amazon rainforest provides ___% of Earth's oxygen", new String[]{"$63,645", "$120,000", "$15", "$64,200"}, 0),
new DefaultQuestion(800, "Apparently this is where the quiz ends", new String[]{"True", "True"}, 0),
});
quiz.add("Riddles", new Question[]{
new DefaultQuestion(200, "What is the meaning of live?", new String[]{"42", "Eat, Drink, Sleep, Repeat", "Grow, get a meaningness job, work till you die", "Parties"}, 0),
new DefaultQuestion(400, "What's black and white and red all over?", new String[]{"A news paper", "A pengiun with a knife", "A panda with a knife"}, 0),
new DefaultQuestion(600, "Is this question pointless?", new String[]{"Yes", "No", "Depends on your point of view"}, 0),
new DefaultQuestion(800, "Why are you stil here?", new String[]{"Pubs are closed", "I want to learn more"}, 0),
});
return quiz;
}
}
public class DefaultQuestion implements Question {
private int points;
private String prompt;
private List<String> options;
private String answer;
public DefaultQuestion(int points, String prompt, String[] options, int answer) {
this.points = points;
this.prompt = prompt;
this.options = Arrays.asList(options);
this.answer = options[answer];
}
public int getPoints() {
return points;
}
public String getPrompt() {
return prompt;
}
public String[] getOptions() {
Collections.shuffle(options);
return options.toArray(new String[options.size()]);
}
#Override
public boolean isCorrect(String answer) {
return this.answer.equals(answer);
}
}
So, this default implementation has a simple build method which builds a quiz, based on the information I extracted from your question.
One thing to note is, every time DefaultQuestion#getOptions is called, the options are randomised!! So you, you know, actually have to read the answers 😉
Now, the UI is broken down into three parts, the "categories pane", the "question and answer pane" and the "controller"
The first two are pretty easy to understand, the controller needs a little bit more consideration.
Let's start with the first two...
public class QuizCategoriesPane extends JPanel {
public static interface Observer {
public void askQuestion(QuizCategoriesPane source, Quiz quize, Question question);
}
private Quiz quiz;
private Observer observer;
public QuizCategoriesPane(Quiz quiz, Observer observer) {
this.quiz = quiz;
this.observer = observer;
String[] categories = quiz.getCatagories();
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridheight = GridBagConstraints.REMAINDER;
gbc.insets = new Insets(4, 4, 4, 4);
gbc.anchor = GridBagConstraints.NORTH;
for (String category : categories) {
add(makeCategoryPaneFor(category, quiz.getQuestionsForCatagory(category)), gbc);
}
JButton spinButton = buildButton();
spinButton.setText("Spin the wheel");
gbc.fill = GridBagConstraints.HORIZONTAL;
add(spinButton, gbc);
}
public Quiz getQuiz() {
return quiz;
}
protected JPanel makeCategoryPaneFor(String category, Question[] questions) {
JPanel panel = new JPanel(new GridLayout(-1, 1, 4, 4));
for (Question question : questions) {
panel.add(makeButtonForQuestion(category, question));
}
return panel;
}
protected JButton makeButtonForQuestion(String category, Question question) {
JButton btn = buildButton();
btn.setText(category);
// I'd prefer to use a Action, but I'm probably already pushing you
// beyond your limits
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
observer.askQuestion(QuizCategoriesPane.this, getQuiz(), question);
}
});
return btn;
}
protected JButton buildButton() {
JButton btn = new JButton();
btn.setContentAreaFilled(false);
btn.setBorderPainted(false);
btn.setBackground(Color.BLUE);
btn.setForeground(Color.YELLOW);
btn.setOpaque(true);
btn.setBorder(new EmptyBorder(32, 32, 32, 32));
return btn;
}
}
public class QuestionPane extends JPanel {
public static interface Obsever {
public void didAnswerQuestion(QuestionPane source);
}
private Quiz quiz;
private Question question;
private QuestionPane(Quiz quiz, Question question, Obsever obsever) {
this.question = question;
setLayout(new BorderLayout());
add(new JLabel("<html>For " + question.getPoints() + " Points<br><h1>" + question.getPrompt() + "</h1></html>"), BorderLayout.NORTH);
JPanel options = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
ButtonGroup bg = new ButtonGroup();
for (String option : question.getOptions()) {
JRadioButton button = new JRadioButton("<html><h2>" + option + "</h2></html>");
button.setActionCommand(option);
bg.add(button);
options.add(button, gbc);
}
add(options);
JPanel actionPane = new JPanel(new GridBagLayout());
gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.anchor = GridBagConstraints.LINE_END;
JButton answerButton = new JButton("Answer");
answerButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String answer = bg.getSelection().getActionCommand();
if (quiz.didAnswerQuestion(question, answer)) {
JOptionPane.showMessageDialog(QuestionPane.this, "Correct");
} else {
JOptionPane.showMessageDialog(QuestionPane.this, "Incorrect");
}
obsever.didAnswerQuestion(QuestionPane.this);
}
});
actionPane.add(answerButton, gbc);
add(actionPane, BorderLayout.SOUTH);
}
}
The "controller" is responsible for managing the presentation of the "categories" and the "question/answer" UIs. Because the UIs are relatively complicated, they are separated into individual classes, this allows them to be responsible for just doing one job and not getting over burden with functionality which really isn't their responsibility anyway.
The controller might look something like...
public class QuizPane extends JPanel {
private CardLayout cardLayout;
public QuizPane(Quiz quiz) {
setBorder(new EmptyBorder(16, 16, 16, 16));
cardLayout = new CardLayout();
setLayout(cardLayout);
QuizCategoriesPane.Observer quizObserver = new QuizCategoriesPane.Observer() {
#Override
public void askQuestion(QuizCategoriesPane source, Quiz quize, Question question) {
QuestionPane qp = new QuestionPane(quiz, question, new QuestionPane.Obsever() {
#Override
public void didAnswerQuestion(QuestionPane source) {
remove(source);
cardLayout.show(QuizPane.this, "categories");
}
});
add(qp, "question");
cardLayout.show(QuizPane.this, "question");
}
};
add(new QuizCategoriesPane(quiz, quizObserver), "categories");
}
}
It has a very basic responsibility, show the user the categories, when a user selects a category, notified via an observer, show the question. When the user answers the question, notified via an observer, show the categories again.
As I said earlier, somebody needs to tell the categories pane that the score has changed, I've suggested that this could be done via an observer pattern on the Quiz itself, as this makes it independent of all the other workflows. And, no, I'm not going to do it.
Now, obviously, this needs some more work, for example, there's no way to track which questions have already been presented to the user, something else for you to figure out 😉
Runnable example
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.border.EmptyBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
Quiz quiz = DefaultQuiz.build();
JFrame frame = new JFrame();
frame.add(new QuizPane(quiz));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static interface Question {
public int getPoints();
public String getPrompt();
public String[] getOptions();
public boolean isCorrect(String answer);
}
public static interface Quiz {
public int getScore();
public String[] getCatagories();
public Question[] getQuestionsForCatagory(String category);
public boolean didAnswerQuestion(Question question, String answer);
}
public static class DefaultQuiz implements Quiz {
private Map<String, List<Question>> questions = new HashMap<>();
private int score;
public void add(String category, Question[] questions) {
this.questions.put(category, Arrays.asList(questions));
}
#Override
public boolean didAnswerQuestion(Question question, String answer) {
if (question.isCorrect(answer)) {
score += question.getPoints();
return true;
}
return false;
}
#Override
public int getScore() {
return score;
}
#Override
public String[] getCatagories() {
Set<String> keys = questions.keySet();
return keys.toArray(new String[keys.size()]);
}
#Override
public Question[] getQuestionsForCatagory(String category) {
List<Question> values = questions.get(category);
return values.toArray(new Question[values.size()]);
}
public static Quiz build() {
DefaultQuiz quiz = new DefaultQuiz();
quiz.add("Oddly Niche Topics", new Question[]{
new DefaultQuestion(200, "What is the capital of Cyprus?", new String[]{"Nicosia", "Mumbai", "Dubait", "Romania"}, 0),
new DefaultQuestion(400, "What is a note that is played for half the duration of a thirty second note?", new String[]{"demisemiquaver", "semidemiquaver", "qaver", "stop note"}, 0),
new DefaultQuestion(600, "How many times was Caesar stabbed by his senators?", new String[]{"23", "27", "72", "4"}, 0),
new DefaultQuestion(800, "Louisiana is home to a rare pink dolphin named?", new String[]{"Pinky", "Cotten Candy", "Lady", "The Other Tide."}, 0),
});
quiz.add("Ominously Enough Teachers", new Question[]{
new DefaultQuestion(200, "What do teachers know?", new String[]{"Everything about you", "All about the thing in the janitors closet", "If Dubait is real or not", "12"}, 0),
new DefaultQuestion(400, "Who is my physics teacher?", new String[]{"Mr. Penny", "Mr. Dime", "Mr. Nickel", "Mr. Dollar"}, 0),
new DefaultQuestion(600, "How much do teachers get payed on average?", new String[]{"$63,645", "$120,000", "$15", "$64,200"}, 0),
new DefaultQuestion(800, "For every 10 Canadian teachers, at least 4 have endured violence from students?", new String[]{"True", "False"}, 0),
});
quiz.add("Common Miconceptions", new Question[]{
new DefaultQuestion(200, "The most prolific modern serial killer is?", new String[]{"Everything about you", "All about the thing in the janitors closet", "If Dubait is real or not", "12"}, 0),
new DefaultQuestion(400, "Urine is sterile?", new String[]{"Mr. Penny", "Mr. Dime", "Mr. Nickel", "Mr. Dollar"}, 0),
new DefaultQuestion(600, "The Amazon rainforest provides ___% of Earth's oxygen", new String[]{"$63,645", "$120,000", "$15", "$64,200"}, 0),
new DefaultQuestion(800, "Apparently this is where the quiz ends", new String[]{"True", "True"}, 0),
});
quiz.add("Riddles", new Question[]{
new DefaultQuestion(200, "What is the meaning of live?", new String[]{"42", "Eat, Drink, Sleep, Repeat", "Grow, get a meaningness job, work till you die", "Parties"}, 0),
new DefaultQuestion(400, "What's black and white and red all over?", new String[]{"A news paper", "A pengiun with a knife", "A panda with a knife"}, 0),
new DefaultQuestion(600, "Is this question pointless?", new String[]{"Yes", "No", "Depends on your point of view"}, 0),
new DefaultQuestion(800, "Why are you stil here?", new String[]{"Pubs are closed", "I want to learn more"}, 0),
});
return quiz;
}
}
public static class DefaultQuestion implements Question {
private int points;
private String prompt;
private List<String> options;
private String answer;
public DefaultQuestion(int points, String prompt, String[] options, int answer) {
this.points = points;
this.prompt = prompt;
this.options = Arrays.asList(options);
this.answer = options[answer];
}
public int getPoints() {
return points;
}
public String getPrompt() {
return prompt;
}
public String[] getOptions() {
Collections.shuffle(options);
return options.toArray(new String[options.size()]);
}
#Override
public boolean isCorrect(String answer) {
return this.answer.equals(answer);
}
}
public static class QuizPane extends JPanel {
private CardLayout cardLayout;
public QuizPane(Quiz quiz) {
setBorder(new EmptyBorder(16, 16, 16, 16));
cardLayout = new CardLayout();
setLayout(cardLayout);
QuizCategoriesPane.Observer quizObserver = new QuizCategoriesPane.Observer() {
#Override
public void askQuestion(QuizCategoriesPane source, Quiz quize, Question question) {
QuestionPane qp = new QuestionPane(quiz, question, new QuestionPane.Obsever() {
#Override
public void didAnswerQuestion(QuestionPane source) {
remove(source);
cardLayout.show(QuizPane.this, "categories");
}
});
add(qp, "question");
cardLayout.show(QuizPane.this, "question");
}
};
add(new QuizCategoriesPane(quiz, quizObserver), "categories");
}
}
public static class QuizCategoriesPane extends JPanel {
public static interface Observer {
public void askQuestion(QuizCategoriesPane source, Quiz quize, Question question);
}
private Quiz quiz;
private Observer observer;
public QuizCategoriesPane(Quiz quiz, Observer observer) {
this.quiz = quiz;
this.observer = observer;
String[] categories = quiz.getCatagories();
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridheight = GridBagConstraints.REMAINDER;
gbc.insets = new Insets(4, 4, 4, 4);
gbc.anchor = GridBagConstraints.NORTH;
for (String category : categories) {
add(makeCategoryPaneFor(category, quiz.getQuestionsForCatagory(category)), gbc);
}
JButton spinButton = buildButton();
spinButton.setText("Spin the wheel");
gbc.fill = GridBagConstraints.HORIZONTAL;
add(spinButton, gbc);
}
public Quiz getQuiz() {
return quiz;
}
protected JPanel makeCategoryPaneFor(String category, Question[] questions) {
JPanel panel = new JPanel(new GridLayout(-1, 1, 4, 4));
for (Question question : questions) {
panel.add(makeButtonForQuestion(category, question));
}
return panel;
}
protected JButton makeButtonForQuestion(String category, Question question) {
JButton btn = buildButton();
btn.setText(category);
// I'd prefer to use a Action, but I'm probably already pushing you
// beyond your limits
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
observer.askQuestion(QuizCategoriesPane.this, getQuiz(), question);
}
});
return btn;
}
protected JButton buildButton() {
JButton btn = new JButton();
btn.setContentAreaFilled(false);
btn.setBorderPainted(false);
btn.setBackground(Color.BLUE);
btn.setForeground(Color.YELLOW);
btn.setOpaque(true);
btn.setBorder(new EmptyBorder(32, 32, 32, 32));
return btn;
}
}
public static class QuestionPane extends JPanel {
public static interface Obsever {
public void didAnswerQuestion(QuestionPane source);
}
private Quiz quiz;
private Question question;
private QuestionPane(Quiz quiz, Question question, Obsever obsever) {
this.question = question;
setLayout(new BorderLayout());
add(new JLabel("<html>For " + question.getPoints() + " Points<br><h1>" + question.getPrompt() + "</h1></html>"), BorderLayout.NORTH);
JPanel options = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
ButtonGroup bg = new ButtonGroup();
for (String option : question.getOptions()) {
JRadioButton button = new JRadioButton("<html><h2>" + option + "</h2></html>");
button.setActionCommand(option);
bg.add(button);
options.add(button, gbc);
}
add(options);
JPanel actionPane = new JPanel(new GridBagLayout());
gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.anchor = GridBagConstraints.LINE_END;
JButton answerButton = new JButton("Answer");
answerButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String answer = bg.getSelection().getActionCommand();
if (quiz.didAnswerQuestion(question, answer)) {
JOptionPane.showMessageDialog(QuestionPane.this, "Correct");
} else {
JOptionPane.showMessageDialog(QuestionPane.this, "Incorrect");
}
obsever.didAnswerQuestion(QuestionPane.this);
}
});
actionPane.add(answerButton, gbc);
add(actionPane, BorderLayout.SOUTH);
}
}
}
Related
My content pane show only white even if it has components on it
I'm doing this as a challenge for myself. My problem is that when I click on the button, the content pane appears plain even if the JPanel has components in it. I've tried adding the components on the frame but I get an error: >Cannot read field "parent" because "comp" is null. I've tried other layout on JFrame and JPanel and still it didn't show. Here's the full code: import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.DecimalFormat; public class test implements ActionListener{ public static void main(String [] args) { new test(); } static JPanel mainPanel, cubePanel; static JFrame frame; static Container container = new Container(); static JLabel calculatorFor; static JButton sphereButton, rightCylinderButton, rightConeButton, rectangularPrismButton, triangularPrismButton, cubeButton, squarePyramidButton, rectangularPyramidButton, ellipsoidButton, tetrahedronButton ,backToPreviousFrameButton; static Font font = new Font(null, Font.PLAIN, 30); static JLabel enterValueForEdge; static JTextField edgeTextField; static JTextArea surfaceAreaTextArea, surfaceAreaFormulaTextArea, surfaceAreaSolutionTextArea; static JButton calculateButton; static double edge; static DecimalFormat surfaceAreaDecimal; public test(){ frame = new JFrame("Calculating for Surface Area"); calculatorFor = new JLabel("Calculator for the Surface Area of:"); calculatorFor.setSize(600, 40); calculatorFor.setLocation(100, 50); calculatorFor.setFont(font); calculatorFor.setFocusable(false); sphereButton = new JButton("Sphere "); sphereButton.setSize(400, 40); sphereButton.setLocation(100, 100); sphereButton.setFont(font); sphereButton.addActionListener(this); sphereButton.setFocusable(false); rightCylinderButton = new JButton("Right Cylinder"); rightCylinderButton.setSize(400, 40); rightCylinderButton.setLocation(100, 150); rightCylinderButton.setFont(font); rightCylinderButton.addActionListener(this); rightCylinderButton.setFocusable(false); rightConeButton = new JButton("Right Cone"); rightConeButton.setSize(400, 40); rightConeButton.setLocation(100, 200); rightConeButton.setFont(font); rightConeButton.addActionListener(this); rightConeButton.setFocusable(false); rectangularPrismButton = new JButton("Rectangular Prism"); rectangularPrismButton.setSize(400, 40); rectangularPrismButton.setLocation(100, 250); rectangularPrismButton.setFont(font); rectangularPrismButton.addActionListener(this); rectangularPrismButton.setFocusable(false); triangularPrismButton = new JButton("Triangular Prism"); triangularPrismButton.setSize(400, 40); triangularPrismButton.setLocation(100, 300); triangularPrismButton.setFont(font); triangularPrismButton.addActionListener(this); triangularPrismButton.setFocusable(false); cubeButton = new JButton("Cube"); cubeButton.setSize(400, 40); cubeButton.setLocation(100, 350); cubeButton.setFont(font); cubeButton.addActionListener(this); cubeButton.setFocusable(false); squarePyramidButton = new JButton("Square Pyramid"); squarePyramidButton.setSize(400, 40); squarePyramidButton.setLocation(100, 400); squarePyramidButton.setFont(font); squarePyramidButton.addActionListener(this); squarePyramidButton.setFocusable(false); rectangularPyramidButton = new JButton("Rectangular Pyramid"); rectangularPyramidButton.setSize(400, 40); rectangularPyramidButton.setLocation(100, 450); rectangularPyramidButton.setFont(font); rectangularPyramidButton.addActionListener(this); rectangularPyramidButton.setFocusable(false); ellipsoidButton = new JButton("Ellipsoid"); ellipsoidButton.setSize(400, 40); ellipsoidButton.setLocation(100, 500); ellipsoidButton.setFont(font); ellipsoidButton.addActionListener(this); ellipsoidButton.setFocusable(false); tetrahedronButton = new JButton("Tetrahedron"); tetrahedronButton.setSize(400, 40); tetrahedronButton.setLocation(100, 550); tetrahedronButton.setFont(font); tetrahedronButton.addActionListener(this); tetrahedronButton.setFocusable(false); backToPreviousFrameButton = new JButton("Back"); backToPreviousFrameButton.setSize(100, 40); backToPreviousFrameButton.setLocation(900, 600); backToPreviousFrameButton.setFont(font); backToPreviousFrameButton.addActionListener(this); backToPreviousFrameButton.setFocusable(false); mainPanel = new JPanel(); mainPanel.setBounds(0, 0, 1080, 720); mainPanel.setLayout(null); mainPanel.setBackground(Color.decode("#FAF7FC")); mainPanel.add(calculatorFor); mainPanel.add(sphereButton); mainPanel.add(rightCylinderButton); mainPanel.add(rightConeButton); mainPanel.add(rectangularPrismButton); mainPanel.add(triangularPrismButton); mainPanel.add(cubeButton); mainPanel.add(squarePyramidButton); mainPanel.add(rectangularPyramidButton); mainPanel.add(ellipsoidButton); mainPanel.add(tetrahedronButton); mainPanel.add(backToPreviousFrameButton); frame.getContentPane().add(mainPanel); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().setBackground(Color.decode("#FAF7FC")); frame.setLayout(new BorderLayout()); frame.setSize(1080,720); frame.setResizable(false); frame.setVisible(true); frame.setLocationRelativeTo(null); } public void cubePanel(){ enterValueForEdge = new JLabel("Enter Edge:"); enterValueForEdge.setSize(200, 40); enterValueForEdge.setLocation(100, 50); enterValueForEdge.setFont(font); enterValueForEdge.setFocusable(false); edgeTextField = new JTextField(); edgeTextField.setSize(400, 40); edgeTextField.setLocation(300, 50); edgeTextField.setFont(font); calculateButton = new JButton("Calculate"); calculateButton.setSize(200, 40); calculateButton.setLocation(100, 100); calculateButton.setFont(font); calculateButton.addActionListener(this); calculateButton.setFocusable(false); surfaceAreaFormulaTextArea = new JTextArea("SA = 6a²"); surfaceAreaFormulaTextArea.setSize(400, 40); surfaceAreaFormulaTextArea.setLocation(100, 150); surfaceAreaFormulaTextArea.setFont(font); surfaceAreaFormulaTextArea.setEditable(false); surfaceAreaTextArea = new JTextArea("SA: "); surfaceAreaTextArea.setSize(500, 40); surfaceAreaTextArea.setLocation(100, 200); surfaceAreaTextArea.setFont(font); surfaceAreaTextArea.setEditable(false); surfaceAreaSolutionTextArea = new JTextArea(); surfaceAreaSolutionTextArea.setSize(900, 80); surfaceAreaSolutionTextArea.setLocation(100, 250); surfaceAreaSolutionTextArea.setFont(font); surfaceAreaSolutionTextArea.setEditable(false); surfaceAreaSolutionTextArea.setLineWrap(true); backToPreviousFrameButton = new JButton("Back"); backToPreviousFrameButton.setSize(100, 40); backToPreviousFrameButton.setLocation(900, 600); backToPreviousFrameButton.setFont(font); backToPreviousFrameButton.addActionListener(this); backToPreviousFrameButton.setFocusable(false); cubePanel = new JPanel(); cubePanel.setBounds(0, 0, 1080, 720); cubePanel.setLayout(null); cubePanel.setBackground(Color.decode("#FAF7FC")); container = new Container(); cubePanel.add(enterValueForEdge); cubePanel.add(edgeTextField); cubePanel.add(calculateButton); cubePanel.add(surfaceAreaFormulaTextArea); cubePanel.add(surfaceAreaTextArea); cubePanel.add(surfaceAreaSolutionTextArea); cubePanel.add(backToPreviousFrameButton); container.add(cubePanel); container.setLayout(null); container.setBackground(Color.decode("#FAF7FH")); } #Override public void actionPerformed(ActionEvent e) { if(e.getSource() == sphereButton){ new sphereFrame(); frame.dispose(); } if(e.getSource() == rightCylinderButton){ new rightCylinderFrame(); frame.dispose(); } if(e.getSource() == rightConeButton){ new rightConeFrame(); frame.dispose(); } if(e.getSource() == rectangularPrismButton){ new rectangularPrismFrame(); frame.dispose(); } if(e.getSource() == triangularPrismButton){ new triangularPrismFrame(); frame.dispose(); } if(e.getSource() == cubeButton){ frame.getContentPane().removeAll(); frame.add(cubePanel); frame.repaint(); frame.revalidate(); System.out.println("Remove"); frame.getContentPane().add(container); } }
Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Learning Swing with the NetBeans IDE section. Pay particular attention to the Laying Out Components Within a Container section. Here's the GUI I created. Press the "Cube" button to bring up the page for the cube calculation. All Swing applications must start with a call to the SwingUtilities invokeLater method. This method ensures that the Swing components are created and executed on the Event Dispatch Thread. The JFrame has a default BorderLayout and holds the main JPanel. The main JPanel uses a CardLayout to display the various calculation JPanels. Using a CardLayout is much easier than managing multiple JFrames and provides a nicer user experience. I used Swing layout managers to position the Swing components on the various JPanels. The start JPanel consists of two subordinate JPanels. The title JPanel uses a FlowLayout to display the title. The button JPanel uses a GridLayout to display the various calculation JButtons. You can create complex JPanels by nesting multiple simple JPanels. The cube calculation JPanel was the only one you had in your code, so it was the only one I created. I made it a method, but you can create a separate class for each of the calculations. The cube calculation JPanel uses a GridBagLayout to create a form-like JPanel. I used lambda expressions to create the ActionListener for each of the JButtons, since they were so simple. I made the start JPanel button ActionListener a separate class just to get the code away from the for loop that creates the JButtons. Here's the complete runnable code. import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.FlowLayout; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingUtilities; public class CardLayoutGUI implements Runnable { public static void main(String[] args) { SwingUtilities.invokeLater(new CardLayoutGUI()); } private CardLayout cardLayout; private JTextField edgeTextField, surfaceAreaSolutionTextField; private JPanel mainPanel; #Override public void run() { JFrame frame = new JFrame("Calculating for Surface Area"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.mainPanel = createMainPanel(); frame.add(mainPanel, BorderLayout.CENTER); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } private JPanel createMainPanel() { cardLayout = new CardLayout(); JPanel panel = new JPanel(cardLayout); panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5)); panel.add(createStartPanel(), "Start"); panel.add(createCubeCalculationPanel(), "Cube"); return panel; } private JPanel createStartPanel() { JPanel panel = new JPanel(new BorderLayout()); panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5)); panel.add(createTitlePanel(), BorderLayout.NORTH); panel.add(createButtonPanel(), BorderLayout.CENTER); return panel; } private JPanel createTitlePanel() { JPanel panel = new JPanel(new FlowLayout()); panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5)); Font font = new Font(Font.DIALOG, Font.PLAIN, 36); JLabel label = new JLabel("Calculator for the Surface Area of:"); label.setFont(font); panel.add(label); return panel; } private JPanel createButtonPanel() { String[] text = { "Sphere", "Right Cylinder", "Right Cone", "Rectangular Prism", "Triangular Prism", "Cube", "Square Pyramid", "Rectangular Pyramid", "Ellipsoid", "Tetrahedron" }; JPanel panel = new JPanel(new GridLayout(0, 3, 5, 5)); panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5)); Font font = new Font(null, Font.PLAIN, 24); ButtonListener listener = new ButtonListener(); for (String s : text) { JButton button = new JButton(s); button.addActionListener(listener); button.setFont(font); panel.add(button); } return panel; } private JPanel createCubeCalculationPanel() { JPanel panel = new JPanel(new GridBagLayout()); panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5)); Font titleFont = new Font(null, Font.PLAIN, 32); Font font = new Font(null, Font.PLAIN, 16); GridBagConstraints gbc = new GridBagConstraints(); gbc.anchor = GridBagConstraints.LINE_START; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.insets = new Insets(0, 5, 5, 5); gbc.weighty = 1.0; gbc.gridwidth = 2; gbc.gridx = 0; gbc.gridy = 0; JLabel label = new JLabel("SA = 6a²"); label.setFont(titleFont); panel.add(label, gbc); gbc.gridwidth = 1; gbc.gridy++; label = new JLabel("Edge:"); label.setFont(font); panel.add(label, gbc); gbc.gridx++; edgeTextField = new JTextField(10); edgeTextField.setFont(font); panel.add(edgeTextField, gbc); gbc.gridx = 0; gbc.gridy++; label = new JLabel("SA:"); label.setFont(font); panel.add(label, gbc); gbc.gridx++; surfaceAreaSolutionTextField = new JTextField(10); surfaceAreaSolutionTextField.setFont(font); surfaceAreaSolutionTextField.setEditable(false); panel.add(surfaceAreaSolutionTextField, gbc); gbc.gridwidth = 2; gbc.gridx = 0; gbc.gridy++; JButton calculateButton = new JButton("Calculate"); calculateButton.addActionListener(event -> { double edge = Double.valueOf(edgeTextField.getText()); double sa = 6.0 * edge * edge; surfaceAreaSolutionTextField.setText(Double.toString(sa)); }); calculateButton.setFont(font); panel.add(calculateButton, gbc); gbc.gridy++; JButton backButton = new JButton("Back"); backButton.addActionListener(event -> { cardLayout.show(mainPanel, "Start"); }); backButton.setFont(font); panel.add(backButton, gbc); return panel; } public class ButtonListener implements ActionListener { #Override public void actionPerformed(ActionEvent event) { JButton button = (JButton) event.getSource(); String text = button.getText(); cardLayout.show(mainPanel, text); } } }
Try this : import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.DecimalFormat; public class Test2 implements ActionListener { public static void main(String[] args) { new Test2(); } static JPanel mainPanel, cubePanel; static JFrame frame; static Container container = new Container(); static JLabel calculatorFor; static JButton sphereButton, rightCylinderButton, rightConeButton, rectangularPrismButton, triangularPrismButton, cubeButton, squarePyramidButton, rectangularPyramidButton, ellipsoidButton, tetrahedronButton, backToPreviousFrameButton; static Font font = new Font(null, Font.PLAIN, 30); static JLabel enterValueForEdge; static JTextField edgeTextField; static JTextArea surfaceAreaTextArea, surfaceAreaFormulaTextArea, surfaceAreaSolutionTextArea; static JButton calculateButton; static double edge; static DecimalFormat surfaceAreaDecimal; public Test2() { frame = new JFrame("Calculating for Surface Area"); calculatorFor = new JLabel("Calculator for the Surface Area of:"); calculatorFor.setSize(600, 40); calculatorFor.setLocation(100, 50); calculatorFor.setFont(font); calculatorFor.setFocusable(false); sphereButton = new JButton("Sphere "); sphereButton.setSize(400, 40); sphereButton.setLocation(100, 100); sphereButton.setFont(font); sphereButton.addActionListener(this); sphereButton.setFocusable(false); rightCylinderButton = new JButton("Right Cylinder"); rightCylinderButton.setSize(400, 40); rightCylinderButton.setLocation(100, 150); rightCylinderButton.setFont(font); rightCylinderButton.addActionListener(this); rightCylinderButton.setFocusable(false); rightConeButton = new JButton("Right Cone"); rightConeButton.setSize(400, 40); rightConeButton.setLocation(100, 200); rightConeButton.setFont(font); rightConeButton.addActionListener(this); rightConeButton.setFocusable(false); rectangularPrismButton = new JButton("Rectangular Prism"); rectangularPrismButton.setSize(400, 40); rectangularPrismButton.setLocation(100, 250); rectangularPrismButton.setFont(font); rectangularPrismButton.addActionListener(this); rectangularPrismButton.setFocusable(false); triangularPrismButton = new JButton("Triangular Prism"); triangularPrismButton.setSize(400, 40); triangularPrismButton.setLocation(100, 300); triangularPrismButton.setFont(font); triangularPrismButton.addActionListener(this); triangularPrismButton.setFocusable(false); cubeButton = new JButton("Cube"); cubeButton.setSize(400, 40); cubeButton.setLocation(100, 350); cubeButton.setFont(font); cubeButton.addActionListener(this); cubeButton.setFocusable(false); squarePyramidButton = new JButton("Square Pyramid"); squarePyramidButton.setSize(400, 40); squarePyramidButton.setLocation(100, 400); squarePyramidButton.setFont(font); squarePyramidButton.addActionListener(this); squarePyramidButton.setFocusable(false); rectangularPyramidButton = new JButton("Rectangular Pyramid"); rectangularPyramidButton.setSize(400, 40); rectangularPyramidButton.setLocation(100, 450); rectangularPyramidButton.setFont(font); rectangularPyramidButton.addActionListener(this); rectangularPyramidButton.setFocusable(false); ellipsoidButton = new JButton("Ellipsoid"); ellipsoidButton.setSize(400, 40); ellipsoidButton.setLocation(100, 500); ellipsoidButton.setFont(font); ellipsoidButton.addActionListener(this); ellipsoidButton.setFocusable(false); tetrahedronButton = new JButton("Tetrahedron"); tetrahedronButton.setSize(400, 40); tetrahedronButton.setLocation(100, 550); tetrahedronButton.setFont(font); tetrahedronButton.addActionListener(this); tetrahedronButton.setFocusable(false); backToPreviousFrameButton = new JButton("Back"); backToPreviousFrameButton.setSize(100, 40); backToPreviousFrameButton.setLocation(900, 600); backToPreviousFrameButton.setFont(font); backToPreviousFrameButton.addActionListener(this); backToPreviousFrameButton.setFocusable(false); mainPanel = new JPanel(); mainPanel.setBounds(0, 0, 1080, 720); mainPanel.setLayout(null); mainPanel.setBackground(Color.decode("#FAF7FC")); mainPanel.add(calculatorFor); mainPanel.add(sphereButton); mainPanel.add(rightCylinderButton); mainPanel.add(rightConeButton); mainPanel.add(rectangularPrismButton); mainPanel.add(triangularPrismButton); mainPanel.add(cubeButton); mainPanel.add(squarePyramidButton); mainPanel.add(rectangularPyramidButton); mainPanel.add(ellipsoidButton); mainPanel.add(tetrahedronButton); mainPanel.add(backToPreviousFrameButton); frame.getContentPane().add(mainPanel); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().setBackground(Color.decode("#FAF7FC")); frame.setLayout(new BorderLayout()); frame.setSize(1080, 720); frame.setResizable(false); frame.setVisible(true); frame.setLocationRelativeTo(null); } public Container cubePanel() { enterValueForEdge = new JLabel("Enter Edge:"); enterValueForEdge.setSize(200, 40); enterValueForEdge.setLocation(100, 50); enterValueForEdge.setFont(font); enterValueForEdge.setFocusable(false); edgeTextField = new JTextField(); edgeTextField.setSize(400, 40); edgeTextField.setLocation(300, 50); edgeTextField.setFont(font); calculateButton = new JButton("Calculate"); calculateButton.setSize(200, 40); calculateButton.setLocation(100, 100); calculateButton.setFont(font); calculateButton.addActionListener(this); calculateButton.setFocusable(false); surfaceAreaFormulaTextArea = new JTextArea("SA = 6a²"); surfaceAreaFormulaTextArea.setSize(400, 40); surfaceAreaFormulaTextArea.setLocation(100, 150); surfaceAreaFormulaTextArea.setFont(font); surfaceAreaFormulaTextArea.setEditable(false); surfaceAreaTextArea = new JTextArea("SA: "); surfaceAreaTextArea.setSize(500, 40); surfaceAreaTextArea.setLocation(100, 200); surfaceAreaTextArea.setFont(font); surfaceAreaTextArea.setEditable(false); surfaceAreaSolutionTextArea = new JTextArea(); surfaceAreaSolutionTextArea.setSize(900, 80); surfaceAreaSolutionTextArea.setLocation(100, 250); surfaceAreaSolutionTextArea.setFont(font); surfaceAreaSolutionTextArea.setEditable(false); surfaceAreaSolutionTextArea.setLineWrap(true); backToPreviousFrameButton = new JButton("Back"); backToPreviousFrameButton.setSize(100, 40); backToPreviousFrameButton.setLocation(900, 600); backToPreviousFrameButton.setFont(font); backToPreviousFrameButton.addActionListener(this); backToPreviousFrameButton.setFocusable(false); cubePanel = new JPanel(); cubePanel.setBounds(0, 0, 1080, 720); cubePanel.setLayout(null); cubePanel.setBackground(Color.decode("#FAF7FC")); container = new Container(); cubePanel.add(enterValueForEdge); cubePanel.add(edgeTextField); cubePanel.add(calculateButton); cubePanel.add(surfaceAreaFormulaTextArea); cubePanel.add(surfaceAreaTextArea); cubePanel.add(surfaceAreaSolutionTextArea); cubePanel.add(backToPreviousFrameButton); container.add(cubePanel); container.setLayout(null); container.setBackground(Color.getColor("#FAF7FH")); return container; } #Override public void actionPerformed(ActionEvent e) { if (e.getSource() == sphereButton) { new sphereFrame(); frame.dispose(); } if (e.getSource() == rightCylinderButton) { new rightCylinderFrame(); frame.dispose(); } if (e.getSource() == rightConeButton) { new rightConeFrame(); frame.dispose(); } if (e.getSource() == rectangularPrismButton) { new rectangularPrismFrame(); frame.dispose(); } if (e.getSource() == triangularPrismButton) { //new triangularPrismFrame(); frame.dispose(); } if (e.getSource() == cubeButton) { frame.getContentPane().removeAll(); frame.add(cubePanel()); frame.repaint(); frame.revalidate(); System.out.println("Remove"); frame.getContentPane().add(container); } } }
Why does this only work on designed comboBox and not on hardcoded swing?
Newbie question: So this code here public void comboItemItemStateChanged(java.awt.event.ItemEvent evt) { ArrayList<String> arrayItem = new ArrayList<>(); Iterator<String> iter; if(comboGroup.getSelectedItem().equals("Betta Fish")){ comboItem.removeAllItems(); arrayItem.add("Plakat"); arrayItem.add("Halfmoon"); arrayItem.add("Crown Tail"); arrayItem.add("Double Tail"); iter = arrayItem.iterator(); while(iter.hasNext()){ comboItem.addItem(iter.next()); } } else if(comboGroup.getSelectedItem().equals("Snails")){ comboItem.removeAllItems(); arrayItem.add("Apple Horn"); arrayItem.add("RamsHorn"); arrayItem.add("Pond Snail"); arrayItem.add("Assassin Snail"); iter = arrayItem.iterator(); while(iter.hasNext()){ comboItem.addItem(iter.next()); } works when I try it on comboBoxes from Design tab in NetBeans. But when I try to apply it to my coded ComboBox, I get a message from evt saying Unused method parameters should be removed. Can I get an explanation why and what is the alternative for hardcoded comboBox? Purpose of code: a dynamic comboBox so whatever I pick from comboBox1 will have each own set of lists for comboBox2 NOTE: I also tried to change comboItemItemStateChanged to just itemStatChanged. Source code of my project: https://github.com/kontext66/GuwiPos/blob/main/GuwiPos Sorry for the confusion everyone, I do have a main class. public class Main{ public static void main(String[] args){ new GuwiPos(); new HelpWin(); } } Main.java, GuwiPos.java
It's quite simple, really. The message is just NetBeans informing you that the code of method comboItemItemStateChanged does not reference the method parameter evt. It is not an error nor even a warning. You can ignore it. NetBeans displays these "hints" in its editor when you write code whereas NetBeans GUI builder generates code. Note that method comboItemItemStateChanged will be called each time an item in the JComboBox is selected and also each time an item is de-selected. I'm guessing that you only want the code to run when an item is selected, hence the first line of method comboItemItemStateChanged should be if (evt.getStateChange() == ItemEvent.SELECTED) { and then you are referencing the method parameter and the "hint" will go away. Refer to How to Write an Item Listener Edit I think maybe you would benefit from learning about GUI design. I have never seen one like yours. I would like to know how you arrived at that design. In any case, the below code addresses only the functionality whereby the list in comboItem adjusts depending on the selected item in comboGroup. In my experience, removing and adding items to the JComboBox via methods removeAllItems and addItem, is very slow. It is much more efficient to simply replace the JComboBox model which is what I have done in the below code. For small lists such as yours, the difference will not be noticed but it increases as the lists get larger. Also, the [JComboBox] selected item is in the evt parameter to method comboItemItemStateChanged. Your original code did not add an item listener to comboGroup nor did it have a main method. I have added these in the below code. Note that the item listener is added via a method reference. import javax.swing.JPanel; import javax.swing.JLabel; import javax.swing.BorderFactory; import javax.swing.ComboBoxModel; import javax.swing.DefaultComboBoxModel; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JTextField; import javax.swing.JComboBox; import java.awt.Color; import java.awt.EventQueue; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Vector; import java.awt.event.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; /** * * #author kahbg */ public class GuwiPos extends JFrame implements ActionListener { public static final Map<String, ComboBoxModel<String>> LISTS; JButton buttonBasket; JButton buttonHelp; JTextField txtGroup; JTextField txtItem; JTextField txtQty; JTextField txtTotal; JTextField txtPrice; JComboBox<String> comboGroup; JComboBox<String> comboItem; static { LISTS = new HashMap<>(); Vector<String> v = new Vector<>(); v.add("Plakat"); v.add("Halfmoon"); v.add("Crown Tail"); v.add("Double Tail"); ComboBoxModel<String> model = new DefaultComboBoxModel<>(v); LISTS.put("Betta Fish", model); v = new Vector<>(); v.add("Apple Horn"); v.add("RamsHorn"); v.add("Pond Snail"); v.add("Assassin Snail"); model = new DefaultComboBoxModel<>(v); LISTS.put("Snails", model); v = new Vector<>(); v.add("Small Fine Net"); v.add("Large Fine Net"); v.add("Flaring Mirror"); v.add("Aquarium Hose"); model = new DefaultComboBoxModel<>(v); LISTS.put("Supplies", model); v = new Vector<>(); v.add("Tubifex"); v.add("Daphnia"); v.add("Optimum Pellets"); model = new DefaultComboBoxModel<>(v); LISTS.put("Food", model); } GuwiPos() { // ComboBox String[] products = {"Select Item...", "Betta Fish", "Snails", "Supplies", "Food"}; comboGroup = new JComboBox<String>(products); comboGroup.addItemListener(this::comboItemItemStateChanged); comboGroup.setBounds(130, 35, 150, 40); comboItem = new JComboBox<String>(); comboItem.setBounds(130, 85, 150, 40); // TextFields txtPrice = new JTextField(); txtPrice.setBounds(130, 135, 150, 40); txtQty = new JTextField(); txtQty.setBounds(130, 185, 150, 40); txtTotal = new JTextField(); txtTotal.setBounds(130, 235, 150, 40); // txtTotalAmt = new JTextField(); to code later on // txtPaid = new JTextField(); to code later on // txtChange = new JTextField(); to code later on // Labels // Product JLabel labelProduct = new JLabel(); labelProduct.setText("Item Group"); labelProduct.setBounds(10, 5, 100, 100); // Item JLabel labelItem = new JLabel(); labelItem.setText("Item"); labelItem.setBounds(10, 55, 100, 100); // Price JLabel labelPrice = new JLabel(); labelPrice.setText("Price"); labelPrice.setBounds(10, 105, 100, 100); // Qty JLabel labelQty = new JLabel(); labelQty.setText("Quantity"); labelQty.setBounds(10, 155, 100, 100); // Total JLabel labelTotal = new JLabel(); labelTotal.setText("Total"); labelTotal.setBounds(10, 205, 100, 100); // Buttons buttonBasket = new JButton(); buttonBasket.setBounds(0, 0, 300, 50); buttonBasket.setText("Add to Basket"); buttonBasket.setFocusable(false); buttonBasket.setBorder(BorderFactory.createEtchedBorder()); buttonBasket.addActionListener(this); JButton buttonPay = new JButton(); buttonPay.setText("PAY"); buttonPay.setBounds(0, 50, 150, 100); buttonPay.setFocusable(false); buttonPay.setBorder(BorderFactory.createEtchedBorder()); buttonPay.addActionListener(e -> System.out.println("Payment Success")); JButton buttonCancel = new JButton(); buttonCancel.setText("CANCEL"); buttonCancel.setBounds(0, 150, 150, 100); buttonCancel.setFocusable(false); buttonCancel.setBorder(BorderFactory.createEtchedBorder()); buttonCancel.addActionListener(e -> System.out.println("Transaction Cancelled")); JButton buttonDiscount = new JButton(); buttonDiscount.setText("Apply Discount?"); buttonDiscount.setBounds(150, 50, 150, 50); buttonDiscount.setFocusable(false); buttonDiscount.setBorder(BorderFactory.createEtchedBorder()); buttonDiscount.addActionListener(e -> System.out.println("20% Discount Applied")); JButton buttonHelp = new JButton(); buttonHelp.setText("HELP"); buttonHelp.setBounds(150, 100, 150, 100); buttonHelp.setFocusable(false); buttonHelp.setBorder(BorderFactory.createEtchedBorder()); JButton buttonDelete = new JButton(); buttonDelete.setText("DELETE"); buttonDelete.setBounds(150, 200, 150, 50); buttonDelete.setFocusable(false); buttonDelete.setBorder(BorderFactory.createEtchedBorder()); buttonDelete.addActionListener(e -> System.out.println("Item Deleted")); // Panels // Left contains item and price JPanel bluePanel = new JPanel(); bluePanel.setBackground(Color.blue); bluePanel.setBounds(0, 0, 300, 300); // x,y,width,height bluePanel.setLayout(null); // Right contains product basket JPanel redPanel = new JPanel(); redPanel.setBackground(Color.red); redPanel.setBounds(300, 0, 600, 300); // x,y,width,length redPanel.setLayout(null); // Bottom Left contains buttons pay,change,discount JPanel greenPanel = new JPanel(); greenPanel.setBackground(Color.green); greenPanel.setBounds(0, 300, 300, 450);// x,y,width,length greenPanel.setLayout(null); // Bottom Right contains total amount JPanel yellowPanel = new JPanel(); yellowPanel.setBackground(Color.yellow); yellowPanel.setBounds(0, 300, 900, 450);// x,y,width,length yellowPanel.setLayout(null); this.setTitle("Open Betta POS"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLayout(null); this.setSize(900, 590); this.setResizable(false); this.setVisible(true); // ADDED AWT bluePanel.add(txtQty); bluePanel.add(txtTotal); bluePanel.add(txtPrice); bluePanel.add(comboItem); bluePanel.add(comboGroup); bluePanel.add(labelProduct); bluePanel.add(labelItem); bluePanel.add(labelPrice); bluePanel.add(labelQty); bluePanel.add(labelTotal); greenPanel.add(buttonBasket); greenPanel.add(buttonPay); greenPanel.add(buttonCancel); greenPanel.add(buttonDiscount); greenPanel.add(buttonHelp); greenPanel.add(buttonDelete); this.add(bluePanel); this.add(redPanel); this.add(greenPanel); this.add(yellowPanel); } #Override public void actionPerformed(ActionEvent e) { if (e.getSource() == buttonBasket) { System.out.println("Added Item to Basket: " + comboGroup.getSelectedItem() + "\n" + comboItem.getSelectedItem()); } } // This is not working public void comboItemItemStateChanged(java.awt.event.ItemEvent evt) { if (evt.getStateChange() == ItemEvent.SELECTED) { Object selection = evt.getItem(); ArrayList<String> arrayItem = new ArrayList<>(); Iterator<String> iter; if (selection.equals("Betta Fish")) { comboItem.setModel(LISTS.get("Betta Fish")); } else if (selection.equals("Snails")) { comboItem.setModel(LISTS.get("Snails")); } else if (selection.equals("Supplies")) { comboItem.setModel(LISTS.get("Supplies")); } else if (selection.equals("Food")) { comboItem.setModel(LISTS.get("Food")); } else if (selection.equals("Select Item...")) { comboItem.removeAllItems(); arrayItem.add("Select Item..."); iter = arrayItem.iterator(); while (iter.hasNext()) { comboItem.addItem(iter.next()); } } } } public static void main(String[] args) { EventQueue.invokeLater(() -> new GuwiPos()); } }
Your code (improved version - minus one ActionListener) public class SwingApp { private static JComboBox<String> comboItem; private static JComboBox<String> productCombo; public static void main (String[] args) { SwingUtilities.invokeLater(new Runnable() { #Override public void run () { createAndShowGUI(); } }); } private static void createAndShowGUI () { JFrame frame = createMainFrame(); JPanel bluePanel = createBluePanel(); JPanel greenPanel = createGreenPanel(); JPanel redPanel = createRedPanel(); JPanel yellowPanel = createYellowPanel(); frame.add(bluePanel); frame.add(greenPanel); frame.add(redPanel); frame.add(yellowPanel); frame.setVisible(true); } private static JFrame createMainFrame () { JFrame frame = new JFrame("Open Betta POS"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(null); frame.setSize(900, 590); frame.setResizable(false); return frame; } private static JPanel createBluePanel () { ComboSelectionListener productComboListener = new ComboSelectionListener(); JPanel panel = new JPanel(null); // Sets layout manager to null which is a bad idea! String[] products = {"Select Item...", "Betta Fish", "Snails", "Supplies", "Food"}; productCombo = new JComboBox<>(products); productCombo.setBounds(130, 35, 150, 40); productCombo.setActionCommand("selectProduct"); productCombo.addActionListener(productComboListener); comboItem = new JComboBox<>(); comboItem.setBounds(130, 85, 150, 40); // TextFields JTextField txtPrice = new JTextField(); txtPrice.setBounds(130, 135, 150, 40); JTextField txtQty = new JTextField(); txtQty.setBounds(130, 185, 150, 40); JTextField txtTotal = new JTextField(); txtTotal.setBounds(130, 235, 150, 40); JLabel labelProduct = new JLabel(); labelProduct.setText("Item Group"); labelProduct.setBounds(10, 5, 100, 100); // Item JLabel labelItem = new JLabel(); labelItem.setText("Item"); labelItem.setBounds(10, 55, 100, 100); // Price JLabel labelPrice = new JLabel(); labelPrice.setText("Price"); labelPrice.setBounds(10, 105, 100, 100); // Qty JLabel labelQty = new JLabel(); labelQty.setText("Quantity"); labelQty.setBounds(10, 155, 100, 100); // Total JLabel labelTotal = new JLabel(); labelTotal.setText("Total"); labelTotal.setBounds(10, 205, 100, 100); panel.setBackground(Color.blue); panel.setBounds(0, 0, 300, 300); // x,y,width,height panel.add(txtQty); panel.add(txtTotal); panel.add(txtPrice); panel.add(comboItem); panel.add(productCombo); panel.add(labelProduct); panel.add(labelItem); panel.add(labelPrice); panel.add(labelQty); panel.add(labelTotal); return panel; } private static JPanel createGreenPanel () { JPanel panel = new JPanel(null); panel.setBackground(Color.green); panel.setBounds(0, 300, 300, 450);// x,y,width,length JButton buttonBasket = new JButton(); buttonBasket.setBounds(0, 0, 300, 50); buttonBasket.setText("Add to Basket"); buttonBasket.setFocusable(false); buttonBasket.setBorder(BorderFactory.createEtchedBorder()); buttonBasket .addActionListener(e -> System.out.println("Added Item to Basket: " + productCombo.getSelectedItem() + "\n" + comboItem.getSelectedItem())); JButton buttonPay = new JButton(); buttonPay.setText("PAY"); buttonPay.setBounds(0, 50, 150, 100); buttonPay.setFocusable(false); buttonPay.setBorder(BorderFactory.createEtchedBorder()); buttonPay.addActionListener(e -> System.out.println("Payment Success")); JButton buttonCancel = new JButton(); buttonCancel.setText("CANCEL"); buttonCancel.setBounds(0, 150, 150, 100); buttonCancel.setFocusable(false); buttonCancel.setBorder(BorderFactory.createEtchedBorder()); buttonCancel .addActionListener(e -> System.out.println("Transaction Cancelled")); JButton buttonDiscount = new JButton(); buttonDiscount.setText("Apply Discount?"); buttonDiscount.setBounds(150, 50, 150, 50); buttonDiscount.setFocusable(false); buttonDiscount.setBorder(BorderFactory.createEtchedBorder()); buttonDiscount .addActionListener(e -> System.out.println("20% Discount Applied")); JButton buttonHelp = new JButton(); buttonHelp.setText("HELP"); buttonHelp.setBounds(150, 100, 150, 100); buttonHelp.setFocusable(false); buttonHelp.setBorder(BorderFactory.createEtchedBorder()); JButton buttonDelete = new JButton(); buttonDelete.setText("DELETE"); buttonDelete.setBounds(150, 200, 150, 50); buttonDelete.setFocusable(false); buttonDelete.setBorder(BorderFactory.createEtchedBorder()); buttonDelete.addActionListener(e -> System.out.println("Item Deleted")); panel.add(buttonBasket); panel.add(buttonPay); panel.add(buttonCancel); panel.add(buttonDiscount); panel.add(buttonHelp); panel.add(buttonDelete); return panel; } private static JPanel createRedPanel () { JPanel panel = new JPanel(null); panel.setBackground(Color.red); panel.setBounds(300, 0, 600, 300); // x,y,width,length return panel; } private static JPanel createYellowPanel () { JPanel panel = new JPanel(); panel.setBackground(Color.yellow); panel.setBounds(0, 300, 900, 450); // x,y,width,length return panel; } private static class ComboSelectionListener implements ActionListener { #Override public void actionPerformed (ActionEvent e) { JComboBox<String> comboGroup = (JComboBox<String>) e.getSource(); ArrayList<String> arrayItem = new ArrayList<>(); Iterator<String> iter; if (comboGroup.getSelectedItem().equals("Betta Fish")) { comboItem.removeAllItems(); arrayItem.add("Plakat"); arrayItem.add("Halfmoon"); arrayItem.add("Crown Tail"); arrayItem.add("Double Tail"); iter = arrayItem.iterator(); while (iter.hasNext()) { comboItem.addItem(iter.next()); } } else if (comboGroup.getSelectedItem().equals("Snails")) { comboItem.removeAllItems(); arrayItem.add("Apple Horn"); arrayItem.add("RamsHorn"); arrayItem.add("Pond Snail"); arrayItem.add("Assassin Snail"); iter = arrayItem.iterator(); while (iter.hasNext()) { comboItem.addItem(iter.next()); } } else if (comboGroup.getSelectedItem().equals("Supplies")) { comboItem.removeAllItems(); arrayItem.add("Small Fine Net"); arrayItem.add("Large Fine Net"); arrayItem.add("Flaring Mirror"); arrayItem.add("Aquarium Hose"); iter = arrayItem.iterator(); while (iter.hasNext()) { comboItem.addItem(iter.next()); } } else if (comboGroup.getSelectedItem().equals("Food")) { comboItem.removeAllItems(); arrayItem.add("Tubifex"); arrayItem.add("Daphnia"); arrayItem.add("Optimum Pellets"); iter = arrayItem.iterator(); while (iter.hasNext()) { comboItem.addItem(iter.next()); } } else if (comboGroup.getSelectedItem().equals("Select Item...")) { comboItem.removeAllItems(); arrayItem.add("Select Item..."); iter = arrayItem.iterator(); while (iter.hasNext()) { comboItem.addItem(iter.next()); } } } } } Improvements made (aside from fixing the main issue) Created a Swing (main) class that is not a Swing component Main class doesn't implement ActionListener Used SwingUtilities to launch Swing Application Created methods to encapsulate the details involving the creation of components Minimized the scope of variables
I am trying to build a Multiple choice test in java and for some reason my code will only work for two questions and not anymore
This is the code for my quiz. import java.util.*; import java.util.List; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Main2 { public class Questions { String Question; String userAns; String realAns; } public static void main(String[] args) { JFrame frame = new JFrame ("Screen"); frame.setSize(2500, 2500); frame.setLayout(null); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panel = new JPanel(); frame.getContentPane().add(panel); panel.setSize(2500, 2500); panel.setLayout(null); //panel.setBackground(Color.red); Question[] questions = new Question[2]; System.out.println(questions.length); Question q1 = new Question(); q1.Question = "1) What is your Name?"; q1.A ="Bob"; q1.B="Billy"; q1.C="Joe"; q1.D="Jill"; questions[0] = q1; Question q2 = new Question(); q2.Question = "2) What is your Age?"; q2.A ="5"; q2.B="69"; q2.C="21"; q2.D="12"; questions[1] = q2; /* Question q3 = new Question(); q3.Question = "3) When Is your Birthday?"; q3.A = "May"; q3.B="Jan"; q3.C="Apr"; q3.D="Aug"; questions[2] = q3; */ //When this question is added the code breaks down JLabel Question = new JLabel(questions[0].Question); Question.setBounds(50, 0, 1500, 50); panel.add(Question); Question.setFont(new Font(Question.getFont().getName(), Font.PLAIN, 25)); Question.setVisible(true); JLabel incorrectAnswerLabel = new JLabel ("Incorrect Answer! Try Again"); incorrectAnswerLabel.setBounds(300, 0, 1000, 500); panel.add(incorrectAnswerLabel); incorrectAnswerLabel.setVisible(false); incorrectAnswerLabel.setFont(new Font(incorrectAnswerLabel.getFont().getName(), Font.BOLD, 46)); incorrectAnswerLabel.setForeground(Color.RED); JLabel correctAnswerLabel = new JLabel ("Correct Answer! Good Job"); correctAnswerLabel.setBounds(300, 0, 1000, 500); panel.add(correctAnswerLabel); correctAnswerLabel.setVisible(false); correctAnswerLabel.setFont(new Font(correctAnswerLabel.getFont().getName(), Font.BOLD, 46)); correctAnswerLabel.setForeground(Color.GREEN); JButton submitButton = new JButton(); submitButton.setBounds(50, 250, 150, 50); submitButton.setText("Submit"); panel.add(submitButton); submitButton.setVisible(true); JRadioButton OptionA = new JRadioButton(questions[0].A); OptionA.setBounds(50, 50, 100, 50); panel.add(OptionA); OptionA.setVisible(true); JRadioButton OptionB = new JRadioButton(questions[0].B); OptionB.setBounds(50, 100, 100, 50); panel.add(OptionB); OptionB.setVisible(true); JRadioButton OptionC = new JRadioButton(questions[0].C); OptionC.setBounds(50, 150, 100, 50); panel.add(OptionC); OptionC.setVisible(true); JRadioButton OptionD = new JRadioButton(questions[0].D); OptionD.setBounds(50, 200, 100, 50); panel.add(OptionD); OptionD.setVisible(true); ButtonGroup radioGroup = new ButtonGroup(); radioGroup.add(OptionA); radioGroup.add(OptionB); radioGroup.add(OptionC); radioGroup.add(OptionD); for(int i = 0; i < questions.length-1; i++) { final int count = i; submitButton.addActionListener(new ActionListener() { #Override public void actionPerformed(ActionEvent e) { if(submitButton.getText().equals("Submit")) { if(OptionA.isSelected()) { submitButton.setText("Next Question"); correctAnswerLabel.setVisible(true); } else incorrectAnswerLabel.setVisible(true); } else { correctAnswerLabel.setVisible(false); submitButton.setText("Submit"); Question q = questions[count+1]; Question.setText(q.Question); setAnswers(q.A, q.B, q.C, q.D, OptionA, OptionB, OptionC, OptionD); } } }); } } static void setAnswers(String A, String B,String C,String D, JRadioButton a, JRadioButton b, JRadioButton c, JRadioButton d) { List<String> answers = Arrays.asList(A, B,C,D); Collections.shuffle(answers); a.setText(answers.get(0)); b.setText(answers.get(1)); c.setText(answers.get(2)); d.setText(answers.get(3)); } } My code works fine with only two questions. When I add the third when in it doesn't even show the text for the problem. I tried debugging it to see if my code is still running. Seems to be that it does run. I worked for hours, but I in vain and desperately NEED help. Notes: The Correct Answer will always be Option A (I didn't get as far as being able to get the right answer) The Submit Button is supposed to saySubmit AND Next Question. For some reason changing the questions array length to 3 makes it not do this
public class Main2 { public class Questions { String Question; String userAns; String realAns; } static int count = 0; public static void main(String[] args) { JFrame frame = new JFrame("Screen"); frame.setSize(2500, 2500); frame.setLayout(null); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panel = new JPanel(); frame.getContentPane().add(panel); panel.setSize(2500, 2500); panel.setLayout(null); //panel.setBackground(Color.red); Question[] questions = new Question[3]; System.out.println(questions.length); Question q1 = new Question(); q1.Question = "1) What is your Name?"; q1.A = "Bob"; q1.B = "Billy"; q1.C = "Joe"; q1.D = "Jill"; questions[0] = q1; Question q2 = new Question(); q2.Question = "2) What is your Age?"; q2.A = "5"; q2.B = "69"; q2.C = "21"; q2.D = "12"; questions[1] = q2; Question q3 = new Question(); q3.Question = "3) When Is your Birthday?"; q3.A = "May"; q3.B = "Jan"; q3.C = "Apr"; q3.D = "Aug"; questions[2] = q3; //When this question is added the code breaks down JLabel Question = new JLabel(questions[0].Question); Question.setBounds(50, 0, 1500, 50); panel.add(Question); Question.setFont(new Font(Question.getFont().getName(), Font.PLAIN, 25)); Question.setVisible(true); JLabel incorrectAnswerLabel = new JLabel("Incorrect Answer! Try Again"); incorrectAnswerLabel.setBounds(300, 0, 1000, 500); panel.add(incorrectAnswerLabel); incorrectAnswerLabel.setVisible(false); incorrectAnswerLabel.setFont(new Font(incorrectAnswerLabel.getFont().getName(), Font.BOLD, 46)); incorrectAnswerLabel.setForeground(Color.RED); JLabel correctAnswerLabel = new JLabel("Correct Answer! Good Job"); correctAnswerLabel.setBounds(300, 0, 1000, 500); panel.add(correctAnswerLabel); correctAnswerLabel.setVisible(false); correctAnswerLabel.setFont(new Font(correctAnswerLabel.getFont().getName(), Font.BOLD, 46)); correctAnswerLabel.setForeground(Color.GREEN); JButton submitButton = new JButton(); submitButton.setBounds(50, 250, 150, 50); submitButton.setText("Submit"); panel.add(submitButton); submitButton.setVisible(true); JRadioButton OptionA = new JRadioButton(questions[0].A); OptionA.setBounds(50, 50, 100, 50); panel.add(OptionA); OptionA.setVisible(true); JRadioButton OptionB = new JRadioButton(questions[0].B); OptionB.setBounds(50, 100, 100, 50); panel.add(OptionB); OptionB.setVisible(true); JRadioButton OptionC = new JRadioButton(questions[0].C); OptionC.setBounds(50, 150, 100, 50); panel.add(OptionC); OptionC.setVisible(true); JRadioButton OptionD = new JRadioButton(questions[0].D); OptionD.setBounds(50, 200, 100, 50); panel.add(OptionD); OptionD.setVisible(true); ButtonGroup radioGroup = new ButtonGroup(); radioGroup.add(OptionA); radioGroup.add(OptionB); radioGroup.add(OptionC); radioGroup.add(OptionD); submitButton.addActionListener(new ActionListener() { #Override public void actionPerformed(ActionEvent e) { if (submitButton.getText().equals("Submit")) { if (OptionA.isSelected()) { submitButton.setText("Next Question"); correctAnswerLabel.setVisible(true); } else { incorrectAnswerLabel.setVisible(true); } } else { correctAnswerLabel.setVisible(false); submitButton.setText("Submit"); if(count < questions.length-1){ count = count+1; } Question q = questions[count]; Question.setText(q.Question); setAnswers(q.A, q.B, q.C, q.D, OptionA, OptionB, OptionC, OptionD); } } }); } static void setAnswers(String A, String B, String C, String D, JRadioButton a, JRadioButton b, JRadioButton c, JRadioButton d) { List<String> answers = Arrays.asList(A, B, C, D); Collections.shuffle(answers); a.setText(answers.get(0)); b.setText(answers.get(1)); c.setText(answers.get(2)); d.setText(answers.get(3)); } }
Array Index Starts from zero but the length starts from 1. The below will work if you want to add a 3rd question. Question[] questions = new Question[3]; Arrays are not dynamic and hence if you want to add questions dynamically use an ArrayList. Otherwise increase the length of array to size you feel comfortable with.
Can't compare button icon to another icon
I am overriding the actionListener. All of the buttons besides "playbutton" have an image attached as an icon (button1, button2, button3). Every time a button is pressed, it should compare its icon to the prepared ImageIcon "livePicture" and if they are the same, it should go with the "Escaped()" method. Otherwise, the program will run the "Died()" method. However, at least with the current code, it only uses "Died()". This, I guess, means that there is something wrong with the ifs that compare the images, but that is the only way of comparison I found on the internet. Also, keep in mind that this is my first project, so it may seem a little cluttered. import javax.imageio.ImageIO; import javax.swing.*; import javax.swing.border.Border; import java.awt.*; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Collections; import java.util.Vector; public class Frame { private final int WIDTH = 1024; private final int HEIGHT = 768; private JFrame frame; private JPanel panel; private JLabel human; private JTextArea text; private JTextArea deathMessage; private ImageIcon livePicture; private JButton button1; private JButton button2; private JButton button3; private GridBagConstraints gbc; private ActionListener actionListener; private JButton playButton; private Border border = BorderFactory.createEmptyBorder(); private Font font = new Font(Font.MONOSPACED, Font.PLAIN, 20); public Frame() { Quest survival = new Quest(); actionListener = e -> { if (e.getSource() == playButton) //playbutton works fine { if (!survival.IsEmpty()) { AppendQuest(survival.GetQuest()); survival.RemoveQuest(); } else { Escaped(); } } else if (e.getSource() == button1) //button1 action { if (button1.getIcon().toString() != livePicture.toString()) { Died(); } else { if (!survival.IsEmpty()) { AppendQuest(survival.GetQuest()); survival.RemoveQuest(); } else { Escaped(); } } } else if (e.getSource() == button2) //button2 action { if (button2.getIcon().toString() != livePicture.toString()) { Died(); } else { if (!survival.IsEmpty()) { AppendQuest(survival.GetQuest()); survival.RemoveQuest(); } else { Escaped(); } } } else if (e.getSource() == button3) //button3 action { if (button3.getIcon().toString() != livePicture.toString()) { Died(); } else { if (!survival.IsEmpty()) { AppendQuest(survival.GetQuest()); survival.RemoveQuest(); } else { Escaped(); } } } }; //I left the rest of the constructor for bonus info frame = new JFrame(); panel = new JPanel(); gbc = new GridBagConstraints(); human = new JLabel(ImageSize(200, 200, "res/human.png")); text = new JTextArea("You have lost in the forest. Now you have to find " + "your way back."); FormatText(text); deathMessage = new JTextArea(); frame.setTitle("Shady Path"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(WIDTH, HEIGHT); frame.setLocationRelativeTo(null); frame.getContentPane().setBackground(Color.BLACK); frame.setResizable(false); playButton = new JButton(); playButton.addActionListener(actionListener); playButton.setFont(font); playButton.setText("Play"); playButton.setForeground(Color.WHITE); playButton.setBackground(Color.BLACK); playButton.setBorder(border); panel.setLayout(new GridBagLayout()); panel.setOpaque(false); gbc.anchor = GridBagConstraints.PAGE_START; gbc.gridwidth = GridBagConstraints.REMAINDER; panel.add(human, gbc); gbc.insets = new Insets(30, 0, 0, 0); gbc.weightx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; panel.add(text, gbc); gbc.fill = GridBagConstraints.VERTICAL; gbc.insets = new Insets(50, 0, 68, 0); panel.add(playButton, gbc); frame.add(panel); frame.setVisible(true); } public void AppendQuest(Vector<String> event) { panel.removeAll(); panel.add(human, gbc); gbc.insets = new Insets(0, 0, 30, 0); text.setText(event.remove(0)); FormatText(text); panel.add(text, gbc); deathMessage.setText(event.remove(0)); FormatText(deathMessage); livePicture = ImageSize(50, 50, event.remove(0)); Collections.shuffle(event); ImageIcon picture1 = ImageSize(50, 50, event.get(0)); //setting button1 button1 = new JButton(); button1.addActionListener(actionListener); button1.setIcon(picture1); button1.setBorder(border); ImageIcon picture2 = ImageSize(50, 50, event.get(1)); //setting button2 button2 = new JButton(); button2.addActionListener(actionListener); button2.setIcon(picture2); button2.setBorder(border); ImageIcon picture3 = ImageSize(50, 50, event.get(2)); //setting button3 button3 = new JButton(); button3.addActionListener(actionListener); button3.setIcon(picture3); button3.setBorder(border); gbc.gridwidth = GridBagConstraints.HORIZONTAL; gbc.insets = new Insets(50, 360, 100, 0); panel.add(button1, gbc); gbc.insets = new Insets(50, 77, 100, 77); panel.add(button2, gbc); gbc.insets = new Insets(50, 0, 100, 360); panel.add(button3, gbc); panel.revalidate(); panel.repaint(); } private void Escaped() { //Unnecessary info } private void Died() { //Unnecessary info } //This just resizes the images private ImageIcon ImageSize(int x, int y, String fileName) { BufferedImage baseImg = null; try { baseImg = ImageIO.read(new File(fileName)); } catch (IOException e) { e.printStackTrace(); } Image resizedImg = baseImg.getScaledInstance(x, y, Image.SCALE_SMOOTH); ImageIcon IconImg = new ImageIcon(resizedImg); return IconImg; } private void FormatText(JTextArea baseText) { //Unnecessary info } } EDIT: Here is also an example of what vector could go as an "event" in "AppendQuest" Vector<String> items2 = new Vector<>(); items2.add("You are kind of disoriented. What will you use to find the right way?" + " moss, sun or tree barks"); items2.add("Unfortunately you didn't orient yourself well enough. Now, you " + "will roam through the forest forever."); items2.add("res/orientation_sun.png"); items2.add("res/orientation_moss.png"); items2.add("res/orientation_sun.png"); items2.add("res/orientation_tree_bark.png");
You can compare Objects with the .equals(Object) function: if(!button.getIcon().equals(livePicture)) { Died(); } else {...} The == operator checks the identity of objects or the value of native types (e.g. int). That means: int nr1 = 1; int nr2 = 1; if(nr1 == nr2) {...} //true -> int is a native type String str1 = "test"; String str2 = "test"; if(str1 == str2) {...} //false -> Same content but not same objects if(str1.equals(str2)) {...} //true -> Same content, different objects //Edit: Another problem might be that you remove the image-url from your vector while creating the livePicture: livePicture = ImageSize(50, 50, event.remove(0)); The url is not in the list anymore when you create your buttons. The result is that the buttons will never have the same image as your livePicture has, unless you're changing it (do you?).
Having trouble calling a JPanel from a different class
Im trying to create a Hangman game for my java class and im struggling with how to make each class work together. In this case, Im trying to write my phrase in from the selectPhrase method to the mainPanel. Im very new to programming so any help would be very appreciated. Thank you import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; /** * Created by Alex on 4/22/2016. */ ``public class HangmanGame extends JFrame implements ActionListener { public HangmanGame() { JPanel lettersPanel = new JPanel(new GridLayout(5,8,5,5)); JButton jbtA = new JButton("A"); JButton jbtB = new JButton("B"); JButton jbtC = new JButton("C"); JButton jbtD = new JButton("D"); JButton jbtE = new JButton("E"); JButton jbtF = new JButton("F"); JButton jbtG = new JButton("G"); JButton jbtH = new JButton("H"); JButton jbtI = new JButton("I"); JButton jbtJ = new JButton("J"); JButton jbtK = new JButton("K"); JButton jbtL = new JButton("L"); JButton jbtM = new JButton("M"); JButton jbtN = new JButton("N"); JButton jbtO = new JButton("O"); JButton jbtP = new JButton("P"); JButton jbtQ = new JButton("Q"); JButton jbtR = new JButton("R"); JButton jbtS = new JButton("S"); JButton jbtT = new JButton("T"); JButton jbtU = new JButton("U"); JButton jbtV = new JButton("V"); JButton jbtW = new JButton("W"); JButton jbtX = new JButton("X"); JButton jbtY = new JButton("Y"); JButton jbtZ = new JButton("Z"); lettersPanel.add(jbtA); lettersPanel.add(jbtB); lettersPanel.add(jbtC); lettersPanel.add(jbtD); lettersPanel.add(jbtE); lettersPanel.add(jbtF); lettersPanel.add(jbtG); lettersPanel.add(jbtH); lettersPanel.add(jbtI); lettersPanel.add(jbtJ); lettersPanel.add(jbtK); lettersPanel.add(jbtL); lettersPanel.add(jbtM); lettersPanel.add(jbtN); lettersPanel.add(jbtO); lettersPanel.add(jbtP); lettersPanel.add(jbtQ); lettersPanel.add(jbtR); lettersPanel.add(jbtS); lettersPanel.add(jbtT); lettersPanel.add(jbtU); lettersPanel.add(jbtV); lettersPanel.add(jbtW); lettersPanel.add(jbtX); lettersPanel.add(jbtY); lettersPanel.add(jbtZ); JPanel mainPanel = new JPanel(new BorderLayout()); setLayout(new GridLayout(2,2,5,5)); mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); mainPanel.add(lettersPanel, BorderLayout.EAST); mainPanel.setBackground(Color.BLACK); //mainPanel.add() add(mainPanel, BorderLayout.CENTER); } public static void main(String[] args) { JFrame frame = new HangmanGame(); frame.add(new HangmanGraphics()); frame.setTitle("Hangman"); frame.setSize(1020, 800); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); frame.setResizable(false); } static String selectPhrase() { String currentGuess = "*"; int[] previousValues = new int[5]; int totalRounds = 0; //set isValid equal to false and creates a random number between 1 and 6 //(between 1 and 6 because previousValues is used to store the old numbers, //and if between 0 and 5 were used, 0 would trip every time because an uninitialized //array has 0's (null) in every position) boolean isValid = false; int index = (int)(Math.random() * 5 + 1); //enters loop because isValid is false, so !isValid is true while(!isValid) { //sets isValid equal to true, so if it never gets changed during the loop, it will exit next time around isValid = true; for(int i = 0; i < totalRounds; i++) { //if the randomly generated value is one of the previous ones, make isValid false if(index == previousValues[i]) { isValid = false; } } //if isValid is false, create a new random number between 1 and 6 if(!isValid) { index = (int)(Math.random() * 5 + 1); } } //once a value that's never been used before is created, save it in previousValues //so that it is not used again previousValues[totalRounds] = index; totalRounds++; //return phrase at the index of the random number String[] phrase = {"NULL", "Go Team", "Hello World" , "Java Rocks", "Bread Bowl" , "Soup"}; return phrase[index]; for( int i=0; i<phrase.length; i++) { currentGuess = currentGuess.concat("?"); } .setText( currentGuess ); } #Override public void actionPerformed(ActionEvent e) { } } class HangmanGraphics extends JPanel { JPanel graphicsPanel = new JPanel(); int incorrectGuesses =0; #Override public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D g2D = (Graphics2D) g; BasicStroke aStroke = new BasicStroke(15.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); g2D.setStroke(aStroke); g2D.setColor(Color.BLUE); switch (incorrectGuesses) { case 10: g2D.drawLine(200, 200, 150, 250); // Left leg case 9: g2D.drawLine(200, 200, 250, 250); // Right leg case 8: g2D.drawLine(150, 150, 200, 175); // Left arm case 7: g2D.drawLine(250, 150, 200, 175); // Right arm case 6: g2D.drawLine(200, 200, 200, 150); // Torso case 5: g2D.drawOval(175, 100, 50, 50); // Head case 4: g2D.drawLine(200, 100, 200, 50);// Noose case 3: g2D.drawLine(200, 50, 100, 50);//Plank case 2: g2D.drawLine(100, 300, 100, 50); //Post case 1: g2D.drawLine(20, 300, 300, 300); //Stage } repaint(); graphicsPanel.add(new HangmanGraphics()); } }
Your issue, which is common to many if not most new developers, is the over use of static and a lack of understanding of Object Oriented Programming, and how to use objects. In your case, you are trying to create a main method inside a JFrame type object (HangmanGame) and then you have a static method you want to call, typically because you are trying to figure out how to call it from the static main method. You are better off creating a separate 'driver' class for HangManGame, that contains the main method. The HangManGame class then creates an instance of a HangManFrame (calls new HangManFrame()). The 2 important points to remember are: 1) In your main method, create an instance of the class that the main is defined in, then call methods on that object. By doing that, you don't need to declare a bunch of static methods and will avoid a lot of pain like you are experiencing now. For example, here is a definition of the HangManGame class: package hangman; public class HangManGame { HangManFrame frame; public HangManGame(){ frame = new HangManFrame(); } public void play() { frame.setVisible(true); String selectedPhrase = selectPhrase(); System.out.println("Selected phrase: " + selectedPhrase); } public String selectPhrase() { String currentGuess = "*"; int[] previousValues = new int[5]; int totalRounds = 0; //set isValid equal to false and creates a random number between 1 and 6 //(between 1 and 6 because previousValues is used to store the old numbers, //and if between 0 and 5 were used, 0 would trip every time because an uninitialized //array has 0's (null) in every position) boolean isValid = false; int index = (int)(Math.random() * 5 + 1); //enters loop because isValid is false, so !isValid is true while(!isValid) { //sets isValid equal to true, so if it never gets changed during the loop, it will exit next time around isValid = true; for(int i = 0; i < totalRounds; i++) { //if the randomly generated value is one of the previous ones, make isValid false if(index == previousValues[i]) { isValid = false; } } //if isValid is false, create a new random number between 1 and 6 if(!isValid) { index = (int)(Math.random() * 5 + 1); } } //once a value that's never been used before is created, save it in previousValues //so that it is not used again previousValues[totalRounds] = index; totalRounds++; //return phrase at the index of the random number String[] phrase = {"NULL", "Go Team", "Hello World" , "Java Rocks", "Bread Bowl" , "Soup"}; return phrase[index]; } public static void main(String[] args) { HangManGame game = new HangManGame(); game.play(); } } Notice that the only task the main method performs is to create an instance of the HangManGame class and call the play() method on that object..that's it! Also notice that the selectPhrase() method is not declared static, as it is not necessary. 2) For all your classes, objects that you need access to and need to be able to call methods on should be declared outside of methods as 'class-wide instance variables'. For example, notice how the HangManFrame is declared inside the HangManGame class, but outside of the methods. Then the frame is created and assigned inside the constructor for `HangManGame public class HangManGame { HangManFrame frame; public HangManGame(){ frame = new HangManFrame(); } ... } Doing this will allow you to call methods on the frame from within any of the HangManGame methods. I have slightly refactored your HangManFrame and HangManGraphics class, following similar stategies, included below. Finally, you should begin to create other methods on the HangManGame class, maybe like nextMove(), or updateBoard() or whatever, that are driven by and called from the play() method. HangManFrame class: package hangman; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class HangManFrame extends JFrame implements ActionListener { JPanel lettersPanel; public HangManFrame() { lettersPanel = new JPanel(new GridLayout(5, 8, 5, 5)); JButton jbtA = new JButton("A"); JButton jbtB = new JButton("B"); JButton jbtC = new JButton("C"); JButton jbtD = new JButton("D"); JButton jbtE = new JButton("E"); JButton jbtF = new JButton("F"); JButton jbtG = new JButton("G"); JButton jbtH = new JButton("H"); JButton jbtI = new JButton("I"); JButton jbtJ = new JButton("J"); JButton jbtK = new JButton("K"); JButton jbtL = new JButton("L"); JButton jbtM = new JButton("M"); JButton jbtN = new JButton("N"); JButton jbtO = new JButton("O"); JButton jbtP = new JButton("P"); JButton jbtQ = new JButton("Q"); JButton jbtR = new JButton("R"); JButton jbtS = new JButton("S"); JButton jbtT = new JButton("T"); JButton jbtU = new JButton("U"); JButton jbtV = new JButton("V"); JButton jbtW = new JButton("W"); JButton jbtX = new JButton("X"); JButton jbtY = new JButton("Y"); JButton jbtZ = new JButton("Z"); lettersPanel.add(jbtA); lettersPanel.add(jbtB); lettersPanel.add(jbtC); lettersPanel.add(jbtD); lettersPanel.add(jbtE); lettersPanel.add(jbtF); lettersPanel.add(jbtG); lettersPanel.add(jbtH); lettersPanel.add(jbtI); lettersPanel.add(jbtJ); lettersPanel.add(jbtK); lettersPanel.add(jbtL); lettersPanel.add(jbtM); lettersPanel.add(jbtN); lettersPanel.add(jbtO); lettersPanel.add(jbtP); lettersPanel.add(jbtQ); lettersPanel.add(jbtR); lettersPanel.add(jbtS); lettersPanel.add(jbtT); lettersPanel.add(jbtU); lettersPanel.add(jbtV); lettersPanel.add(jbtW); lettersPanel.add(jbtX); lettersPanel.add(jbtY); lettersPanel.add(jbtZ); JPanel mainPanel = new JPanel(new BorderLayout()); setLayout(new GridLayout(2, 2, 5, 5)); mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); mainPanel.add(lettersPanel, BorderLayout.EAST); mainPanel.setBackground(Color.BLACK); add(mainPanel, BorderLayout.CENTER); add(new HangmanGraphics()); setTitle("Hangman"); setSize(1020, 800); setLocationRelativeTo(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setResizable(false); } #Override public void actionPerformed(ActionEvent e) { System.out.println("Received actionPerformed event: " + e.getActionCommand()); } } HangManGraphics class: package hangman; import javax.swing.; import java.awt.; class HangmanGraphics extends JPanel { JPanel graphicsPanel = new JPanel(); int incorrectGuesses =0; #Override public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D g2D = (Graphics2D) g; BasicStroke aStroke = new BasicStroke(15.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); g2D.setStroke(aStroke); g2D.setColor(Color.BLUE); switch (incorrectGuesses) { case 10: g2D.drawLine(200, 200, 150, 250); // Left leg case 9: g2D.drawLine(200, 200, 250, 250); // Right leg case 8: g2D.drawLine(150, 150, 200, 175); // Left arm case 7: g2D.drawLine(250, 150, 200, 175); // Right arm case 6: g2D.drawLine(200, 200, 200, 150); // Torso case 5: g2D.drawOval(175, 100, 50, 50); // Head case 4: g2D.drawLine(200, 100, 200, 50);// Noose case 3: g2D.drawLine(200, 50, 100, 50);//Plank case 2: g2D.drawLine(100, 300, 100, 50); //Post case 1: g2D.drawLine(20, 300, 300, 300); //Stage } repaint(); graphicsPanel.add(new HangmanGraphics()); } }