I am trying to create a quiz. The quiz starts by reading a file. The file has 6 questions. Each question gets its own card in the cardlayout. Each card has a button to the next CardLayout. Questions 1 - 5 should have a 'next' button that links to the next card. Question 6 should have a button that says 'get results' this will link to a card that displays one of the possible results cards. (these are still in progress, for now I am simply trying to get the button created and am testing it with the .previous() method). As of now each card has a next button and it seems the statement that adds a 'get results' button isn't being reached. take a look.
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ItemListener;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class UserInterface extends JPanel {
public static final Object QUESTION = "question";
// fill label with blank text to expand it
private JLabel resultLabel = new JLabel(String.format("%150s", " "));
// CardLayout to allow swapping of question panels
private CardLayout cardLayout = new CardLayout();
private JPanel centerPanel = new JPanel(cardLayout);
private List<String> answers = new ArrayList<>();
private int currentCard = 0;
private QuestionsContainer containers = new QuestionsContainer();
public UserInterface(QuestionsContainer container) throws FileNotFoundException {
centerPanel.setBorder(BorderFactory.createLineBorder(Color.BLUE));
for (Questions question : container.getQuestions()) {
centerPanel.add(createQPanel(question), null);
currentCard++;
JPanel bottomPanel = new JPanel(new BorderLayout());
if ((currentCard == containers.questionsLength() - 1){
bottomPanel.add(new JButton(new AbstractAction("Next") {
#Override
public void actionPerformed(ActionEvent e) {
cardLayout.next(centerPanel);
}
}),
BorderLayout.LINE_START);
add(bottomPanel, BorderLayout.LINE_START);
bottomPanel.add(resultLabel);
setLayout(new BorderLayout());
add(bottomPanel, BorderLayout.PAGE_END);
add(centerPanel);
}
JPanel bottomPanel1 = new JPanel();
bottomPanel1.add(new JButton(new AbstractAction("Get Results") {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("hello");
cardLayout.previous(centerPanel);
// both of these are just to see if this statement is reached
bottomPanel.validate();
bottomPanel.repaint();
}
}),
BorderLayout.LINE_START);
add(bottomPanel1, BorderLayout.LINE_START);
bottomPanel1.add(resultLabel);
setLayout(new BorderLayout());
add(bottomPanel1, BorderLayout.PAGE_END);
add(centerPanel);
}
}
private JPanel createQPanel(Questions question) {
JPanel radioPanel = new JPanel(new GridLayout(0, 1));
radioPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
radioPanel.add(new JLabel(question.getQuestion()), BorderLayout.PAGE_START);
ButtonGroup buttonGroup = new ButtonGroup();
ItemListener myItemListener = new MyItemListener(this);
for (String answer : question.getAnswer()) {
JRadioButton answerButton = new JRadioButton(answer);
answerButton.putClientProperty(QUESTION, question);
answerButton.addItemListener(myItemListener);
buttonGroup.add(answerButton);
radioPanel.add(answerButton);
}
JPanel qPanel = new JPanel(new BorderLayout());
qPanel.add(radioPanel);
return qPanel;
}
public void displayResult(String selectedText) {
resultLabel.setText(selectedText);
}
public void displayFinalResults(){
}
public static void createAndShowGui() throws FileNotFoundException {
UserInterface mainPanel = new UserInterface(new QuestionsContainer());
JFrame frame = new JFrame("User Interface");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public class QuestionsContainer {
private List<Questions> questions = new ArrayList<>();
private int questionCount = 0;
QuestionsContainer() throws FileNotFoundException {
File file = new File("src/house1.txt");
try (Scanner reader = new Scanner(file)) {
String question = "";
List<String> answers = new ArrayList<>();
while (reader.hasNextLine()){
String line = reader.nextLine();
if (line.startsWith("QUESTION: ")) {
question = line.substring(10);
} else if (line.startsWith("ANSWER: ")){
String answer = line.substring(8);
answers.add(answer);
} else if (line.isEmpty()) {
questions.add(new Questions(question, answers));
question = "";
answers = new ArrayList<>();
questionCount++;
}
}
}
}
public List<Questions> getQuestions() {
return questions;
}
public int questionsLength(){
return questions.size();
}
I've tried making the bottomPanel its own method that returned a bottomPanel. this did not achieve the desired results because it was called in the constructor and I don't think the currentCard variable was adding up every time.
Right now this code reads all the questions fine and all the answers fine. But it creates a next button on every single card instead of on the first 5 only. if there's a variable in a weird place or a suspicious print call it's most likely leftover code from a previous test that I forgot to delete/comment out.
You seem to be thinking in terms of a procedural process, rather than an event driven process. The state of currentCard will be updated during each loop, it's state is not "stored" between iterations.
This means, as a side effect of BorderLayout, only the last component added to the container will be displayed.
Instead, you need to change your thinking, so that when the ActionListener is triggered, you update the state and make determinations about what should be done, for example
public UserInterface(QuestionsContainer container) throws FileNotFoundException {
setLayout(new BorderLayout());
centerPanel.setBorder(BorderFactory.createLineBorder(Color.BLUE));
for (Questions question : container.getQuestions()) {
centerPanel.add(createQPanel(question), null);
}
add(centerPanel);
JPanel navigationPane = new JPanel(new GridBagLayout());
navigationPane.setBorder(new EmptyBorder(8, 8, 8, 8));
JButton navButton = new JButton("Next");
navButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
if (evt.getActionCommand().equals("Next")) {
currentCard++;
if (currentCard == container.questionsLength()) {
((JButton) evt.getSource()).setText("Get results");
}
cardLayout.next(centerPanel);
} else {
System.out.println("Print the results");
}
}
});
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.EAST;
gbc.weightx = 1;
navigationPane.add(navButton, gbc);
add(navigationPane, BorderLayout.SOUTH);
}
Related
i have a problem with adding a specific number of buttons from my for-loop to my JPanel, i know how to add all oof them, but i want to add only 1-10 (i havent decided yet, lets go with 10).'
this is my class where i just declare what objects i want to have.
private static int cID;
private static Deck[] card;
static ArrayList<JButton> buttonList = new ArrayList<JButton>();
private JFrame f;
private JPanel p1;
private JButton button;
public boolean isEmpty() {
return cID == 0;
}
public static void main(String[] args) {
CustomDecks c = new CustomDecks();
c.deckCreator();
}```
this is my for-loop where i create 420 buttons and give them names "card" + i where i is 0 - 419, yet when i try to add card0 to my panel, it fails, why?
private void deckCreator() {
card = new Deck[25];
new ArrayList<Cards> (cSet.cards);
for(int i = 0; i < 420; i++) {
button = new JButton();
buttonList.add(button);
button.setName("card" + i);
f.add(button);
p1.add(card0);
}
f.add(p1);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setVisible(true);
f.setExtendedState(Frame.MAXIMIZED_BOTH);
f.setUndecorated(true);
}
}
}
I'm not sure you can create a JPanel large enough to hold 420 JButtons.
Here's an example of a JButton GUI.
[
Generally, you create an application model and view separately. The model is made up of one or more plain Java classes. The view reads from the application model but doesn't update the model.
Your controller classes (ActionListener classes) update the application model and update / repaint the view.
This pattern is called the model / view / controller (MVC) pattern.
You can see in the example code below that the model is created in the view class constructor. Generally, you create the application model first, then you create the application view.
And here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
public class JButtonScrollGUI {
private JFrame frame;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new JButtonScrollGUI();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private String[] greekAlphabet;
public JButtonScrollGUI() {
this.greekAlphabet = new String[] { "alpha", "beta", "gamma", "epsilon", "zeta" };
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setTitle("Application");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createScrollPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createScrollPanel() {
JPanel panel = new JPanel(new BorderLayout());
JPanel innerPanel = createButtonPanel();
Dimension d = innerPanel.getPreferredSize();
d.width += 50;
d.height /= 2;
panel.setPreferredSize(d);
JScrollPane scrollPane = new JScrollPane(innerPanel);
panel.add(scrollPane, BorderLayout.CENTER);
return panel;
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel(new GridLayout(0, 3, 10, 10));
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
for (int i = 0; i < 20; i++) {
JButton button1 = new JButton("Previous " + i);
panel.add(button1);
JComboBox<String> selectorBox = new JComboBox<>(greekAlphabet);
panel.add(selectorBox);
JButton button2 = new JButton("Next " + i);
button2.setPreferredSize(button1.getPreferredSize());
panel.add(button2);
}
return panel;
}
}
I am making a dating game in the style of the Japanese dating game with pictures and responses for fun and practice. I am trying to have a JOptionPane message dialog show up for each button in a grid layout as a response to each option. In this way it's like a logic tree. I am not used to using action listener as I am somewhat of a beginner. Here is my code. I am just not used to the syntax of doing this.
Can anyone help me?
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.util.Scanner;
import javax.swing.JFrame;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.*;
//Implementations of packages
public class NestedPanels extends JPanel {
private static final String[] BTN_TEXTS = { "Say Hello", "Say You Look Good", "Say Sorry I'm Late" }; //three buttons
private static final int TITLE_POINTS = 3; //number of objects in text box
public NestedPanels() { //implemeted class
JPanel southBtnPanel = new JPanel(new GridLayout(3, 2, 1, 1)); //grid layout of buttons and declaration of panel SoutbtnPanel
for (String btnText : BTN_TEXTS) { //BTN TEXT button titles linked to string btnText label
southBtnPanel.add(new JButton(btnText)); //add btnText label
}
setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); //layout of buttons "Button text"
setLayout(new BorderLayout());
add(Box.createRigidArea(new Dimension(600, 600))); //space size of text box webapp over all
add(southBtnPanel, BorderLayout.SOUTH);
}
private static void createAndShowGui() {//class to show gui
NestedPanels mainPanel = new NestedPanels(); //mainPanel new class of buttons instantiation
JFrame frame = new JFrame("Date Sim 1.0");//title of webapp on top
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setVisible(true);
ImageIcon icon = new ImageIcon("C:/Users/wchri/Pictures/10346538_10203007241845278_2763831867139494749_n.jpg");
JLabel label = new JLabel(icon);
mainPanel.add(label);
frame.setDefaultCloseOperation
(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
System.out.println("Welcome to Date Sim 1.0 with we1. Are you ready to play? Yes/No?");
Scanner in = new Scanner(System.in);
String confirm = in.nextLine();
if (confirm.equalsIgnoreCase("Yes")) {
System.out.println("Ok hot stuff... Let's start.");
NestedPanels mainPanel = new NestedPanels();
} else {
System.out.println("Maybe some other time!");
return;
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Review the following to get an idea of how to add action listener to buttons.
Please note the comments:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class NestedPanels extends JPanel {
private static final String[] BTN_TEXTS = { "Say Hello", "Say You Look Good", "Say Sorry I'm Late" }; //three buttons
//never used : private static final int TITLE_POINTS = 3;
public NestedPanels() {
JPanel southBtnPanel = new JPanel(new GridLayout(3, 2, 1, 1));
for (String btnText : BTN_TEXTS) {
JButton b = new JButton(btnText);
//add action listener
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
buttonClicked(e);//when button clicked, invoke method
}
});
//alternative much shorter way to add action listener:
//b.addActionListener(e -> buttonClicked());
southBtnPanel.add(b);
}
setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
setLayout(new BorderLayout());
//this adds Box to the default BorderLayout.CENTER position
add(Box.createRigidArea(new Dimension(600, 600)));
add(southBtnPanel, BorderLayout.SOUTH);
}
//respond to button clicked
private void buttonClicked(ActionEvent e) {
String msg = ((JButton)e.getSource()).getActionCommand()+" pressed" ;
JOptionPane.showMessageDialog(this, msg ); //display button Action
}
private static void createAndShowGui() {
NestedPanels mainPanel = new NestedPanels();
JFrame frame = new JFrame("Date Sim 1.0");
//no need to invoke twice frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
//no need to invoke twice frame.pack();
//no need to invoke twice frame.setVisible(true);
frame.getContentPane().add(mainPanel);
/*
* when posting images, use web resources that anyone can access
*
ImageIcon icon = new ImageIcon("C:/Users/wchri/Pictures/10346538_10203007241845278_2763831867139494749_n.jpg");
JLabel label = new JLabel(icon);
*this adds label to the default BorderLayout.CENTER position, which is already taken by
*the Box. Only one (last) component will be added
mainPanel.add(label);
*
*/
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//remove all code which is not essential to the question
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGui();
}
});
}
}
but I have already instantiated a parent class of extending the jpanel
Did you look at the example code provided in the tutorial???
The example there "
... extends JFrame implements ActionListener
So all you need is:
... extends JPanel implements ActionListener
Or in case you need multiple ActionListeners the more flexible approach to create a custom class.
You can use an "annonymous inner class" for the ActionListener. Something like:
ActionListener al = new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
JButton button = (JButton)e.getSource();
String text = button.getText();
Window window = SwingUtilities.windowForComponent(button);
JOptionPane.showMessageDialog(window, text);
}
};
Then when you create the button you would do:
for (String btnText : BTN_TEXTS)
{
JButton button = new JButton( btnText );
button.addActionListener( al );
southBtnPanel.add( button );
}
I am working on my final project and we are making a quiz to find out what kind of parties people like... but I can't get mine to run sequentially and with this right panels!
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.awt.*;
import javax.swing.ImageIcon;
import java.awt.Dimension;
import javax.swing.JPanel;
import java.awt.GridLayout;
import javax.swing.BoxLayout;
import java.awt.Component;
import java.awt.Container;
import javax.swing.JOptionPane;
import java.applet.Applet;
//This class is where we set up all the questions.
class party{
int num_questions = 10;
int panel_number = 0;
int party_score = 0;
JFrame frame = new JFrame();
String AnswerA;
String AnswerB;
String AnswerC;
String AnswerD;
JButton button1;
JButton button2;
JButton button3;
JButton button4;
String target_word;
String user_text;
String label_text;
JLabel question_frame;
JPanel pane;
JPanel panel;
public void image_question(){
//This panel will display four images that the user will choose from.
panel = new JPanel();
panel.setLayout(new BorderLayout());
label_text = "Which party appeals to you the most?";
question_frame = new JLabel(label_text);
question_frame.setFont(new Font("Calibri", Font.PLAIN, 20));
panel.add(question_frame, BorderLayout.NORTH);
button1 = new JButton();
JPanel inner = new JPanel();
inner.setLayout(new GridLayout(0, 2));
button1.setIcon(new ImageIcon("ball.jpg")); //img1
button1.setPreferredSize(new Dimension(100, 100));
button1.setActionCommand("1");
inner.add(button1);
button2 = new JButton();
button2.setIcon(new ImageIcon("christmas_party.jpg"));
button2.setPreferredSize(new Dimension(100, 100));
button2.setActionCommand("2");
inner.add(button2);
button3 = new JButton();
button3.setIcon(new ImageIcon("college_party.jpg"));
button3.setPreferredSize(new Dimension(100, 100));
button3.setActionCommand("3");
inner.add(button3);
button4 = new JButton();
button4.setIcon(new ImageIcon("kid_party.jpg"));
button4.setPreferredSize(new Dimension(100, 100));
button4.setActionCommand("4");
inner.add(button4);
panel.add(inner, BorderLayout.CENTER);
//ImageIcon icon = new ImageIcon("Alex.jpg");
//frame.getContentPane().add(new JLabel(icon), BorderLayout.EAST);
//frame.setVisible(true);
frame.add(panel);
ActionListener al = new click();
button1.addActionListener(al);
button2.addActionListener(al);
button3.addActionListener(al);
button4.addActionListener(al);
frame.setSize(600, 600);
frame.setVisible(true);
frame.setBackground(Color.white);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void multiple_choice_question(){
//This panel displays a 4 answer multiple choice question that they user will choose from.
pane = new JPanel();
pane.setLayout(new BorderLayout());
label_text = "What music would you prefer at a party?";
question_frame = new JLabel(label_text);
pane.add(question_frame, BorderLayout.NORTH);
JPanel center = new JPanel();
GridLayout grid = new GridLayout(0,2);
center.setLayout(grid);
pane.add(center, BorderLayout.CENTER);
AnswerA = "1";
AnswerB = "2";
AnswerC = "3";
AnswerD = "4";
ActionListener al = new click();
addAButton(AnswerA, center, al, "1");
addAButton(AnswerB, center, al, "2");
addAButton(AnswerC, center, al, "3");
addAButton(AnswerD, center, al, "4");
frame.add(pane);
frame.setSize(600, 600);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void input_question(){
//This panel will display a question and chance for the user to input their answer.
user_text = JOptionPane.showInputDialog(null, "Describe your ideal party");
target_word = "music";
if (user_text.indexOf(target_word) >=0){
System.out.println("ho ho ho");
}
}
public void party() {
panel_number++;
if (panel_number == 1){
image_question();
}
if(panel_number == 2){
multiple_choice_question();
}
if(panel_number == 3){
input_question();
}
/* else if (panel_number == 4){
image_question();
}
else if(panel_number == 5){
multiple_choice_question();
}
else if(panel_number == 6){
input_question();
}*/
}
private static void addAButton(String text, Container container, ActionListener al, String actionCommand) {
JButton button = new JButton(text);
button.setAlignmentX(Component.CENTER_ALIGNMENT);
container.add(button);
button.addActionListener(al);
button.setActionCommand(actionCommand);
}
public static void main(String args[]) {
party myGUI = new party();
myGUI.party();
}
class ClassParty{
//This class will read txt documents created by users and suggest a party that everyone would enjoy!
}
class click implements ActionListener{
public void actionPerformed(ActionEvent event){
party partier = new party();
if (event.getActionCommand().equals("1")){
party_score++;
}
else if (event.getActionCommand().equals("2")){
party_score++;
}
else if (event.getActionCommand().equals("3")){
party_score++;
}
else if (event.getActionCommand().equals("4")){
party_score++;
}
System.out.println(panel_number);
frame.dispose();
party();
//System.out.println(party_score);
/* creates a GUI that presents the user with a question with clickable answers that gives you the next question
when you finish answering. It plays jeapordy theme music and has a picture Alex Trabeck. It has a status bar
that tells you how close you are to finishing the program. */
}
}
}
When I run my code it runs the image_question twice and then runs input_question and quits. I can't get the multiple_choice_question to work.
I fixed it using debug and stepping through each command. Debug works great, you should try it. Debug was key because it showed that multiple_choice_question() was actually getting reached, even though the GUI looked like the first GUI. It narrowed down the source of the bug.
public void multiple_choice_question(){
frame=new JFrame(); <----add this and everything seems to be working
pane = new JPanel();
pane.setLayout(new BorderLayout());
label_text = "What music would you prefer at a party?";
...
I am working on my HOMEWORK (please don't do my work for me). I have 95% of it completed already. I am having trouble with this last bit though. I need to display the selected gender in the JTextArea. I must use the JRadioButton for gender selection.
I understand that JRadioButtons work different. I set up the action listener and the Mnemonic. I think I am messing up here. It would seem that I might need to use the entire group to set and action lister maybe.
Any help is greatly appreciated.
Here is what I have for my code (minus parts that I don't think are needed so others can't copy paste schoolwork):
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.border.TitledBorder;
public class LuisRamosHW3 extends JFrame {
private JLabel WelcomeMessage;
private JRadioButton jrbMale = new JRadioButton("Male");
private JRadioButton jrbFemale = new JRadioButton("Female");
public LuisRamosHW3(){
setLayout(new FlowLayout(FlowLayout.LEFT, 20, 30));
JPanel jpRadioButtons = new JPanel();
jpRadioButtons.setLayout(new GridLayout(2,1));
jpRadioButtons.add(jrbMale);
jpRadioButtons.add(jrbFemale);
add(jpRadioButtons, BorderLayout.AFTER_LAST_LINE);
ButtonGroup gender = new ButtonGroup();
gender.add(jrbMale);
jrbMale.setMnemonic(KeyEvent.VK_B);
jrbMale.setActionCommand("Male");
gender.add(jrbFemale);
jrbFemale.setMnemonic(KeyEvent.VK_B);
jrbFemale.setActionCommand("Female");
//Set defaulted selection to "male"
jrbMale.setSelected(true);
//Create Welcome button
JButton Welcome = new JButton("Submit");
add(Welcome);
Welcome.addActionListener(new SubmitListener());
WelcomeMessage = (new JLabel(" "));
add(WelcomeMessage);
}
class SubmitListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e){
String FirstName = jtfFirstName.getText();
String FamName = jtfLastName.getText();
Object StateBirth = jcbStates.getSelectedItem();
String Gender = gender.getActionCommand(); /*I have tried different
variations the best I do is get one selection to print to the text area*/
WelcomeMessage.setText("Welcome, " + FirstName + " " + FamName + " a "
+ gender.getActionCommmand + " born in " + StateBirth);
}
}
} /*Same thing with the printing, I have tried different combinations and just can't seem to figure it out*/
I have done a similar kind of a problem on JTable where we get the selection from the radio group and then act accordingly. Thought of sharing the solution.
Here, I have grouped the radio buttons using the action listener and each radio button will have an action command associated with it. When the user clicks on a radio button then an action will be fired subsequently an event is generated where we deselect other radio button selection and refresh the text area with the new selection.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextArea;
public class RadioBtnToTextArea {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
new RadioBtnToTextArea().createUI();
}
};
EventQueue.invokeLater(r);
}
private void createUI() {
JFrame frame = new JFrame();
JPanel panel = new JPanel(new BorderLayout());
JPanel radioPnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
JPanel textPnl = new JPanel();
JRadioButton radioMale = new JRadioButton();
JRadioButton radioFemale = new JRadioButton();
JTextArea textArea = new JTextArea(10, 30);
ActionListener listener = new RadioBtnAction(radioMale, radioFemale, textArea);
radioPnl.add(new JLabel("Male"));
radioPnl.add(radioMale);
radioMale.addActionListener(listener);
radioMale.setActionCommand("1");
radioPnl.add(new JLabel("Female"));
radioPnl.add(radioFemale);
radioFemale.addActionListener(listener);
radioFemale.setActionCommand("2");
textPnl.add(textArea);
panel.add(radioPnl, BorderLayout.NORTH);
panel.add(textPnl, BorderLayout.CENTER);
frame.add(panel);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class RadioBtnAction implements ActionListener {
JRadioButton maleBtn;
JRadioButton femaleBtn;
JTextArea textArea;
public RadioBtnAction(JRadioButton maleBtn,
JRadioButton femaleBtn,
JTextArea textArea) {
this.maleBtn = maleBtn;
this.femaleBtn = femaleBtn;
this.textArea = textArea;
}
#Override
public void actionPerformed(ActionEvent e) {
int actionCode = Integer.parseInt(e.getActionCommand());
switch (actionCode) {
case 1:
maleBtn.setSelected(true);
femaleBtn.setSelected(false);
textArea.setText("Male");
break;
case 2:
maleBtn.setSelected(false);
femaleBtn.setSelected(true);
textArea.setText("Female");
break;
default:
break;
}
}
}
Suggestions:
Make your ButtonGroup variable, gender, a field (declared in the class) and don't declare it in the constructor which will limit its scope to the constructor only. It must be visible throughout the class.
Make sure that you give your JRadioButton's actionCommands. JRadioButtons are not like JButtons in that if you pass a String into their constructor, this does not automatically set the JRadioButton's text, so you will have to do this yourself in your code.
You must first get the selected ButtonModel from the ButtonGroup object via getSelection()
Then check that the selected model is not null before getting its actionCommand text.
For example
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class RadioButtonEg extends JPanel {
public static final String[] RADIO_TEXTS = {"Mon", "Tues", "Wed", "Thurs", "Fri"};
// *** again declare this in the class.
private ButtonGroup buttonGroup = new ButtonGroup();
private JTextField textfield = new JTextField(20);
public RadioButtonEg() {
textfield.setFocusable(false);
JPanel radioButtonPanel = new JPanel(new GridLayout(0, 1));
for (String radioText : RADIO_TEXTS) {
JRadioButton radioButton = new JRadioButton(radioText);
radioButton.setActionCommand(radioText); // **** don't forget this
buttonGroup.add(radioButton);
radioButtonPanel.add(radioButton);
}
JPanel bottomPanel = new JPanel();
bottomPanel.add(new JButton(new ButtonAction("Press Me", KeyEvent.VK_P)));
setLayout(new BorderLayout());
add(radioButtonPanel, BorderLayout.CENTER);
add(bottomPanel, BorderLayout.PAGE_END);
add(textfield, BorderLayout.PAGE_START);
}
private class ButtonAction extends AbstractAction {
public ButtonAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
ButtonModel model = buttonGroup.getSelection();
if (model == null) {
textfield.setText("No radio button has been selected");
} else {
textfield.setText("Selection: " + model.getActionCommand());
}
}
}
private static void createAndShowGui() {
RadioButtonEg mainPanel = new RadioButtonEg();
JFrame frame = new JFrame("RadioButtonEg");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
The next function of my cardlayout is working properly, but previous isnt. As far as I'm concerned, just having "layout.previous(_);" in the actionPerformed method body in my makePanel() method should work, but when I run my program and click the prev button, nothing happens. What am I doing wrong? –
import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
public class Temp
{
public static void main (String[] args)
{
new MakeAQuiz();
}
static class MakeAQuiz
{
private JPanel start, base, fields, buttonz, question;
private String [] labels = {"Enter your question: ", "Answer 1: ", "Answer 2: ", "Answer 3: ", "Answer 4: "};
private JButton [] buttons = {new JButton("<<Go back"), new JButton("I'm done"), new JButton("Next>>")};
private JFrame makeFrame;
public MakeAQuiz()
{
start = new JPanel(new CardLayout());
start.add(makePanel(),"1");
makeFrame = new JFrame();
makeFrame.setSize(500,600);
makeFrame.add(start);
makeFrame.setVisible(true);
makeFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public JFrame getJFrame()
{
return makeFrame;
}
public JPanel makePanel()
{
question = new JPanel(new FlowLayout());
fields = new JPanel(new GridBagLayout());
buttonz = new JPanel(new FlowLayout());
base = new JPanel(new BorderLayout());
GridBagConstraints c = new GridBagConstraints();
c.weighty=0.5; //adds padding between the fields vertically
for (int i = 1; i<5; i++)
{
c.gridy++; //puts each field in a seperate line/row
JLabel label = new JLabel(labels[i]);
// c.fill = GridBagConstraints.HORIZONTAL;
fields.add(label,c);
JTextField textField = new JTextField(20);
fields.add(textField,c);
}
final CardLayout layout = (CardLayout)start.getLayout();
buttons[1].addActionListener(new ActionListener() {
// #Override
public void actionPerformed(ActionEvent e) {
buttons[0].setEnabled(false);
buttons[2].setEnabled(false);
// for(Component comp : cardPanel.getComponents()) {
// if(comp instanceof Page) {
// Page page = (Page)comp;
// page.printData();
// }
// }
}
});
buttons[2].addActionListener(new ActionListener()
{
// #Override
public void actionPerformed(ActionEvent e)
{
start.add(makePanel(), String.valueOf(start.getComponentCount() + 1));
layout.next(start);
}
});
buttons[0].addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
layout.previous(start);
}
});
buttonz.add(buttons[0]);
buttonz.add(buttons[1]);
buttonz.add(buttons[2]);
JLabel l = new JLabel(labels[0]);
JTextField t = new JTextField(30);
question.add(l);
question.add(t);
base.add(question,BorderLayout.NORTH);
base.add(buttonz,BorderLayout.SOUTH);
base.add(fields,BorderLayout.CENTER);
return base;
}
}
}
I have no issue (with your code), once I added some additional components to the start panel.
You will, however, have issues because you've added the buttons to the panel been displayed in the CardLayout.
A better solution would be to put the buttons at the bottom of the main screen and separate it from the cards.
You would need to maintain some kind of counter or reference to the current page, as CardLayout doesn't provide any way to obtain a reference to the current card. This would allow you to enabled/disable the next/previous buttons approritaly...
Updated with runnable example...
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MakeAQuiz {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
new MakeAQuiz();
}
});
}
private JPanel start, base, fields, buttonz, question;
private String[] labels = {"Enter your question: ", "Answer 1: ", "Answer 2: ", "Answer 3: ", "Answer 4: "};
private JButton[] buttons = {new JButton("<<Go back"), new JButton("I'm done"), new JButton("Next>>")};
private JFrame makeFrame;
public MakeAQuiz() {
start = new JPanel(new CardLayout());
start.add(makePanel(), "1");
makeFrame = new JFrame();
makeFrame.add(start);
buttonz = new JPanel(new FlowLayout());
final CardLayout layout = (CardLayout) start.getLayout();
buttons[1].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
buttons[0].setEnabled(false);
buttons[2].setEnabled(false);
}
});
buttons[2].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int count = start.getComponentCount();
start.add(new JLabel(Integer.toString(count), JLabel.CENTER), Integer.toString(count));
layout.next(start);
}
});
buttons[0].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
layout.previous(start);
}
});
buttonz.add(buttons[0]);
buttonz.add(buttons[1]);
buttonz.add(buttons[2]);
makeFrame.add(buttonz, BorderLayout.SOUTH);
makeFrame.pack();
makeFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
makeFrame.setVisible(true);
}
public JFrame getJFrame() {
return makeFrame;
}
public JPanel makePanel() {
question = new JPanel(new FlowLayout());
fields = new JPanel(new GridBagLayout());
base = new JPanel(new BorderLayout());
GridBagConstraints c = new GridBagConstraints();
c.weighty = 0.5; //adds padding between the fields vertically
for (int i = 1; i < 5; i++) {
c.gridy++; //puts each field in a seperate line/row
JLabel label = new JLabel(labels[i]);
// c.fill = GridBagConstraints.HORIZONTAL;
fields.add(label, c);
JTextField textField = new JTextField(20);
fields.add(textField, c);
}
JLabel l = new JLabel(labels[0]);
JTextField t = new JTextField(30);
question.add(l);
question.add(t);
base.add(question, BorderLayout.NORTH);
base.add(fields, BorderLayout.CENTER);
return base;
}
}
No. I think its not gonna work that way. Simply clicking the previous button will not bring anything back. You should save your entries somewhere else and load them to corresponding fields when clicking on the previous button.