THE SYLLABUS TASK
What you need to build
Build a Course Feedback Form UI.
Full syllabus requirements: classes, fields and methods
Desktop interaction, no standard input. Select a 1–5 rating for each of three questions, optionally type comments, then Submit. Clear removes every selection, comment and summary.
UNDERSTAND THE IDEA
Explanation
Each question has its own ButtonGroup so one rating can be chosen for that question without clearing other questions. JTextArea stores comments and shows the submitted summary.
Submit validates that all questions have ratings before displaying feedback. Clear resets both control state and output. The frame is created on Swing’s event-dispatch thread; this is an in-memory form, not a stored feedback service.
TURN THE IDEA INTO STEPS
Step-by-step algorithm
- Build rating groups and comment/summary areas.
- Wait for a Submit or Clear event.
- Require a selection in every rating group.
- Construct the summary from selected action commands.
- On Clear, clear all groups and text fields.
SEE THE CORE OPERATION
Flowchart
This chart focuses on the named operation or core OOP decision. Diamonds show conditions; labeled branches show outcomes. Read it with the complete algorithm and source for input handling and other operations. Scroll within the diagram on a phone.
Feedback Submit handler
Main.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Locale;
public class Main {
static JPanel root(String title) {
for(String key:new String[]{"Label.font","Button.font","RadioButton.font","CheckBox.font","TextField.font","TextArea.font","ComboBox.font"})UIManager.put(key,new Font(Font.SANS_SERIF,Font.PLAIN,18));
JPanel panel=new JPanel(new BorderLayout(12,12));panel.setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
JLabel heading=new JLabel(title);heading.setFont(new Font(Font.SANS_SERIF,Font.BOLD,24));panel.add(heading,BorderLayout.NORTH);return panel;
}
static void show(String title,JPanel panel) {
JFrame frame=new JFrame(title);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setContentPane(panel);frame.pack();frame.setLocationRelativeTo(null);frame.setVisible(true);
}
public static JPanel createPanel(){
JPanel panel=root("Course Feedback");JPanel form=new JPanel();form.setLayout(new BoxLayout(form,BoxLayout.Y_AXIS));
String[] questions={"Clarity of explanation","Practice usefulness","Overall experience"};ButtonGroup[] groups=new ButtonGroup[questions.length];
for(int q=0;q<questions.length;q++){
JPanel row=new JPanel(new FlowLayout(FlowLayout.LEFT));row.add(new JLabel(questions[q]));groups[q]=new ButtonGroup();
for(int r=1;r<=5;r++){JRadioButton button=new JRadioButton(Integer.toString(r));button.setActionCommand(Integer.toString(r));button.setName("rating-"+q+"-"+r);groups[q].add(button);row.add(button);}form.add(row);
}
JTextArea comments=new JTextArea(5,42);comments.setLineWrap(true);comments.setWrapStyleWord(true);comments.setName("comments");form.add(new JLabel("Suggestions / comments"));form.add(new JScrollPane(comments));
JTextArea output=new JTextArea(5,42);output.setEditable(false);output.setLineWrap(true);output.setWrapStyleWord(true);output.setName("summary");form.add(new JScrollPane(output));
JButton submit=new JButton("Submit"),clear=new JButton("Clear");JPanel buttons=new JPanel();buttons.add(submit);buttons.add(clear);form.add(buttons);
submit.addActionListener(e->{
StringBuilder result=new StringBuilder();
for(int q=0;q<groups.length;q++){if(groups[q].getSelection()==null){output.setText("Please answer every rating question.");return;}result.append(questions[q]).append(": ").append(groups[q].getSelection().getActionCommand()).append("/5\n");}
result.append("Comments: ").append(comments.getText().trim());output.setText(result.toString());
});
clear.addActionListener(e->{for(ButtonGroup group:groups)group.clearSelection();comments.setText("");output.setText("");});
panel.add(form,BorderLayout.CENTER);return panel;
}
public static void main(String[] args){SwingUtilities.invokeLater(()->show("Course Feedback",createPanel()));}
}
Copy a source file or download the project to preserve its file names.
USE THE RIGHT ENVIRONMENT
How to compile and run
Install a JDK (Java 11 or newer; JDK 17 is suitable), extract this project’s ZIP into its own folder, then open a terminal in that folder.
javac -encoding UTF-8 Main.java
java MainThis program opens a Swing desktop window. Run on your computer with a graphical desktop. A browser compiler or headless server cannot normally display this window. No console sample input is required.
Each experiment has its own folder because many use the public class Main. Compile and run one experiment at a time.
UNDERSTAND THE JAVA CODE
Line-by-line explanation
These steps follow the exact Java source above. Related statements are grouped; line numbers count blank lines and restart for each file. Start with main to follow execution, then open the constructors, methods or event handlers it uses.
Main.java
Lines 1–6Import Swing components, layouts and event types
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Locale;
public class Main {javax.swing supplies buttons, labels, panels and frames. java.awt supplies layouts, colours and fonts. java.awt.event supplies listener/event types. Locale is available where text formatting needs it. Main matches the source filename.
Lines 7–8Set readable component fonts in a reusable panel helper
static JPanel root(String title) {
for(String key:new String[]{"Label.font","Button.font","RadioButton.font","CheckBox.font","TextField.font","TextArea.font","ComboBox.font"})UIManager.put(key,new Font(Font.SANS_SERIF,Font.PLAIN,18));root configures the selected UIManager font keys to an 18-point sans-serif font before creating the form’s components. This affects the Java application, not the website’s CSS.
Lines 9–11Create a padded root panel with a heading
JPanel panel=new JPanel(new BorderLayout(12,12));panel.setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
JLabel heading=new JLabel(title);heading.setFont(new Font(Font.SANS_SERIF,Font.BOLD,24));panel.add(heading,BorderLayout.NORTH);return panel;
}BorderLayout places the heading in NORTH and leaves CENTER for each experiment’s form. The empty border adds padding; the heading uses a larger bold font. Return the JPanel for further assembly.
Lines 12–14Show the completed panel in a desktop window
static void show(String title,JPanel panel) {
JFrame frame=new JFrame(title);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setContentPane(panel);frame.pack();frame.setLocationRelativeTo(null);frame.setVisible(true);
}show creates a JFrame, installs its content, packs it to component sizes, centres it and makes it visible. EXIT_ON_CLOSE ends this demonstration application when its window closes. The desktop main calls this helper on the event-dispatch thread.
Lines 16–18Create the form and one selection group per question
public static JPanel createPanel(){
JPanel panel=root("Course Feedback");JPanel form=new JPanel();form.setLayout(new BoxLayout(form,BoxLayout.Y_AXIS));
String[] questions={"Clarity of explanation","Practice usefulness","Overall experience"};ButtonGroup[] groups=new ButtonGroup[questions.length];createPanel returns the assembled UI. A vertical BoxLayout stacks question rows. Each ButtonGroup enforces one radio selection for its own question, rather than one selection across the whole survey.
Lines 19–22Create five rating choices for each question
for(int q=0;q<questions.length;q++){
JPanel row=new JPanel(new FlowLayout(FlowLayout.LEFT));row.add(new JLabel(questions[q]));groups[q]=new ButtonGroup();
for(int r=1;r<=5;r++){JRadioButton button=new JRadioButton(Integer.toString(r));button.setActionCommand(Integer.toString(r));button.setName("rating-"+q+"-"+r);groups[q].add(button);row.add(button);}form.add(row);
}For each question, make a row and five radio buttons labelled 1–5. Action commands store the selected numeric rating; names identify components for tests. Add the radio buttons to both their logical group and the visible row.
Lines 23–24Provide editable comments and a read-only summary
JTextArea comments=new JTextArea(5,42);comments.setLineWrap(true);comments.setWrapStyleWord(true);comments.setName("comments");form.add(new JLabel("Suggestions / comments"));form.add(new JScrollPane(comments));
JTextArea output=new JTextArea(5,42);output.setEditable(false);output.setLineWrap(true);output.setWrapStyleWord(true);output.setName("summary");form.add(new JScrollPane(output));Comments wrap within a scroll pane. The output area is not editable by the student but its text can be updated by the listener. Component names support finding the correct fields in tests.
Lines 25–26Create buttons and register a submit callback
JButton submit=new JButton("Submit"),clear=new JButton("Clear");JPanel buttons=new JPanel();buttons.add(submit);buttons.add(clear);form.add(buttons);
submit.addActionListener(e->{Creating an ActionListener does not submit anything immediately. Its lambda runs later when Submit generates an action event.
Lines 27–30Build a summary only when every question has a rating
StringBuilder result=new StringBuilder();
for(int q=0;q<groups.length;q++){if(groups[q].getSelection()==null){output.setText("Please answer every rating question.");return;}result.append(questions[q]).append(": ").append(groups[q].getSelection().getActionCommand()).append("/5\n");}
result.append("Comments: ").append(comments.getText().trim());output.setText(result.toString());
});Use StringBuilder to accumulate the selected action commands. If any group has no selection, display the instruction and return from the listener. Otherwise append trimmed comments and replace the output text. No network request is made.
Lines 31–33Clear all form state and finish the panel
clear.addActionListener(e->{for(ButtonGroup group:groups)group.clearSelection();comments.setText("");output.setText("");});
panel.add(form,BorderLayout.CENTER);return panel;
}The Clear listener resets every radio group, comments and summary. Add the form to CENTER and return panel to the caller.
Lines 34–36Create and show Swing UI on the event-dispatch thread
public static void main(String[] args){SwingUtilities.invokeLater(()->show("Course Feedback",createPanel()));}
}SwingUtilities.invokeLater schedules the lambda on Swing’s event-dispatch thread. The lambda creates the panel and calls show. This main needs a graphical desktop; the panel and its event handlers are separate from console input.
FOLLOW THE STATE
Dry run
- Submit with no ratings displays a missing-answer message.
- Selecting 5 in each group and adding a comment displays three 5/5 ratings and that comment.
- Changing one group leaves the others selected.
- Clear returns the form to its blank initial state.
CHECK THE BEHAVIOUR
GUI preview & checks
These panels were rendered from this exact Java source. Event handlers were checked without a desktop window; window decorations and native error-dialog appearance can differ on your computer.


Try these checks
- Submit with no ratings displays a missing-answer message.
- Selecting 5 in each group and adding a comment displays three 5/5 ratings and that comment.
- Changing one group leaves the others selected.
- Clear returns the form to its blank initial state.
Common mistakes
- Use one ButtonGroup per question.
- Create/update Swing controls on the EDT.
- Validate before generating a complete summary.
WHY THIS GROWTH RATE?
Time and space complexity
O(q+C) submit processing for q questions and C comment characters; UI layout/painting is framework work.
Submit walks q groups and constructs a text summary including comments. Clear also visits every group and resets the text.
The component tree contains O(q) rating groups with a fixed five choices each. Swing’s rendering and event dispatch are separate from this handler’s data-processing cost.
These bounds describe the implemented data processing. Input/output text length, scheduling, framework rendering and runtime/library internals are identified separately where they matter. Educational limits bound the actual examples.
PREPARE FOR YOUR LAB VIVA
Related viva questions & answers
Try answering aloud, then expand to check your reasoning. Questions focus on this program’s classes, state and behavior.
Why does each feedback question need its own ButtonGroup?
A group enforces exclusivity among its rating choices. Sharing one group across all questions would allow only one rating for the entire form.
What is the purpose of a rating button’s action command?
It stores the selected numeric rating as a String. The submit handler reads it from the selected button model when constructing the summary.
Why is JTextArea suitable for comments?
It supports multiple lines and can wrap long text. A scroll pane keeps the form usable when suggestions exceed the visible area.
What does the Clear button reset beyond comments?
It clears every rating selection and the previous summary as well. Otherwise the form could retain old answers after appearing partly reset.
Why is the summary area read-only?
It is output generated from the submitted controls. Preventing direct edits avoids confusing manually typed text with the actual feedback result.
Does submitting this form save feedback to a database?
No. This lab displays an in-memory summary in the window. Persistence would need an additional storage layer outside the syllabus task.