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 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);
}
}
}
Hi I am creating a hangman game with GUI in Java and I had a problem when I added the JButtons for the letters to the GUI because they were not appearing. Not sure why. The code where I start adding the buttons is in the is in the GamePanel class and the Game, GameWord, GameMain and GameFrame classes and parts of the GamePanel class are not shown because they are not needed to understand and answer the question.
GamePanel class:
//some imports were omitted because they are irrelevant to the post
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JPanel;
import javax.swing.JButton;
public class GamePanel extends JPanel implements ActionListener
{
//some declarations were omitted because they are irrelevant to the post
private JButton a;
private JButton b;
private JButton c;
private JButton d;
private JButton e;
private JButton f;
private JButton g;
private JButton h;
private JButton i;
private JButton j;
private JButton k;
private JButton l;
private JButton m;
private JButton n;
private JButton o;
private JButton p;
private JButton q;
private JButton r;
private JButton s;
private JButton t;
private JButton u;
private JButton v;
private JButton w;
private JButton x;
private JButton y;
private JButton z;
public GamePanel(Game aGame)
{
// certain initialization's were omitted because they are irrelevant
this.addLetters();
}
public void paint(Graphics g)
{
//paint code goes here some parts were omitted as they are irrelevant to the post
repaint();
}
public void addLetters()
{
a = new JButton("A");
b = new JButton("B");
c = new JButton("C");
d = new JButton("D");
e = new JButton("E");
f = new JButton("F");
g = new JButton("G");
h = new JButton("H");
i = new JButton("I");
j = new JButton("J");
k = new JButton("K");
l = new JButton("L");
m = new JButton("M");
n = new JButton("N");
o = new JButton("O");
p = new JButton("P");
q = new JButton("Q");
r = new JButton("R");
s = new JButton("S");
t = new JButton("T");
u = new JButton("U");
v = new JButton("V");
w = new JButton("W");
x = new JButton("X");
y = new JButton("Y");
z = new JButton("Z");
a.addActionListener(this);
b.addActionListener(this);
c.addActionListener(this);
d.addActionListener(this);
e.addActionListener(this);
f.addActionListener(this);
g.addActionListener(this);
h.addActionListener(this);
i.addActionListener(this);
j.addActionListener(this);
k.addActionListener(this);
l.addActionListener(this);
m.addActionListener(this);
n.addActionListener(this);
o.addActionListener(this);
p.addActionListener(this);
q.addActionListener(this);
r.addActionListener(this);
s.addActionListener(this);
t.addActionListener(this);
u.addActionListener(this);
v.addActionListener(this);
w.addActionListener(this);
x.addActionListener(this);
y.addActionListener(this);
z.addActionListener(this);
a.setBounds(340, 250, 5, 5);
b.setBounds(350, 250, 5, 5);
c.setBounds(360, 250, 5, 5);
d.setBounds(370, 250, 5, 5);
e.setBounds(380, 250, 5, 5);
f.setBounds(390, 250, 5, 5);
g.setBounds(400, 250, 5, 5);
h.setBounds(410, 250, 5, 5);
i.setBounds(420, 250, 5, 5);
j.setBounds(430, 250, 5, 5);
k.setBounds(440, 250, 5, 5);
l.setBounds(450, 250, 5, 5);
m.setBounds(460, 250, 5, 5);
n.setBounds(340, 350, 5, 5);
o.setBounds(350, 350, 5, 5);
p.setBounds(360, 350, 5, 5);
q.setBounds(370, 350, 5, 5);
r.setBounds(380, 350, 5, 5);
s.setBounds(390, 350, 5, 5);
t.setBounds(400, 350, 5, 5);
u.setBounds(410, 350, 5, 5);
v.setBounds(420, 350, 5, 5);
w.setBounds(430, 350, 5, 5);
x.setBounds(440, 350, 5, 5);
y.setBounds(450, 350, 5, 5);
z.setBounds(460, 350, 5, 5);
a.setVisible(true);
b.setVisible(true);
c.setVisible(true);
d.setVisible(true);
e.setVisible(true);
f.setVisible(true);
g.setVisible(true);
h.setVisible(true);
i.setVisible(true);
j.setVisible(true);
k.setVisible(true);
l.setVisible(true);
m.setVisible(true);
n.setVisible(true);
o.setVisible(true);
p.setVisible(true);
q.setVisible(true);
r.setVisible(true);
s.setVisible(true);
t.setVisible(true);
u.setVisible(true);
v.setVisible(true);
w.setVisible(true);
x.setVisible(true);
y.setVisible(true);
z.setVisible(true);
this.add(a);
this.add(b);
this.add(c);
this.add(d);
this.add(e);
this.add(f);
this.add(g);
this.add(h);
this.add(i);
this.add(j);
this.add(k);
this.add(l);
this.add(m);
this.add(n);
this.add(o);
this.add(p);
this.add(q);
this.add(r);
this.add(s);
this.add(t);
this.add(u);
this.add(v);
this.add(w);
this.add(x);
this.add(y);
this.add(z);
}
public void actionPerformed(ActionEvent e)
{
//actionPerformed code omitted because it is irrelevant
}
}
(Not actually an answer; just to show you how much easier it is to implement the existing logic with a loop)
int x = 340;
for (char c = 'A'; c <= 'Z'; ++c, x += 10) {
JButton button = new JButton(Character.toString(c));
final char lower = Character.toLowercase(c);
button.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
game.checkGuess(lower);
}
});
button.setBounds(x, 250, 5, 5);
button.setVisible(true);
this.add(button);
}
Note that I have defined an anonymous per-button ActionListener, so there is no need to keep the references to the buttons in an array.
I figured it out you must call super.paint(g); it order to make the buttons appear and than in void addLetters() you must call this.setLayout(null); which will allow you to set the size and location of the button. I also added the buttons via a loop to get rid of unnecessary repetition. my paint() and addLetters() methods are below
paint() method
/**
* paint the graphics to the screen
*/
public void paint(Graphics g)
{
//paint code goes here some parts were omitted as they are irrelevant to the post
super.paint(g);
repaint();
}
addLetters() method
/**
* add the letter buttons to the screen
*/
public void addLetters()
{
int x = (this.getWidth()/2)-60;
int y = 300;
int btnSize =20;
int btnsAdded = 0;
for (Character c : game.getAlphabet())
{
this.setLayout(null);
JButton letter = new JButton(Character.toString(c).toUpperCase());
letter.setLayout(null);
letter.setSize(btnSize, btnSize);
letter.setLocation(x,y);
letter.setFont(new Font("Calibri",Font.PLAIN,10));
letter.setMargin(new Insets(0,0,0,0));
letter.setVisible(true);
this.add(letter);
char guess = Character.toLowerCase(c);
letter.addActionListener(new ActionListener()
{
#Override public void actionPerformed(ActionEvent e)
{
//actionPerformed code omitted because it is irrelevant
}
});
x += 25;
btnsAdded++;
if(btnsAdded == 13)
{
x=(this.getWidth()/2)-60;
y+=50;
}
}
}
I second what Andy Turner mentioned in comment: your code has much unnecessary repetition because you are not using arrays and/or collections such as ArrayLists, but as he noted, that's not the cause of your trouble.
One problem is that you're using setBounds(...) on components but forgetting that layout managers usually ignore bounds, location and size properties. Remember that JPanels use FlowLayout by default and so will place and size components based on this layout manager and the component's preferred size and will ignore your bounds. One solution is to use null layouts, but this leads to ugly GUI's that look terrible on all but one platform and are difficult to debug and maintain. No, learn to use and then use the layout managers. Remember that you can nest JPanels, each using its own layout and thereby achieve complex layouts with simple layout managers.
Also you're overriding JPanel's paint method but not calling the super's method, something that can cause serious side effects. Instead override paintComponent, not paint, and call the super's method in your override.
Note on testing your code, calling super.paint(g); as the first line of the paint method showed the buttons, though in the wrong place.
Note that rather than painting directly on the JPanel, one option instead is to create BufferedImages with your hangman on it, create ImageIcons of the images, and then draw them in a JLabel by calling setIcon(...) on the JLabel.
For example you could hold the buttons in a GridLayout-using JPanel:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class Hangman2 extends JPanel {
private static final int GAP = 5;
// best to create ImageIcons where you draw your Hangman in, and
// then display it in a JLabel by calling setIcon(...) on the label.
private JLabel imageLabel = new JLabel();
private List<Icon> iconList = createIcons();
public Hangman2() {
JLabel titleLabel = new JLabel("Welcome to Hangman", SwingConstants.CENTER);
titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, 40f));
JPanel buttonPanel = createButtonPanel();
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
setLayout(new BorderLayout());
add(titleLabel, BorderLayout.PAGE_START);
add(buttonPanel, BorderLayout.PAGE_END);
// placeholder component just to show something in the center of the GUI
add(Box.createRigidArea(new Dimension(200, 200)), BorderLayout.CENTER);
}
private List<Icon> createIcons() {
List<Icon> iconList = new ArrayList<>();
// TODO: create hangman drawing icons and place into array
return iconList;
}
private JPanel createButtonPanel() {
int rows = 2;
int cols = 16;
JPanel buttonPanel = new JPanel(new GridLayout(rows, cols, GAP, GAP));
// number of empty JLabels in the beginning and end of the bottom row
int labelCount = (2 * 16 - ('Z' - 'A' + 1)) / 2;
for (char c = 'A'; c <= 'Z'; c++) {
if (c - 'A' == cols) { // at 2nd row, add empty JLabels
for (int i = 0; i < labelCount; i++) {
buttonPanel.add(new JLabel());
}
}
JButton button = new JButton("" + c);
buttonPanel.add(button);
}
for (int i = 0; i < labelCount; i++) {
buttonPanel.add(new JLabel());
}
return buttonPanel;
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Hangman");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Hangman2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}