I need to create a simple GUI app using Swing in Eclipse. I've decided that I wanted to make a simple Car Rental service app.
I'm not too sure on how to attach prices to the car models and days that are in two separate combo boxes. I'm also not too sure on how to make the combined price of the car model and day appear in a text box once a hire button is pressed.
Below is a picture of my GUI just so you guys can see what I'm working with. I've also added my code that I have so far.
Picture of my GUI
private JLabel l0 = new JLabel(" Car Rental ");
private JLabel l1 = new JLabel("Name ");
private JTextField t1=new JTextField(" ",8);
private JLabel l2 = new JLabel("Email ");
private JTextField t2=new JTextField(" ",8);
private JLabel l3 = new JLabel("Phone Number ");
private JTextField t3=new JTextField("0",8);
private JLabel l4 = new JLabel("Car Model ");
private String [] models={"BMW","Mercedes","Audi"};
private JComboBox c1=new JComboBox(models);
private JLabel l5 = new JLabel("Days ");
private String [] days={"1","2","3","4","5","6","7"};
private JComboBox c2=new JComboBox(days);
private JButton b1=new JButton("Hire");
private JTextField t4=new JTextField("0",8);
private JButton b2=new JButton("Print Receipt");
private JButton b3=new JButton("Exit");
private JPanel p1=new JPanel();
public MyFrame2(String s){
super(s);
Container content=getContentPane();
content.setLayout(new FlowLayout());
Font f=new Font("TimesRoman", Font.BOLD,20);
p1.setLayout(new GridLayout(7,2));
l0.setFont(f); l1.setFont(f);
content.add(l0);
p1.add(l1); p1.add(t1);
p1.add(l2); p1.add(t2);
p1.add(l3); p1.add(t3);
p1.add(l4); p1.add(c1);
p1.add(l5); p1.add(c2);
p1.add(b1); p1.add(t4);
p1.add(b2); p1.add(b3);
content.add(p1);
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
setSize(270,320); setVisible(true);}
public void actionPerformed(ActionEvent e){
Object target=e.getSource();
if (target==b1)
if (target==b2){
System.out.println("====Receipt====");
System.out.println("Name: " + t1.getText());
System.out.println("Phone Number: " + t3.getText());
System.out.println("Car Model: " + c1.getSelectedItem());
System.out.println("Days: " + c2.getSelectedItem());}
if (target==b3) {
System.exit(1);}
}
}
The below code should get you started. It is incomplete since I didn't find all the requirements in your question.
Explanations after the code.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.math.BigDecimal;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class CarsHire implements ActionListener, Runnable {
private JButton exitButton;
private JButton hireButton;
private JButton receiptButton;
private JComboBox<Car> carModelsCombo;
private JComboBox<Integer> daysCombo;
private JFrame frame;
private JTextField emailTextField;
private JTextField nameTextField;
private JTextField phoneTextField;
private JTextField priceTextField;
#Override // java.awt.event.ActionListener
public void actionPerformed(ActionEvent event) {
Object src = event.getSource();
if (exitButton == src) {
System.exit(0);
}
else if (hireButton == src) {
displayPrice();
}
else if (receiptButton == src) {
System.out.println("====Receipt====");
System.out.println("Name: " + t1.getText());
System.out.println("Phone Number: " + t3.getText());
System.out.println("Car Model: " + c1.getSelectedItem());
System.out.println("Days: " + c2.getSelectedItem());
}
}
#Override // java.lang.Runnable
public void run() {
createAndShowGui();
}
private void createAndShowGui() {
frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createHeaderPanel(), BorderLayout.PAGE_START);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.add(createButtonsPanel(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel();
receiptButton = new JButton("Print Receipt");
receiptButton.setMnemonic(KeyEvent.VK_R);
receiptButton.addActionListener(this);
buttonsPanel.add(receiptButton);
exitButton = new JButton("Exit");
exitButton.setMnemonic(KeyEvent.VK_X);
exitButton.addActionListener(this);
buttonsPanel.add(exitButton);
exitButton.setPreferredSize(receiptButton.getPreferredSize());
return buttonsPanel;
}
private JPanel createHeaderPanel() {
JPanel headerPanel = new JPanel();
JLabel headerLabel = new JLabel("Car Rental");
Font f = new Font("TimesRoman", Font.BOLD, 20);
headerLabel.setFont(f);
headerPanel.add(headerLabel);
return headerPanel;
}
private JPanel createMainPanel() {
JPanel mainPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets.bottom = 5;
gbc.insets.left = 5;
gbc.insets.right = 5;
gbc.insets.top = 5;
gbc.anchor = GridBagConstraints.LINE_START;
// First row of form.
JLabel nameLabel = new JLabel("Name");
nameLabel.setDisplayedMnemonic(KeyEvent.VK_N);
mainPanel.add(nameLabel, gbc);
gbc.gridx = 1;
nameTextField = new JTextField(10);
mainPanel.add(nameTextField, gbc);
nameLabel.setLabelFor(nameTextField);
// Second row of form.
gbc.gridx = 0;
gbc.gridy = 1;
JLabel emailLabel = new JLabel("Email");
emailLabel.setDisplayedMnemonic(KeyEvent.VK_E);
mainPanel.add(emailLabel, gbc);
gbc.gridx = 1;
emailTextField = new JTextField(10);
mainPanel.add(emailTextField, gbc);
emailLabel.setLabelFor(emailTextField);
gbc.gridx = 0;
gbc.gridy = 2;
JLabel phoneLabel = new JLabel("Phone Number");
phoneLabel.setDisplayedMnemonic(KeyEvent.VK_P);
mainPanel.add(phoneLabel, gbc);
gbc.gridx = 1;
phoneTextField = new JTextField(10);
mainPanel.add(phoneTextField, gbc);
phoneLabel.setLabelFor(phoneTextField);
gbc.gridx = 0;
gbc.gridy = 3;
JLabel carModelLabel = new JLabel("Car Model");
carModelLabel.setDisplayedMnemonic(KeyEvent.VK_M);
mainPanel.add(carModelLabel, gbc);
gbc.gridx = 1;
Car[] carModels = new Car[]{new Car("BMW", new BigDecimal(36295)),
new Car("Mercedes", new BigDecimal(33795)),
new Car("Audi", new BigDecimal(34295))};
carModelsCombo = new JComboBox<>(carModels);
carModelsCombo.setSelectedIndex(-1);
mainPanel.add(carModelsCombo, gbc);
carModelLabel.setLabelFor(carModelsCombo);
gbc.gridx = 0;
gbc.gridy = 4;
JLabel daysLabel = new JLabel("Days");
daysLabel.setDisplayedMnemonic(KeyEvent.VK_D);
mainPanel.add(daysLabel, gbc);
gbc.gridx = 1;
daysCombo = new JComboBox<>(new Integer[]{1, 2, 3, 4, 5, 6, 7});
daysCombo.setSelectedIndex(-1);
mainPanel.add(daysCombo, gbc);
daysLabel.setLabelFor(daysCombo);
gbc.gridx = 0;
gbc.gridy = 5;
hireButton = new JButton("Hire");
hireButton.setMnemonic(KeyEvent.VK_H);
hireButton.addActionListener(this);
mainPanel.add(hireButton, gbc);
gbc.gridx = 1;
priceTextField = new JTextField(10);
mainPanel.add(priceTextField, gbc);
return mainPanel;
}
private void displayPrice() {
Car car = (Car) carModelsCombo.getSelectedItem();
if (car != null) {
BigDecimal price = car.getPrice();
priceTextField.setText(price.toString());
}
}
/**
* #param args
*/
public static void main(String[] args) {
EventQueue.invokeLater(new CarsHire());
}
}
class Car {
private String model;
private BigDecimal price;
public Car(String model, BigDecimal price) {
this.model = model;
this.price = price;
}
public String getModel() {
return model;
}
public BigDecimal getPrice() {
return price;
}
public String toString() {
return model;
}
}
Swing code is executed on the Event Dispatch Thread (EDT). The JFrame constructor will launch the EDT but there was a time where Oracle recommended explicitly launching the EDT via method invokeLater() of class EventQueue. That method takes a single argument which is an instance of a class that implements the Runnable interface.
Swing uses the Model-View-Controller (MVC) paradigm so each Swing component has a model that stores the data that the component displays. JComboBox model is its list of items. That list can contain objects of any class. The value displayed by the JComboBox is the value returned by the toString() method of the class. Hence I created a Car class that contains the car's model and its price. Hence what is displayed in the JComboBox is just the [car] model, but the selected item is actually an instance of class Car. So in the displayPrice() method, I know that the value returned by getSelectedItem() must be an instance of Car (or null if nothing is selected). From there it's simple to obtain the [car] price and display it in the priceTextField.
Initially, I thought the price meant the actual price of the car, that's why I used BigDecimal for the price in class Car.
As I said in my comment to your question, I use GridBagLayout since it is very suitable for laying out forms. There are other layout managers that are also suitable for laying out forms. I am just used to using GridBagLayout.
I also use mnemonics. For example if you press the keys Alt+H it will activate the Hire button and if you press Alt+N, the Name text field will become the focused field.
Refer to Using Top-Level Containers which is part of Oracle's java tutorials. The default content pane for a JFrame is a JPanel whose layout manager is BorderLayout. When you program in Swing you need to look at the source code a lot to understand what's going on and how best to utilize the framework.
Related
How do I add a break to put my "Make pokemon" buttons and textarea not in the same row as my "Pokemon choice." I'm trying to put an empty JLabel, but I don't think it works.
public class PokemonPanel extends JPanel {
private JLabel lTitle = new JLabel("Pokemon");
private JLabel lMsg = new JLabel(" ");
private JButton bDone = new JButton(" Make Pokemon ");
private JButton bClear = new JButton(" Clear ");
private JPanel topSubPanel = new JPanel();
private JPanel centerSubPanel = new JPanel();
private JPanel bottomSubPanel = new JPanel();
private GUIListener listener = new GUIListener();
private Choice chSpe = new Choice();
private JLabel lEmp = new JLabel(" ");
private PokemonGUILizylf st;
private final int capacity = 10;
private PokemonGUILizylf[ ] stArr = new PokemonGUILizylf[capacity];
private int count = 0;
private String sOut = new String("");
private JTextArea textArea = new JTextArea(400, 500);
private JTextArea textArea2 = new JTextArea(400, 500);
private JScrollPane scroll = new JScrollPane(textArea,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
public PokemonPanel() {
this.setLayout(new BorderLayout());
this.setPreferredSize(new Dimension(400, 500));
topSubPanel.setBackground(Color.cyan);
centerSubPanel.setBackground(Color.white);
bottomSubPanel.setBackground(Color.white);
topSubPanel.add(lTitle);
this.add("North", topSubPanel);
JLabel lSpe = new JLabel("Pokemon Available: ");
JLabel lEmp = new JLabel(" ");
JLabel lNew = new JLabel("New Pokemon: ");
//add choices to the choice dropdown list
chSpe.add("Choose");
chSpe.add("Bulbasaur");
chSpe.add("Venusaur");
chSpe.add("Ivysaur");
chSpe.add("Squirtle");
chSpe.add("Wartortle");
chSpe.add("Blastoise");
chSpe.add("Charmander");
chSpe.add("Charmeleon");
chSpe.add("Charizard");
centerSubPanel.add(lSpe);
centerSubPanel.add(chSpe);
centerSubPanel.add(lEmp);
centerSubPanel.add(bDone);
centerSubPanel.add(lNew);
textArea.setPreferredSize(new Dimension(500, 200));
textArea.setEditable(false);
textArea2.setPreferredSize(new Dimension(500, 200));
textArea2.setEditable(false);
textArea.setBackground(Color.white);
textArea.setEditable(false);
scroll.setBorder(null);
centerSubPanel.add(scroll); //add scrollPane to panel, textArea inside.
scroll.getVerticalScrollBar().setPreferredSize(new Dimension(10, 0));
add("Center", centerSubPanel);
bottomSubPanel.add(lMsg);
bDone.addActionListener(listener); //add listener to button
bottomSubPanel.add(bClear);
bClear.addActionListener(listener); //add listener to button
//add bottomSubPanel sub-panel to South area of main panel
add("South", bottomSubPanel);
}
This is what my GUI looks like:
enter image description here
But it should show like this:
enter image description here
Can someone explain to me how I can do that?
Use a different layout manager (other then default FlowLayout which JPanel uses)
See Laying Out Components Within a Container for more details.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
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() {
JFrame frame = new JFrame();
frame.add(new PokemonPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class PokemonPanel extends JPanel {
private JLabel lTitle = new JLabel("Pokemon");
// private JLabel lMsg = new JLabel(" ");
private JButton bDone = new JButton("Make Pokemon ");
private JButton bClear = new JButton("Clear");
private JPanel topSubPanel = new JPanel();
private JPanel centerSubPanel = new JPanel(new GridBagLayout());
private JPanel bottomSubPanel = new JPanel();
// private GUIListener listener = new GUIListener();
private JComboBox<String> chSpe = new JComboBox<>();
private JLabel lEmp = new JLabel(" ");
// private PokemonGUILizylf st;
private final int capacity = 10;
// private PokemonGUILizylf[] stArr = new PokemonGUILizylf[capacity];
// private int count = 0;
// private String sOut = new String("");
// private JTextArea textArea = new JTextArea(400, 500);
// private JTextArea textArea2 = new JTextArea(400, 500);
//
// private JScrollPane scroll = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
// JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
public PokemonPanel() {
this.setLayout(new BorderLayout());
// this.setPreferredSize(new Dimension(400, 500));
topSubPanel.setBackground(Color.cyan);
centerSubPanel.setBackground(Color.white);
bottomSubPanel.setBackground(Color.white);
topSubPanel.add(lTitle);
this.add("North", topSubPanel);
JLabel lSpe = new JLabel("Pokemon Available: ");
JLabel lNew = new JLabel("New Pokemon: ");
//add choices to the choice dropdown list
DefaultComboBoxModel<String> chSpeModel= new DefaultComboBoxModel<>();
chSpeModel.addElement("Choose");
chSpeModel.addElement("Bulbasaur");
chSpeModel.addElement("Venusaur");
chSpeModel.addElement("Ivysaur");
chSpeModel.addElement("Squirtle");
chSpeModel.addElement("Wartortle");
chSpeModel.addElement("Blastoise");
chSpeModel.addElement("Charmander");
chSpeModel.addElement("Charmeleon");
chSpeModel.addElement("Charizard");
chSpe.setModel(chSpeModel);
centerSubPanel.setBorder(new EmptyBorder(4, 4, 4, 4));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(4, 4, 4, 4);
gbc.anchor = GridBagConstraints.LINE_END;
centerSubPanel.add(lSpe, gbc);
gbc.gridx++;
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridwidth = GridBagConstraints.REMAINDER;
centerSubPanel.add(chSpe);
gbc.anchor = GridBagConstraints.NORTH;
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy++;
centerSubPanel.add(bDone, gbc);
gbc.gridx++;
gbc.anchor = GridBagConstraints.FIRST_LINE_END;
centerSubPanel.add(lNew, gbc);
gbc.gridx++;
gbc.gridheight = gbc.REMAINDER;
centerSubPanel.add(new JScrollPane(new JTextArea(10, 10)), gbc);
// textArea.setEditable(false);
// textArea2.setEditable(false);
//
// textArea.setBackground(Color.white);
// textArea.setEditable(false);
// scroll.setBorder(null);
// centerSubPanel.add(scroll); //add scrollPane to panel, textArea inside.
// scroll.getVerticalScrollBar().setPreferredSize(new Dimension(10, 0));
add("Center", centerSubPanel);
// bottomSubPanel.add(lMsg);
// bDone.addActionListener(listener); //add listener to button
bottomSubPanel.add(bClear);
// bClear.addActionListener(listener); //add listener to button
//add bottomSubPanel sub-panel to South area of main panel
add("South", bottomSubPanel);
}
}
}
Also, avoid using setPreferredSize, let the layout managers do their job. In the example I'm used insets (from GridBagConstraints) and an EmptyBorder to add some additional space around the components
Also, be careful of using AWT components (ie Choice), they don't always play nicely with Swing. In this case, you should be using JComboBox
I'd like to have a GUI that can adapt to user input, rather than making a different panel for each option.
The first panel has a number of buttons to choose from, each will bring you to the next panel that will contain text entry fields.
Option A: Has 2 components and should open a panel with 4 text fields.
Option B: Has 3 components and should open a panel with 6 text fields.
Specifically, option A is a recipe with two components, and option B is a recipe with 3 components. Each component has a lot number and an expiration date. So both panels will have the same two types of fields: lot number and expiration date. The number and names of components is what will change.
Can I have the same panel be able to adapt to a number of components sent to it based on which of the two options was selected? Or do I have to make two separate panels, one with 4 fields and one with 6?
Here's one idea:
Map<String, JTextField> fieldMap = new HashMap<String, JTextField>()
for(int i = 0; i < recipe.length; i++)
{
fieldMap.put("field" + i, new JTextField());
}
Idea derived from Creating a variable name using a String value
The code below addresses specifically your question statement, although I can't help thinking that you probably want something more generic, i.e. where there are more than two options. Also, the below code is only one possible implementation of your stated requirements.
The idea in the below code is to initially create all the required GUI components in a single container and simply change the visibility of the [optional] components depending on the selected option.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerDateModel;
public class Opciones implements ActionListener {
private JFrame frame;
private JLabel expiryThirdLabel;
private JLabel lotThirdLabel;
private JRadioButton twoRadioButton;
private JRadioButton threeRadioButton;
private JSpinner expiryFirstSpinner;
private JSpinner expirySecondSpinner;
private JSpinner expiryThirdSpinner;
private JTextField lotFirstTextField;
private JTextField lotSecondTextField;
private JTextField lotThirdTextField;
public void actionPerformed(ActionEvent event) {
Object src = event.getSource();
boolean flag;
if (twoRadioButton == src) {
flag = false;
}
else if (threeRadioButton == src) {
flag = true;
}
else {
flag = false;
JOptionPane.showMessageDialog(frame,
"Unrecognized source.",
"WARNING",
JOptionPane.WARNING_MESSAGE);
}
expiryThirdLabel.setVisible(flag);
expiryThirdSpinner.setVisible(flag);
lotThirdLabel.setVisible(flag);
lotThirdTextField.setVisible(flag);
frame.pack();
}
private void createAndDisplayGui() {
frame = new JFrame("Options");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createTopPanel(), BorderLayout.PAGE_START);
frame.add(createForm(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createForm() {
JPanel form = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.LINE_START;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets.bottom = 5;
gbc.insets.left = 5;
gbc.insets.right = 5;
gbc.insets.top = 5;
JLabel lotFirstLabel = new JLabel("Lot Number");
form.add(lotFirstLabel, gbc);
gbc.gridx = 1;
lotFirstTextField = new JTextField(6);
form.add(lotFirstTextField, gbc);
gbc.gridx = 2;
JLabel expiryFirstLabel = new JLabel("Expiry");
form.add(expiryFirstLabel, gbc);
gbc.gridx = 3;
expiryFirstSpinner = createSpinner();
form.add(expiryFirstSpinner, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
JLabel lotSecondLabel = new JLabel("Lot Number");
form.add(lotSecondLabel, gbc);
gbc.gridx = 1;
lotSecondTextField = new JTextField(6);
form.add(lotSecondTextField, gbc);
gbc.gridx = 2;
JLabel expirySecondLabel = new JLabel("Expiry");
form.add(expirySecondLabel, gbc);
gbc.gridx = 3;
expirySecondSpinner = createSpinner();
form.add(expirySecondSpinner, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
lotThirdLabel = new JLabel("Lot Number");
lotThirdLabel.setVisible(false);
form.add(lotThirdLabel, gbc);
gbc.gridx = 1;
lotThirdTextField = new JTextField(6);
lotThirdTextField.setVisible(false);
form.add(lotThirdTextField, gbc);
gbc.gridx = 2;
expiryThirdLabel = new JLabel("Expiry");
expiryThirdLabel.setVisible(false);
form.add(expiryThirdLabel, gbc);
gbc.gridx = 3;
expiryThirdSpinner = createSpinner();
expiryThirdSpinner.setVisible(false);
form.add(expiryThirdSpinner, gbc);
return form;
}
private JSpinner createSpinner() {
SpinnerDateModel sdm = new SpinnerDateModel();
JSpinner spinner = new JSpinner(sdm);
spinner.setEditor(new JSpinner.DateEditor(spinner, "MM/dd/yyyy")); // USA format
return spinner;
}
private JPanel createTopPanel() {
JPanel topPanel = new JPanel();
JLabel label = new JLabel("Number of Components");
topPanel.add(label);
ButtonGroup buttonGroup = new ButtonGroup();
twoRadioButton = new JRadioButton("Two");
twoRadioButton.addActionListener(this);
twoRadioButton.setSelected(true);
buttonGroup.add(twoRadioButton);
topPanel.add(twoRadioButton);
threeRadioButton = new JRadioButton("Three");
threeRadioButton.addActionListener(this);
buttonGroup.add(threeRadioButton);
topPanel.add(threeRadioButton);
return topPanel;
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new Opciones().createAndDisplayGui());
}
}
Initially, the GUI looks like this
And after selecting Three radio button
Refer to the following.
How to Use Buttons, Check Boxes, and Radio Buttons
How to Make Frames (Main Windows)
How to Use Spinners
How to Use GridBagLayout
How to Write an Action Listener
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GUI_Borrower extends JFrame implements ActionListener {
JPanel panel = new JPanel();
JLabel lblName = new JLabel("Name:");
JLabel lblProg = new JLabel("Program:");
JLabel lblId = new JLabel("Library ID: ");
JLabel lblTitle = new JLabel("Add Borrower");
JTextField txtName = new JTextField(10);
JTextField txtProg = new JTextField(10);
JTextField txtId = new JTextField(10);
static int counter = 19000;
JButton btnSubmit = new JButton("Submit");
public GUI_Borrower() {
super("Add Borrower");
makeFrame();
showFrame();
}
public void makeFrame() {
lblTitle.setFont(new Font("Forte", Font.PLAIN, 40));
lblTitle.setForeground(Color.BLUE);
add(lblTitle);
add(lblName);
add(txtName);
add(lblProg);
add(txtProg);
add(lblId);
add(txtId);
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
panel.add(btnSubmit);
btnSubmit.addActionListener(this);
}
public void showFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 200);
setLocationRelativeTo(null);
setVisible(true);
}
public void actionPerformed(ActionEvent ae) {
Object source = ae.getSource();
if (ae.getActionCommand().equals("Confirm")) {
txtName.setText("");
txtProg.setText("");
btnSubmit.setText("Submit");
} else if (source == btnSubmit) {
if (txtName.getText().equals("") && txtProg.getText().equals("")) {
txtId.setText("No entry of both");
} else if (txtName.getText().equals("")) {
txtId.setText("No entry of Name");
} else if (txtProg.getText().equals("")) {
txtId.setText("No entry of Program");
} else {
counter++;
txtId.setText("" + counter);
btnSubmit.setText("Confirm");
}
}
}
public static void main(String[] args) {
new GUI_Borrower();
}
}
I tried adding BoxLayout because all the text fields and labels are on one line. So I tried box Layout and failed.
Can anyone show me how to make it like the title one line, label Different line, button different line?
Like this:
As camickr says in his comment, you generally use a GridBagLayout to create a form.
I reworked your code because I hope to show a better way to code a GUI panel.
Here's the GUI.
The major changes I made include:
All Swing applications must start with a call to the SwingUtilities invokeLater method. This method ensures that all Swing components are created and executed on the Event Dispatch Thread.
I organized the GUI code into three methods so I could focus on one part of the GUI at a time. The JFrame is created in the run method. The title JPanel is created in the createTitlePanel method. The form JPanel is created in the createFormPanel method. The code for the JFrame will rarely change from Swing application to Swing application.
I use Swing components. I don't extend Swing components, or any Java class, unless I intend to override one of the class methods.
The createFormPanel class uses the GridBagLayout to organize the labels and text fields in columns. You can think of the GridBagLayout as a flexible grid. The cells of the grid don't have to be the same size. The Oracle tutorial, How to Use GridBagLayout, has another example.
I put the ActionListener in a separate class. I made it an inner class in this example so I could paste the code as one file. Generally, you should put separate classes in separate files. It makes each class shorter and easier to understand.
Here's the runnable, example code.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class BorrowerGUI implements Runnable {
private static int ID_COUNTER = 19000;
public static void main(String[] args) {
SwingUtilities.invokeLater(new BorrowerGUI());
}
private JButton btnSubmit;
private JTextField txtName;
private JTextField txtProg;
private JTextField txtId;
#Override
public void run() {
JFrame frame = new JFrame("Add Borrower");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createTitlePanel(), BorderLayout.BEFORE_FIRST_LINE);
frame.add(createFormPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createTitlePanel() {
JPanel panel = new JPanel(new FlowLayout());
JLabel lblTitle = new JLabel("Add Borrower");
lblTitle.setFont(new Font("Forte", Font.PLAIN, 40));
lblTitle.setForeground(Color.BLUE);
panel.add(lblTitle);
return panel;
}
private JPanel createFormPanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(5, 5, 5, 5);
gbc.gridx = 0;
gbc.gridy = 0;
JLabel lblName = new JLabel("Name:");
panel.add(lblName, gbc);
gbc.gridx++;
txtName = new JTextField(20);
panel.add(txtName, gbc);
gbc.gridx = 0;
gbc.gridy++;
JLabel lblProg = new JLabel("Program:");
panel.add(lblProg, gbc);
gbc.gridx++;
txtProg = new JTextField(20);
panel.add(txtProg, gbc);
gbc.gridx = 0;
gbc.gridy++;
JLabel lblId = new JLabel("Library ID:");
panel.add(lblId, gbc);
gbc.gridx++;
txtId = new JTextField(20);
txtId.setEditable(false);
panel.add(txtId, gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.gridwidth = 2;
btnSubmit = new JButton("Submit");
btnSubmit.addActionListener(new SubmitListener());
panel.add(btnSubmit, gbc);
return panel;
}
public class SubmitListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent ae) {
Object source = ae.getSource();
if (ae.getActionCommand().equals("Confirm")) {
txtName.setText("");
txtName.requestFocus();
txtProg.setText("");
txtId.setText("");
btnSubmit.setText("Submit");
} else if (source == btnSubmit) {
if (txtName.getText().equals("") &&
txtProg.getText().equals("")) {
txtId.setText("No entry of both");
} else if (txtName.getText().equals("")) {
txtId.setText("No entry of Name");
} else if (txtProg.getText().equals("")) {
txtId.setText("No entry of Program");
} else {
ID_COUNTER++;
txtId.setText("" + ID_COUNTER);
btnSubmit.setText("Confirm");
}
}
}
}
}
Edited to add: If you want the title JLabel to be right-justified, you'll have to switch to a BorderLayout. I added an empty border so the text wouldn't be on the right edge of the JFrame.
Here's the changed method.
private JPanel createTitlePanel(String title) {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
JLabel lblTitle = new JLabel(title);
lblTitle.setFont(new Font("Forte", Font.PLAIN, 40));
lblTitle.setForeground(Color.BLUE);
panel.add(lblTitle, BorderLayout.AFTER_LINE_ENDS);
return panel;
}
I have a JTextArea that is filled with numbers with no duplicates. There is an add and remove button. I have programmed the add button, but I am struggling with programming the remove button. I know how to remove the number from the array, but I'm not sure how to remove the number from the text area.
How do I remove a line from a text area that contains a certain number?
Extra notes:
The only input is integers.
Your question may in fact be an XY Problem where you ask how to fix a specific code problem when the best solution is to use a different approach entirely. Consider using a JList and not a JTextArea. You can easily rig it up to look just like a JTextArea, but with a JList, you can much more easily remove an item such as a line by removing it from its model.
For example:
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class NumberListEg extends JPanel {
private static final int VIS_ROW_COUNT = 10;
private static final int MAX_VALUE = 10000;
private DefaultListModel<Integer> listModel = new DefaultListModel<>();
private JList<Integer> numberList = new JList<>(listModel);
private JSpinner spinner = new JSpinner(new SpinnerNumberModel(0, 0, MAX_VALUE, 1));
private JButton addNumberButton = new JButton(new AddNumberAction());
public NumberListEg() {
JPanel spinnerPanel = new JPanel();
spinnerPanel.add(spinner);
JPanel addNumberPanel = new JPanel();
addNumberPanel.add(addNumberButton);
JPanel removeNumberPanel = new JPanel();
JButton removeNumberButton = new JButton(new RemoveNumberAction());
removeNumberPanel.add(removeNumberButton);
JPanel eastPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
// gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(3, 3, 3, 3);
eastPanel.add(spinner, gbc);
gbc.gridy = GridBagConstraints.RELATIVE;
eastPanel.add(addNumberButton, gbc);
eastPanel.add(removeNumberButton, gbc);
// eastPanel.add(Box.createVerticalGlue(), gbc);
numberList.setVisibleRowCount(VIS_ROW_COUNT);
numberList.setPrototypeCellValue(1234567);
numberList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane listPane = new JScrollPane(numberList);
listPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
setLayout(new BorderLayout());
add(listPane, BorderLayout.CENTER);
add(eastPanel, BorderLayout.LINE_END);
}
private class AddNumberAction extends AbstractAction {
public AddNumberAction() {
super("Add Number");
putValue(MNEMONIC_KEY, KeyEvent.VK_A);
}
#Override
public void actionPerformed(ActionEvent arg0) {
int value = (int) spinner.getValue();
if (!listModel.contains(value)) {
listModel.addElement(value);
}
}
}
private class RemoveNumberAction extends AbstractAction {
public RemoveNumberAction() {
super("Remove Number");
putValue(MNEMONIC_KEY, KeyEvent.VK_R);
}
#Override
public void actionPerformed(ActionEvent e) {
Integer selection = numberList.getSelectedValue();
if (selection != null) {
listModel.removeElement(selection);
}
}
}
private static void createAndShowGui() {
NumberListEg mainPanel = new NumberListEg();
JFrame frame = new JFrame("Gui");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
can not be remove from the array,you can to make index to be empty,for example String a= Integer.toString(type for int),then a.replace("your int","");
Can someone please tell me what's wrong with this code?
I need it to pop up a frame and fill the frame with certain field a namer field and an intake field and also display a button at the bottom of the grid.
Any help would be welcomed, Thanks!!
import java.awt.*;
import javax.swing.*;
public class FrameDemo
//To create the gui and show it.
{
public static void createAndShowGUI()
{
//create and set up the window.
JFrame frame = new JFrame("RungeKutta");
GridLayout first = new GridLayout(1,14);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create, name and Populate TextField
JTextField PL = new JTextField("Pendulum Length", 20);
//Set TextField to Uneditable. Each will have Empty Field Below For Variables
PL.setEditable(false);
//Set Textfield for user entered dat
JTextField PLv = new JTextField();
//Allow handler for user input on Empty Textfield?
JTextField AD = new JTextField("Angular Displacement", 20);
AD.setEditable(false);
JTextField ADv = new JTextField();
JTextField AV = new JTextField("Angular Velocity", 20);
AV.setEditable(false);
JTextField Avv = new JTextField();
JTextField TS= new JTextField("Time Steps", 20);
TS.setEditable(false);
JTextField TSv = new JTextField();
JTextField MT = new JTextField("Max Time", 20);
MT.setEditable(false);
JTextField MTv = new JTextField();
JTextField V = new JTextField("Viscosity (0-1)", 20);
V.setEditable(false);
JTextField Vv = new JTextField();
//Create Button to Restart
JButton BNewGraph = new JButton("Draw New Graph"); //Button to restart entire drawing process
JLabel emptyLabel = new JLabel("");
emptyLabel.setPreferredSize(new Dimension(600,500));
frame.getContentPane().add(PL, first);
frame.getContentPane().add(PLv, first);
frame.getContentPane().add(AD, first);
frame.getContentPane().add(ADv, first);
frame.getContentPane().add(AV, first);
frame.getContentPane().add(Avv, first);
frame.getContentPane().add(TS, first);
frame.getContentPane().add(TSv, first);
frame.getContentPane().add(MT, first);
frame.getContentPane().add(MTv, first);
frame.getContentPane().add(V, first);
frame.getContentPane().add(Vv, first);
frame.getContentPane().add(BNewGraph, first);
//display the window
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
//add job to event scheduler
//create and show GUI
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
This is not how you use GridLayout:
frame.getContentPane().add(PL, first);
Instead you'd set the container's layout using the layout manager:
frame.getContentPane().setLayout(first);
and then add components to the container:
frame.getContentPane().add(PL);
frame.getContentPane().add(PLv);
frame.getContentPane().add(AD);
frame.getContentPane().add(ADv);
frame.getContentPane().add(AV);
frame.getContentPane().add(Avv);
frame.getContentPane().add(TS);
frame.getContentPane().add(TSv);
frame.getContentPane().add(MT);
frame.getContentPane().add(MTv);
// and so on for all the components.
You will want to read the tutorial on how to use GridLayout which you can find here: GridLayout Tutorial.
As an aside, note that this:
frame.getContentPane().add(PL);
can be shortened to this:
frame.add(PL);
Also you will want to study and learn Java naming conventions: class names begin with an upper case letter and all method and variables with lower case letters. Also avoid variable names like pl or plv, or ad or adv, and instead use names that are a little bit longer and have meaning, names that make your code self-commenting. So instead of AD, consider angularDisplacementField for the JTextfield's name.
Myself, I'd use a GridBagLayout and do something like:
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.swing.*;
public class GuiDemo extends JPanel {
// or better -- use an enum for this
public static final String[] FIELD_LABELS = {
"Pendulum Length", "Angular Displacement", "Angular Velocity",
"Time Steps", "Max Time", "Viscocity (0-1)"
};
private static final int TEXT_FIELD_COLUMNS = 10;
private static final int GAP = 3;
private static final Insets RIGHT_GAP_INSETS = new Insets(GAP, GAP, GAP, 3 * GAP);
private static final Insets BALANCED_INSETS = new Insets(GAP, GAP, GAP, GAP);
private Map<String, JTextField> labelFieldMap = new HashMap<>();
public GuiDemo() {
JPanel labelFieldPanel = new JPanel(new GridBagLayout());
int row = 0;
// to make sure that no focusAccelerator is re-used
Set<Character> focusAccelSet = new HashSet<>();
for (String fieldLabelLText : FIELD_LABELS) {
JLabel fieldLabel = new JLabel(fieldLabelLText);
JTextField textField = new JTextField(TEXT_FIELD_COLUMNS);
labelFieldPanel.add(fieldLabel, getGbc(row, 0));
labelFieldPanel.add(textField, getGbc(row, 1));
labelFieldMap.put(fieldLabelLText, textField);
for (char c : fieldLabelLText.toCharArray()) {
if (!focusAccelSet.contains(c)) {
textField.setFocusAccelerator(c);
fieldLabel.setDisplayedMnemonic(c);
focusAccelSet.add(c);
break;
}
}
row++;
}
JButton button = new JButton(new DrawGraphAction("Draw New Graph"));
labelFieldPanel.add(button, getGbc(row, 0, 2, 1));
setLayout(new BorderLayout(GAP, GAP));
add(labelFieldPanel, BorderLayout.CENTER);
}
private class DrawGraphAction extends AbstractAction {
public DrawGraphAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO calculation method
}
}
public static GridBagConstraints getGbc(int row, int column) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = column;
gbc.gridy = row;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
if (column == 0) {
gbc.anchor = GridBagConstraints.LINE_START;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = RIGHT_GAP_INSETS;
} else {
gbc.anchor = GridBagConstraints.LINE_END;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = BALANCED_INSETS;
}
return gbc;
}
public static GridBagConstraints getGbc(int row, int column, int width, int height) {
GridBagConstraints gbc = getGbc(row, column);
gbc.gridwidth = width;
gbc.gridheight = height;
gbc.insets = BALANCED_INSETS;
gbc.fill = GridBagConstraints.BOTH;
return gbc;
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Gui Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new GuiDemo());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}