Swapping between panels - java

I am learning Java creating small projects for fun. I am fairly new to it and easily stuck, hence the question I am asking.
I'm trying to create a simple Shopping Cart program, which in it's main panel has a 3x3 grid consisting of empty labels later
going to be replaced with images. And to the right of the grid there is four buttons, Add a Meal, Add a Drink, Total Price
and Clear All. So when either of the first two buttons are clicked, I want it to change the current panel to the panels corresponding to the button that was clicked.
The panel that is displayed then has data, like type of the food in a combobox which displays set food and quantity of the food.
Which then when the user chooses the type and quantity, presses the Add button, that would then change the panel
back to the main panel and the first empty label now has an image of the item that has been added to the cart.
This is all I currently know and as far as I can get.
Main class
public class ShoppingCart
{
public ShoppingCart()
{
JFrame app = new JFrame("Cart");
MainPanel main = new MainPanel();
app.add(main);
app.pack();
app.setResizable(false);
app.setLocationRelativeTo(null);
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.setVisible(true);
}
public static void main(String[] args)
{
new ShoppingCart();
}
}
MainPanel class
public class MainPanel extends JPanel implements ActionListener
{
private final JLabel labels[] = new JLabel[9];
private final JButton button[] = new JButton[4];
public MainPanel()
{
String buttonText[] ={"Add a Meal", "Add a Drink", "Total Price", "Clear All"};
String buttonToolTipText[] =
{"This will add food", "This will add drink", "This will display the price", "Clear the cart"};
this.setLayout(new BorderLayout());
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(4, 1, 2, 2));
for (int i = 0; i < 4; i++)
{
button[i] = new JButton(buttonText[i]);
button[i].setOpaque(true);
button[i].setBackground(Color.WHITE);
button[i].setFont(new Font("Ariel", Font.PLAIN, 18));
button[i].setPreferredSize(new Dimension(150,50));
button[i].setVisible(true);
button[i].setToolTipText(buttonToolTipText[i]);
button[i].addActionListener(this);
buttonPanel.add(button[i]);
}
JPanel labelPanel = new JPanel(new GridLayout(3, 3, 2, 2));
Border border = BorderFactory.createLineBorder(Color.GRAY);
for (int i = 0; i < 9; i++)
{
labels[i] = new JLabel();
labels[i].setOpaque(true);
labels[i].setVisible(true);
labels[i].setPreferredSize(new Dimension(100, 100));
labels[i].setBorder(border);
labels[i].setBackground(Color.WHITE);
labelPanel.add(labels[i]);
//set empty label to the image of the type chose,
//if right clicked, show type and quantity chosen
}
add(labelPanel, BorderLayout.WEST);
add(buttonPanel, BorderLayout.EAST);
}
#Override
public void actionPerformed(ActionEvent e)
{
if(button[0] == e.getSource())
{
//Change panel to Meal panel
}
if(button[1] == e.getSource())
{
//Change panel to Drink panel
}
if(button[2] == e.getSource())
{
//JOptionPane to show total price
}
if(button[3] == e.getSource())
{
//Check whether labels are empty, if not clear them else display message
}
}
}
MealPanel class
public class MealPanel extends JPanel implements ActionListener
{
public MealPanel()
{
this.setLayout(new BorderLayout());
JPanel titlePanel = new JPanel();
JPanel labelPanel = new JPanel(new GridLayout(2, 1, 3, 3));
JPanel inputField = new JPanel(new GridLayout(2, 1, 3, 3));
JPanel addCancel = new JPanel();
JLabel title = new JLabel("Add a Meal");
title.setBorder(BorderFactory.createMatteBorder(5,0,10,0, new Color(0,0,0,0)));
titlePanel.add(title);
JLabel type = new JLabel("Type:", JLabel.RIGHT);
labelPanel.add(type);
JLabel quantity = new JLabel("Quantity:", JLabel.RIGHT);
labelPanel.add(quantity);
final String arr[] = {"Burger", "Pizza"};
JComboBox mealType = new JComboBox(arr);
inputField.add(mealType);
JTextField quant = new JTextField();
inputField.add(quant);
JButton add = new JButton("Add");
add.addActionListener(this);
addCancel.add(add);
JButton cancel = new JButton("Cancel");
cancel.addActionListener(this);
addCancel.add(cancel);
add(titlePanel, BorderLayout.NORTH);
add(labelPanel, BorderLayout.WEST);
add(inputField, BorderLayout.EAST);
add(addCancel, BorderLayout.SOUTH);
}
#Override
public void actionPerformed(ActionEvent e)
{
//If cancel is pressed, return back to main, nothing changed on this panel
//else if add is pressed, set the type and quantity and return back to main
}
}
I guess what is shown, is I don't know how to specifically change the current panel to the panel chosen via which button is clicked. Then when the panel is shown, how to set the data then change the panel back to the MainPanel to then have that type of food displayed in the label as an image within the grid corresponding to the type that was chosen, so either a burger or pizza in the first empty label.
How would one go about doing the application?

Related

Cant add to arraylist inside actionevent Buttonclicked

Im kind of new to programming in java but here im trying to figure out how to add the value of a button clicked in ActionEvent. I even changed the actionlistener to MouseListener etc but still not working. It only displays the current button clicked but i would like to add every button clicked into an arraylist.
Problem: I cant add the value of buttons clicked into an arraylist.
Example: if i click on the button named E then i want E to be added to arraylist, after that if i click on the button S then it should add S o the same arraylist.
but its not adding aything to the arraylist. it only displays the current button clicked
public class WordFinder extends JFrame implements ActionListener {
private JButton buttons[];
ArrayList<String> LettersClicked = new ArrayList<String>();
private JTextArea jta;
private JLabel jLabel;
public WordFinder(){
int numberOfLetters = 64;
buttons = new JButton[numberOfLetters];
JFrame frame = new JFrame("wordfinder");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.red);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
JPanel topPanel = new JPanel();
topPanel.setBorder(BorderFactory.createLineBorder(Color.GREEN));
topPanel.setPreferredSize(new Dimension(600, 600));
topPanel.setMaximumSize(new Dimension(600, 600));
topPanel.setBackground(Color.red);
JPanel bottomPanel = new JPanel();
bottomPanel.setBorder(BorderFactory.createLineBorder(Color.yellow));
bottomPanel.setPreferredSize(new Dimension(600, 300));
bottomPanel.setMaximumSize(new Dimension(600, 300));
bottomPanel.setBackground(Color.green);
Font f3 = new Font(Font.DIALOG, Font.BOLD, 35);
for (int i = 0;i<numberOfLetters;i++) {
char letter = alphabet();
buttons[i] = new JButton(String.valueOf(letter));
buttons[i].setFont(f3);
// buttons[i].setMinimumSize(new Dimension(40, 20));
buttons[i].setPreferredSize(new Dimension(65, 65));
buttons[i].setMargin(new Insets(0,0,0,0));
buttons[i].setBackground(Color.white);
buttons[i].setFocusPainted(false);
buttons[i].addActionListener(this);
topPanel.add(buttons[i]);
}
String buttValue = "";
jLabel = new JLabel(""+buttValue);
jLabel.setFont(f3);
bottomPanel.add(jLabel);
LettersClicked.add(jLabel.toString());
for (int z = 0; z<LettersClicked.size(); z++){
JLabel aa = new JLabel(""+LettersClicked.size());
bottomPanel.add(aa);
}
mainPanel.add(topPanel);
mainPanel.add(bottomPanel);
frame.getContentPane().add(mainPanel);
frame.setSize(1000,1000);
frame.setMinimumSize(new Dimension(1000, 1000));
frame.setVisible(true);
}
public char alphabet(){
Random rnd = new Random();
String alphabets = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char letter = alphabets.charAt(rnd.nextInt(alphabets.length()));
return letter;
}
#Override
public void actionPerformed(ActionEvent actionEvent) {
JButton button = (JButton) actionEvent.getSource();
jLabel.setText(button.getText());
LettersClicked.add(button.getText());
}
}
I think you are confused about the content of the JLabel displayed on the GUI and your ArrayList. The issue is actually in the former.
Your current implementation replaces the text of the JLabel instead of appending it for each pressed button.
So, in your actionPerformed() method, change this line
jLabel.setText(button.getText());
to
jLabel.setText(jLabel.getText() + button.getText());

How do you choose a specific card in Java CardLayout?

I am using a card layout as a refreshing element on a JFrame and want to switch to a specific card after the user selects a button. Is there a way to call a specific card in the CardLayout on an action event?
public class ComboBoxTest() extends JFrame implements ActionListener {
JPanel comboBoxPane = new JPanel(); //use FlowLayout
JButton cb = new JButton("next");
cb.setActionCommand(next);
cb.addActionListener(this);
cb.setText("Forward");
this.add(cb);
comboBoxPane.add(cb);
JButton cb2 = new JButton("next");
cb2.setActionCommand(previous);
cb2.addActionListener(this);
cb2.setText("Back");
this.add(cb2);
comboBoxPane.add(cb2);
//Create the "cards".
card1 = new JPanel();
card1.add(HomeGui.getBody());
card2 = new JPanel();
card2.add(HomeGui.getSecondCard());
card3 = new JPanel();
card3.add(Start.getbody());
//Create the panel that contains the "cards".
cards = new JPanel(new CardLayout());
cards.add(card1, next);
cards.add(card2, previous);
Container base = getContentPane();
pane.add(header, BorderLayout.BEFORE_FIRST_LINE);
pane.add(comboBoxPane, BorderLayout.AFTER_LAST_LINE);
pane.add(cards);
}
public void actionPerformed(ActionEvent e) {
CardLayout c1 = (CardLayout)(cards.getLayout());
String button = e.getActionCommand();
if(button.equals(next)) {
c1.last(cards);
}
if(button.equals(previous)) {
c1.first(cards);
}
if(button.equals(card3)) {
//calls the third, specified card
}
}
}
You have to use show method of the CardLayout object

Java GUI - Possible to store JPanels inside a single main JPanel?

I am working on a semester project that I have and I was wondering if it was possible to store 3-4 JPanels instead one single "main" JPanel. The reason for me asking this is because I a trying to make a GUI checkbook program and my checkbook has 7 buttons that should open a new window once I click on it. To switch between each window I'm going to have to use the CardLayout, but my understand of the CardLayout is that I can only assign one single JPanel to that card so I can't assign multiple JPanels to a single Card layout so when the user clicks on a different card 3-4 different JPanels appear.
The reason that I am asking this is because I asked for help earlier and received help for creating my first window in this project, it produces the output I want PERFECTLY, but uses more than 1 JPanel in doing so. Since this prevents me from continuing on to the other steps of my 7 GUI Windows, I am stuck.
Here is the code:
import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class checkbook extends JPanel implements ActionListener {
private static final String title = "Use The Buttons Below To Manage Transactions";
private static final String[] bottomButtons = { "Create a New Account",
"Load a Trans from a File", "Add New Transactions",
"Search Transactions", "Sort Transactions",
"View/Delete Transactions", "Backup Transaction", "Exit" };
static JButton Button[] = new JButton[8];
static ActionListener AL = new checkbook();
public checkbook() {
JLabel titleLabel = new JLabel(title, SwingConstants.CENTER);
titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, 18));
JPanel titlePanel = new JPanel();
titlePanel.add(titleLabel); // put it in a JPanel so it will expand to fill BoxLayout
JTextField textfield = new JTextField();
JPanel accountBalancePanel = new JPanel();
accountBalancePanel.add(new JLabel("Account Name:"));
accountBalancePanel.add(new JTextField(10));
accountBalancePanel.add(Box.createHorizontalStrut(4));
accountBalancePanel.add(new JLabel("Balance:"));
textfield = new JTextField("0.0", 10);
textfield.setHorizontalAlignment(JTextField.RIGHT);
accountBalancePanel.add(textfield);
JPanel northPanel = new JPanel();
northPanel.setLayout(new BoxLayout(northPanel, BoxLayout.PAGE_AXIS));
northPanel.add(titlePanel);
northPanel.add(accountBalancePanel);
JPanel southBtnPanel = new JPanel(new GridLayout(2, 4, 1, 1));
for(int i = 0; i < 8; i++){
Button[i] = new JButton(bottomButtons[i]);
southBtnPanel.add(Button[i]);
Button[i].addActionListener(AL);
}
setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
setLayout(new BorderLayout());
add(northPanel, BorderLayout.NORTH);
add(Box.createRigidArea(new Dimension(100, 100))); // just an empty placeholder
add(southBtnPanel, BorderLayout.SOUTH);
}
private static void createAndShowGui() {
checkbook mainPanel = new checkbook();
JFrame frame = new JFrame("Checkbook");
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();
}
});
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == Button[7]) {
System.exit(0);
}
}
}
Credit goes to Hovercraft Full Of Eels for showing me the above example
If there is anything that is unclear about my question, please ask and I will do the best I can to fix it.
Here is what the code produces:
http://i.stack.imgur.com/WY0c3.png

Changing background color of a ContentPane

I'm working on a GUI and I'm not having some trouble with panes.
My GUI is divided into two parts (topPane and bottomPane).
I have buttons and labels on both panes, but one of the button functions I wanted to change the background color, but it's not doing the job.
What I did is that I used a Container (called thisContentPane) to change the background color of my entire GUI.
Here is my current code:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class TempConverter extends JFrame
{
//Creating a contentPane down inside the inner class
Container thisContentPane;
//class scope variables : DO NOT CREATE THIS OBJECTS HERE.
JButton calculateButton, clearButton;
JTextField celsiusField, fahrenheitField, kelvinField;
//menu
JMenuBar menuBar = new JMenuBar();
JMenu backgroundColor = new JMenu("Background Color");
JMenu help = new JMenu("Help");
JMenuItem lightGray, white, black, blue, howToUse, about;
//constructor
TempConverter()
{
super("Temperature Converter App");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new BorderLayout());
this.setSize(400,200);;
this.setLocationRelativeTo(null);
//menuBar
this.setJMenuBar(menuBar);
menuBar.add(backgroundColor);
//adding JMenu to JMenuBar
menuBar.add(backgroundColor);
menuBar.add(help);
//adding JMenuItems
lightGray = backgroundColor.add("LIGHTGRAY");
white = backgroundColor.add("WHITE");
black = backgroundColor.add("BLACK");
blue = backgroundColor.add("BLUE");
howToUse = help.add("How To Use");
about = help.add("Help");
//babysitter
MaryPoppins babysitter = new MaryPoppins();
//adding action listener to the menu item
lightGray.addActionListener(babysitter);
white.addActionListener(babysitter);
black.addActionListener(babysitter);
blue.addActionListener(babysitter);
howToUse.addActionListener(babysitter);
about.addActionListener(babysitter);
//building JPanels
JPanel topPanel = new JPanel();
topPanel.setLayout(new GridLayout(3,2,0,20));
//add this to JFrame in centerzone
this.add(topPanel, BorderLayout.CENTER);
//bottom panel
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new FlowLayout());
//add this to JFrame in bottom
this.add(bottomPanel, BorderLayout.SOUTH);
//add components to the panels
//add the buttons
calculateButton = new JButton("Calculate");
clearButton = new JButton("Clear");
//add buttons
bottomPanel.add(calculateButton);
bottomPanel.add(clearButton);
//register listeners
calculateButton.addActionListener(babysitter);
clearButton.addActionListener(babysitter);
//add components to the top panel
JLabel labelOne = new JLabel("Celsius:");
JLabel secondOne = new JLabel("Fahrenheit:");
JLabel thirdOne = new JLabel("Kelvin:");
celsiusField = new JTextField("");
fahrenheitField = new JTextField("");
kelvinField = new JTextField("");
//add the label and text fields
topPanel.add(labelOne);
topPanel.add(celsiusField);
topPanel.add(secondOne);
topPanel.add(fahrenheitField);
topPanel.add(thirdOne);
topPanel.add(kelvinField);
this.setVisible(true);
} // end constructor
public static void main (String[] args) {
new TempConverter();
}
private class MaryPoppins implements ActionListener
{
//implement the abstract method from the interface
public void actionPerformed(ActionEvent ev)
{
thisContentPane = getContentPane();
if(ev.getActionCommand().equals("LIGHTGRAY"))
{
thisContentPane.setBackground(Color.lightGray);
}
else if (ev.getActionCommand().equals("BLUE"))
{
thisContentPane.setBackground(Color.BLUE);
}
else if(ev.getActionCommand().equals("WHITE") )
{
thisContentPane.setBackground(Color.WHITE);
}
else if (ev.getActionCommand().equals("BLACK"))
{
thisContentPane.setBackground(Color.BLACK);
}else if (ev.getActionCommand().equals("Clear"))
{
thisContentPane.setBackground(Color.BLACK);
}
else if (ev.getActionCommand().equals("BLACK"))
{
thisContentPane.setBackground(Color.BLACK);
}
}//end ActionPerformed()
}//end inner class
} // end class
When I click the buttons or menu items it doesn't do anything.
Your problem is that your contentPanel's background color is not "visible": your topPanel and your bottomPanel are on top of it :)
You should either do:
if (ev.getActionCommand().equals("LIGHTGRAY")) {
thisTopPanel.setBackground(Color.lightGray);
thisBottemPanel.setBackground(Color.lightGray);
}
... and do it for each of your if conditions (you know what I mean).
But that's not really the best way to go. An alternative that, in my opinion, makes perfect sense 'cause it reflects the exact behaviour you're looking for, would be:
topPanel.setOpaque(false);
bottomPanel.setOpaque(false);
I would obviously recommend the second option ;)
Also, since I'm at it, I prefer to use Color.LIGHTGRAY (and Color.BLACK, Color.WHITE, etc.) instead of Color.lightGrey, because these aliases respect the convention that states that constants must be upper-case.

Creating Java dialogs

What would be the easiest way for creating a dialog:
in one window I'm giving data for envelope addressing, also set font type from list of sizes
when clicked OK, in the same window or in next window I get preview of how the envelope would look like with the given names, and used selected font size
It should look similarly to:
alt text http://img15.imageshack.us/img15/7355/lab10aa.gif
Should I use Jdialog? Or will JOptionPane will be enough? The next step will be to choose color of font and background so I must keep that in mind.
This should get you going.
class TestDialog extends JDialog {
private JButton okButton = new JButton(new AbstractAction("ok") {
public void actionPerformed(ActionEvent e) {
System.err.println("User clicked ok");
// SHOW THE PREVIEW...
setVisible(false);
}
});
private JButton cancelButton = new JButton(new AbstractAction("cancel") {
public void actionPerformed(ActionEvent e) {
System.err.println("User clicked cancel");
setVisible(false);
}
});
private JTextField nameField = new JTextField(20);
private JTextField surnameField = new JTextField();
private JTextField addr1Field = new JTextField();
private JTextField addr2Field = new JTextField();
private JComboBox sizes = new JComboBox(new String[] { "small", "large" });
public TestDialog(JFrame frame, boolean modal, String myMessage) {
super(frame, "Envelope addressing", modal);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
getContentPane().add(mainPanel);
JPanel addrPanel = new JPanel(new GridLayout(0, 1));
addrPanel.setBorder(BorderFactory.createTitledBorder("Receiver"));
addrPanel.add(new JLabel("Name"));
addrPanel.add(nameField);
addrPanel.add(new JLabel("Surname"));
addrPanel.add(surnameField);
addrPanel.add(new JLabel("Address 1"));
addrPanel.add(addr1Field);
addrPanel.add(new JLabel("Address 2"));
addrPanel.add(addr2Field);
mainPanel.add(addrPanel);
mainPanel.add(new JLabel(" "));
mainPanel.add(sizes);
JPanel buttons = new JPanel(new FlowLayout());
buttons.add(okButton);
buttons.add(cancelButton);
mainPanel.add(buttons);
pack();
setLocationRelativeTo(frame);
setVisible(true);
}
public String getAddr1() {
return addr1Field.getText();
}
// ...
}
Result:
If you need to use JOptionPane :
import java.awt.*;
import javax.swing.*;
public class Main extends JFrame {
private static JTextField nameField = new JTextField(20);
private static JTextField surnameField = new JTextField();
private static JTextField addr1Field = new JTextField();
private static JTextField addr2Field = new JTextField();
private static JComboBox sizes = new JComboBox(new String[] { "small", "medium", "large", "extra-large" });
public Main(){
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
getContentPane().add(mainPanel);
JPanel addrPanel = new JPanel(new GridLayout(0, 1));
addrPanel.setBorder(BorderFactory.createTitledBorder("Receiver"));
addrPanel.add(new JLabel("Name"));
addrPanel.add(nameField);
addrPanel.add(new JLabel("Surname"));
addrPanel.add(surnameField);
addrPanel.add(new JLabel("Address 1"));
addrPanel.add(addr1Field);
addrPanel.add(new JLabel("Address 2"));
addrPanel.add(addr2Field);
mainPanel.add(addrPanel);
mainPanel.add(new JLabel(" "));
mainPanel.add(sizes);
String[] buttons = { "OK", "Cancel"};
int c = JOptionPane.showOptionDialog(
null,
mainPanel,
"My Panel",
JOptionPane.DEFAULT_OPTION,
JOptionPane.PLAIN_MESSAGE,
null,
buttons,
buttons[0]
);
if(c ==0){
new Envelope(nameField.getText(), surnameField.getText(), addr1Field.getText()
, addr2Field.getText(), sizes.getSelectedIndex());
}
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(String[] args) {
new Main();
}
}
You will need to use JDialog. No point messing about with JOptoinPane - it's not meant for gathering more than a simple string. Additionally, use either MigLayout, TableLayout, or JGoodies forms - it will help you get a nice layout that's easy to code.
If it is allowed to use a GUI builder I would recommend you IntelliJ IDEA's
You can create something like that in about 5 - 10 mins.
If that's not possible ( maybe you want to practice-learn-or-something-else ) I would use a JFrame instead ) with CardLayout
Shouldn't be that hard to do.
You can use JOptionPane. You can add any Swing component to it.
Create a panel with all the components you need except for the buttons and then add the panel to the option pane. The only problem with this approach is that focus will be on the buttons by default. To solve this problem see the solution presented by Dialog Focus.

Categories

Resources