I am currently trying to make a little app using a jframe that has multiple jpanels. I have a couple questions about this.
There has to be a cleaner way of making an app with 16 different panels than having it all inside one class. What are some other options.
Currently I only have 3 panels. I haven't gone any further because 2 of the panels aren't reflecting my changes. They are the two panels I call using
removeAll();
add();
revalidate();
repaint();
What would be causing the other panels I am calling to be blank?
Here is a look at what I have, any advice would be great. Thanks
public class Jframetest extends JFrame {
private JPanel Home;
private JPanel masslog;
private JPanel DEH;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Jframetest frame = new Jframetest();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Jframetest() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setBounds(100, 100, 618, 373);
Home = new JPanel();
masslog = new JPanel();
DEH = new JPanel();
Home.setBackground(new Color(255, 250, 250));
Home.setBorder(new LineBorder(Color.DARK_GRAY, 1, true));
DEH.setBackground(new Color(255, 250, 250));
DEH.setBorder(new LineBorder(Color.DARK_GRAY, 1, true));
masslog.setBackground(new Color(255, 250, 250));
masslog.setBorder(new LineBorder(Color.DARK_GRAY, 1, true));
setContentPane(Home);
Home.setLayout(null);
JButton dehbutton = new JButton("Sign in");
dehbutton.setFont(new Font("Tahoma", Font.PLAIN, 14));
dehbutton.setForeground(new Color(0, 0, 0));
dehbutton.setBackground(UIManager.getColor("Menu.selectionBackground"));
DEH.add(dehbutton);
JButton btnNewButton = new JButton("Data Entry login");
btnNewButton.setFont(new Font("Tahoma", Font.PLAIN, 14));
btnNewButton.setForeground(new Color(0, 0, 0));
btnNewButton.setBackground(UIManager.getColor("Menu.selectionBackground"));
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Home.removeAll();
Home.add(DEH);
Home.revalidate();
Home.repaint();
// JOptionPane.showMessageDialog(null, "Username/Password incorrect");
}
});
btnNewButton.setBounds(44, 214, 204, 61);
Home.add(btnNewButton);
final JButton button = new JButton("Manager and Associate login");
button.setFont(new Font("Tahoma", Font.PLAIN, 14));
button.setBackground(UIManager.getColor("EditorPane.selectionBackground"));
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Home.removeAll();
Home.add(masslog);
Home.revalidate();
Home.repaint();
}
});
button.setBounds(340, 214, 204, 61);
Home.add(button);
JTextPane txtpnEmployeeLogin = new JTextPane();
txtpnEmployeeLogin.setForeground(Color.DARK_GRAY);
txtpnEmployeeLogin.setBackground(Color.WHITE);
txtpnEmployeeLogin.setFont(new Font("Tahoma", Font.PLAIN, 34));
txtpnEmployeeLogin.setText("Employee Login");
txtpnEmployeeLogin.setBounds(181, 123, 260, 52);
Home.add(txtpnEmployeeLogin);
JLabel lblNewLabel = new JLabel("New label");
lblNewLabel.setIcon(new ImageIcon("C:\\Users\\Will and April\\Downloads\\your-logo-here.jpg"));
lblNewLabel.setBounds(427, 11, 165, 67);
Home.add(lblNewLabel);
}
}
Your mistake is using a null layout, revalidate, invalidate and validate will no longer have any significant meaning, because they are related to supporting the layout management API.
Because you've removed the layout manager, you panels no longer have anything to tell them what size or location that they should appear at, meaning when you add a new component, it has a size of 0x0 and position of 0x0
Update with example
There are many reasons why you should take advantage of the layout manager API, including automatic handling of differences between how fonts are rendered on different systems, dynamic and resizable layouts, differences in screen resolution and DPI to name a few.
It will also encourage you to separate your UI into areas of responsibility instead of trying to dump your entire UI code into a single class (yes, I've seen this done, yes, I've spent most of my career cleaning up after people who do this...)
This example makes use of CardLayout and GridBagLayout, but you should take the time to become farmiluar with the some of the others avaiable in the default JDK
import java.awt.CardLayout;
import java.awt.EventQueue;
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.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
public class FrameTest extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
FrameTest frame = new FrameTest();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public FrameTest() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final CardLayout layout = new CardLayout();
setLayout(layout);
LoginPane loginPane = new LoginPane();
add(loginPane, "login");
add(new NewLoginPane(), "newLogin");
add(new ManagerLoginPane(), "managerLogin");
loginPane.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
System.out.println(command);
if ("new".equals(command)) {
layout.show(getContentPane(), "newLogin");
} else if ("manager".equals(command)) {
layout.show(getContentPane(), "managerLogin");
}
}
});
layout.show(getContentPane(), "layout");
pack();
setLocationRelativeTo(null);
}
public class LoginPane extends JPanel {
private JTextField userName;
private JButton newButton;
private JButton managerButton;
public LoginPane() {
setBorder(new EmptyBorder(20, 20, 20, 20));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.weightx = 1;
gbc.insets = new Insets(10, 10, 10, 10);
userName = new JTextField(10);
userName.setFont(new Font("Tahoma", Font.PLAIN, 34));
add(userName, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.weightx = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
newButton = new JButton("Sign in");
newButton.setActionCommand("new");
managerButton = new JButton("Manager and Associate login");
managerButton.setActionCommand("manager");
add(newButton, gbc);
gbc.gridx++;
add(managerButton, gbc);
}
public void addActionListener(ActionListener listener) {
newButton.addActionListener(listener);
managerButton.addActionListener(listener);
}
public void remveActionListener(ActionListener listener) {
newButton.removeActionListener(listener);
managerButton.removeActionListener(listener);
}
public String getUserName() {
return userName.getText();
}
}
public class NewLoginPane extends JPanel {
public NewLoginPane() {
setLayout(new GridBagLayout());
add(new JLabel("New Login"));
}
}
public class ManagerLoginPane extends JPanel {
public ManagerLoginPane() {
setLayout(new GridBagLayout());
add(new JLabel("Welcome overlord"));
}
}
}
There has to be a cleaner way of making an app with 16 different panels than having it all inside one class. What are some other options.
You are free to create and use as many classes as need be. So if a JPanel holds a complex bit of GUI that you may wish to re-use elsewhere, or that has its own specific and separate functionality, by all means put the code in its own class.
Currently I only have 3 panels. I haven't gone any further because 2 of the panels aren't reflecting my changes. They are the two panels I call using
removeAll();
add();
revalidate();
repaint();
Smells like you're trying to re-invent the CardLayout. Why re-invent it when you can just use it?
And yes, everything MadProgrammer says about null layout is true. You should avoid using it.
Oh, the CardLayout may work for you. I thought about using a JTabbedPane. Here are my thoughts in a code example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
public class TabbedPaneDemo extends JFrame {
public TabbedPaneDemo() {
// set the layout of the frame to all the addition of all components
setLayout(new FlowLayout());
// create a tabbed pane
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.setPreferredSize(new Dimension(500,500));
add(tabbedPane);
// create three panels to be added to this frame
JPanel redPanel = new JPanel();
JPanel greenPanel = new JPanel();
JPanel bluePanel = new JPanel();
// set the colors of the panels
redPanel.setBackground(Color.RED);
greenPanel.setBackground(Color.GREEN);
bluePanel.setBackground(Color.BLUE);
// set the preferred size of each panel
redPanel.setPreferredSize(new Dimension(150,150));
greenPanel.setPreferredSize(new Dimension(150,150));
bluePanel.setPreferredSize(new Dimension(150,150));
// add the panels to the tabbed pane
tabbedPane.addTab("Red Panel", redPanel);
tabbedPane.addTab("Green Panel", greenPanel);
tabbedPane.addTab("Blue Panel", bluePanel);
// finish initializing this window
setSize(500,500); // size the window to fit its components (i.e. panels in this case)
setLocationRelativeTo(null); // center this window
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // exit application when this window is closed
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TabbedPaneDemo().setVisible(true);
}
});
}
}
And for your other question about having 16 panels in one class:
You can have panels within panel to organize things.
You can subclass JPanel and put the subclasses in their own .java files.
You can send me an email if I can be of further assistance. kaydell#yahoo.com (I like helping people with their programming and I learn from it too.)
Related
i was following a tutorial on youtube to learn java guis ands i was making a login screen.
i was testing the login button by making it print works in console w but i presses. i followed the whole tutoral properly and tried every way. the code is spamming widows shown in the video.
link to video : https://hriday.tk/2022-01-09%2019-56-32.mkv
the code :
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Login implements ActionListener{
public Login() {
JPanel panel = new JPanel();
JFrame frame = new JFrame();
JLabel Ulabel = new JLabel("UserName");
JLabel Plabel = new JLabel("PassWord");
JTextField Utext = new JTextField(20);
JPasswordField Ptext = new JPasswordField(20);
JButton login = new JButton("Login");
JLabel success = new JLabel("");
panel.setLayout(null);
panel.add(Ulabel);
panel.add(Utext);
panel.add(Plabel);
panel.add(Ptext);
panel.add(login);
panel.add(success);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(350, 150);
frame.setTitle("Login");
frame.add(panel);
Ulabel.setBounds(10, 10, 80, 25);
Utext.setBounds(100, 10, 165, 25);
Plabel.setBounds(10, 40, 80, 25);
Ptext.setBounds(100, 40, 165, 25);
login.setBounds(50, 70, 100, 25);
success.setBounds(200, 70, 100, 25);
login.addActionListener(new Login());
}
public static void main(String[] args){ new Login(); }
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("works");
}
} ```
This is causing your problems:
// imports
public class Login implements ActionListener {
public Login() {
// .... code removed
login.addActionListener(new Login()); // **** here ****
}
// .....
}
You're calling this in the Login constructor and so are creating new Login objects recursively, meaning, each time the Login constructor is called, it creates a new Login object, which calls the constructor, which creates a new Login object, which.... well, you should get the point.
Instead, change it to this:
login.addActionListener(this);
Here you add the already created Login object, the this object, and add it to the ActionListener.
Caveat:
Having said this, I would be remiss if I didn't mention that using null layouts and setBounds(...) is not healthy as this makes for very inflexible GUI's that while they might look good on one platform look terrible on most other platforms or screen resolutions and that are very difficult to update and maintain. Instead, you will want to study and learn the layout managers and then nest JPanels, each using its own layout manager to create pleasing and complex GUI's that look good on all OS's.
For that reason you're far better off learning about and using the layout managers. You can find the layout manager tutorial here: Layout Manager Tutorial, and you can find links to the Swing tutorials and to other Swing resources here: Swing Info.
... and if this is from a tutorial and it recommends use of null layouts, then ditch the tutorial!
For example (using GridBagLayout):
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import javax.swing.*;
public class Login2 {
private static final int GAP = 5;
private JPanel mainPanel = new JPanel();
private JTextField userNameField = new JTextField(20);
private JPasswordField passwordField = new JPasswordField(20);
private JButton loginButton = new JButton("Login");
private JLabel successLabel = new JLabel(" ");
public Login2() {
mainPanel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
mainPanel.setLayout(new GridBagLayout());
mainPanel.add(new JLabel("UserName:"), createGBC(0, 0));
mainPanel.add(userNameField, createGBC(1, 0));
mainPanel.add(new JLabel("Password:"), createGBC(0, 1));
mainPanel.add(passwordField, createGBC(1, 1));
mainPanel.add(loginButton, createGBC(0, 2));
mainPanel.add(successLabel, createGBC(1, 2));
loginButton.addActionListener(e -> {
successLabel.setText("Success");
Window window = SwingUtilities.getWindowAncestor(mainPanel);
window.dispose();
});
}
public String getUserName() {
return userNameField.getText();
}
public char[] getPassword() {
return passwordField.getPassword();
}
// create constraints that help position components in the GridBagLayout-using container
private GridBagConstraints createGBC(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.insets = new Insets(GAP, GAP, GAP, GAP);
return gbc;
}
public JPanel getMainPanel() {
return mainPanel;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
Login2 login2 = new Login2();
JDialog dialog = new JDialog(null, "Login", ModalityType.APPLICATION_MODAL);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.add(login2.getMainPanel());
dialog.pack();
dialog.setLocationByPlatform(true);
dialog.setVisible(true);
System.out.println("User Name: " + login2.getUserName());
System.out.println("Password: " + new String(login2.getPassword()));
});
}
}
This question already has answers here:
Implementing back/forward buttons in Swing
(3 answers)
Closed 8 years ago.
I want to know how do you go to another panel by pressing a button.
The codes for my main GUI is below:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
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.border.LineBorder;
public class MainMenu extends JFrame {
private JPanel contentPane, confirmPage_Panel;
private JTextField NumberofSoups_TEXTFIELD;
private JTextField NumberofSandwiches_TEXTFIELD;
private JTextField totalCost_TEXTFIELD;
private JTextField OrderNumber_TEXTFIELD;
private int Soupclicks = 0;
private int Sandwichclicks = 0;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainMenu frame = new MainMenu();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public MainMenu() {
super("Welcome Yo!");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 1268, 716);
contentPane = new JPanel();
contentPane.setBackground(Color.DARK_GRAY);
contentPane.setBorder(new LineBorder(new Color(255, 200, 0), 4, true));
setContentPane(contentPane);
contentPane.setLayout(null);
JPanel Header_Panel = new JPanel();
Header_Panel.setBackground(Color.DARK_GRAY);
Header_Panel.setBounds(145, 11, 977, 35);
contentPane.add(Header_Panel);
JLabel Header_Label = new JLabel("Super Sandwich Store");
Header_Label.setForeground(Color.PINK);
Header_Label.setFont(new Font("Tahoma", Font.PLAIN, 22));
Header_Panel.add(Header_Label);
JPanel Soup_Panel = new JPanel();
Soup_Panel.setBackground(Color.PINK);
Soup_Panel.setBounds(10, 71, 459, 339);
contentPane.add(Soup_Panel);
Soup_Panel.setLayout(null);
JButton Confirm_Button = new JButton("Confirm Now");
Confirm_Button.setFont(new Font("Tahoma", Font.PLAIN, 14));
Confirm_Button.setBounds(511, 558, 121, 23);
contentPane.add(Confirm_Button);
JButton Exit_Button = new JButton("Exit");
Exit_Button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
System.exit(0);
}
});
Exit_Button.setFont(new Font("Tahoma", Font.PLAIN, 13));
Exit_Button.setBounds(641, 558, 111, 23);
contentPane.add(Exit_Button);
}// end of MainMenu()
}
And when i clicked the confirm button it will invoke this page :
public class ConfirmationGUI extends JFrame {
private JPanel contentPane;
private JTextField ConfirmedOrder_Field;
private JTextField totalCost_Field;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ConfirmationGUI frame = new ConfirmationGUI();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public ConfirmationGUI() {
super("Confirmation Yo!");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 668, 457);
contentPane = new JPanel();
contentPane.setBackground(Color.DARK_GRAY);
contentPane.setBorder(new LineBorder(Color.ORANGE, 4, true));
setContentPane(contentPane);
contentPane.setLayout(null);
JPanel Top_Panel = new JPanel();
Top_Panel.setBackground(Color.DARK_GRAY);
Top_Panel.setBounds(5, 5, 637, 93);
contentPane.add(Top_Panel);
Top_Panel.setLayout(null);
JLabel lblNewLabel = new JLabel("Super Sandwich Store");
lblNewLabel.setForeground(Color.PINK);
lblNewLabel.setBounds(245, 11, 185, 45);
Top_Panel.add(lblNewLabel);
lblNewLabel.setFont(new Font("Tahoma", Font.PLAIN, 18));
}
}
It would be much of a help,
Thank you :)
To switch between JFrames, call setVisible(true) for the JFrame you want to reveal and setVisible(false) for the one you want to hide. CardLayout doesn't apply here.
Suggestions: read the Swing tutorial on layouts, don't use null layouts with absolutely positioning, and familiarize yourself with the differences between ordinary containers and top-level containers.
This class generates a window or frame(Im not too sure what the proper title would be) that has a back button and a ship select button on the left side. I would like to add a panel that takes up the right half of the frame. I am trying to add some more options specific to "Ship Selection" so I am assuming a panel is the correct way to go about it but am not entirely sure. Thanks in advance.
private class OptionsPanel extends JPanel{
private Galaga parent;
public OptionsPanel(Galaga p) {
super();
parent = p;
//layout components however you wish
setLayout(null);
JButton backButton = new JButton("<< Back");
backButton.setBounds(5, 20, 100, 20);
backButton.setFont(new Font("Arial", Font.PLAIN, 15));
backButton.setForeground(Color.white);
backButton.setBackground(Color.black);
backButton.setOpaque(true);
backButton.setBorderPainted(false);
backButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
parent.getLayeredPane().remove(parent.getOptionsPanel());
parent.getLayeredPane().add(parent.getButtonPanel(), new Integer(10));
parent.invalidate();
}
});
add(backButton);
JButton shipSelectButton = new JButton("Ship Selection");
shipSelectButton.setBounds(10, 60, 200, 40);
shipSelectButton.setFont(new Font("Arial", Font.PLAIN, 20));
shipSelectButton.setForeground(Color.white);
shipSelectButton.setBackground(Color.black);
shipSelectButton.setOpaque(true);
shipSelectButton.setBorderPainted(false);
shipSelectButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
}
});
add(shipSelectButton);
}
}
}
The most basic option is to use a GridLayout
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class LayoutExamples {
public static void main(String[] args) {
new LayoutExamples();
}
public LayoutExamples() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(0, 2));
frame.add(new OptionsPanel());
frame.add(new OtherPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class OtherPane extends JPanel {
public OtherPane() {
setBackground(Color.RED);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 200);
}
}
public class OptionsPanel extends JPanel {
public OptionsPanel() {
super();
//layout components however you wish
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(8, 8, 8, 8);
gbc.anchor = GridBagConstraints.NORTHWEST;
JButton backButton = new JButton("<< Back");
backButton.setFont(new Font("Arial", Font.PLAIN, 15));
backButton.setForeground(Color.white);
backButton.setBackground(Color.black);
backButton.setOpaque(true);
backButton.setBorderPainted(false);
backButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
}
});
add(backButton, gbc);
JButton shipSelectButton = new JButton("Ship Selection");
shipSelectButton.setFont(new Font("Arial", Font.PLAIN, 20));
shipSelectButton.setForeground(Color.white);
shipSelectButton.setBackground(Color.black);
shipSelectButton.setOpaque(true);
shipSelectButton.setBorderPainted(false);
shipSelectButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
}
});
gbc.insets = new Insets(12, 8, 12, 12);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weighty = 1;
gbc.weightx = 1;
add(shipSelectButton, gbc);
}
}
}
Pixel perfect layouts are an illusion in modern UI design. You don't have control over how things like fonts or even a single line will be rendered. Differences in rendering pipelines and DPI settings (for example) will change the metrics/size requirements of the components between platforms.
Swing is designed to use layout managers, make appropriate use of them.
I am having problems with figuring how to use event handlers in order to remove and repaint between 2 panels.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PanelSwitcherView extends JFrame {
private JPanel panel1, panel2;
public PanelSwitcherView() {
super("Panel Switching Test");
Font font = new Font("SansSerif", Font.BOLD, 30);
panel1 = new JPanel();
panel1.setLayout(new GridLayout(2, 2, 5, 5));
font = new Font("Serif", Font.ITALIC, 30);
panel2 = new JPanel();
panel2.setLayout(new BorderLayout());
Here I decided to add a test ActionListener but am unsure if correctly used
font = new Font("Monospaced", Font.BOLD + Font.ITALIC, 30);
JButton button = new JButton("Switch Panels");
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.print("Test");
PanelSwitcherModel.switchPanel(); // used to make value of whichpanel 1 or 2
}
});
button.setFont(font);
add(button, BorderLayout.NORTH);
add(panel1, BorderLayout.CENTER);
}
Not completely sure how to use this either
public void displayPanel(int whichPanel) {
remove(panel1);
remove(panel2);
if (whichPanel == 1) {
System.out.println("Should display panel1");
add(panel1, BorderLayout.CENTER);
} else {
System.out.println("Should display panel2");
add(panel2, BorderLayout.CENTER);
}
validate();
repaint();
}
My Controller (class below)
public void register(PanelSwitcherController controller) {
}
Problem lies mainly here, I am a newbie here, do I move my ActionListener here somehow? How do I access other classes in order to change the number from 1 to 2 for my panel options?
import java.awt.event.*;
public class PanelSwitcherController implements ActionListener{
public PanelSwitcherController(PanelSwitcherView view,
PanelSwitcherModel model) {
}
public void actionPerformed(ActionEvent e) {
}
}
I am having some problem with CardLayout. I have a panel and a Next button on it. upon clicking on it i want to display the 2nd panel. In my code, when i click on the Next buton, the next panel is not displayed. Can someone help me solve this ?
package com.test;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.CardLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class CardLay extends JFrame {
private JPanel contentPane;
private CardLayout ca;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CardLay frame = new CardLay();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public CardLay() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
ca =new CardLayout(0, 0);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(ca);
JPanel panel = new JPanel();
panel.setLayout(null);
contentPane.add("1",panel);
JButton btnNext = new JButton("NEXT");
btnNext.setBounds(131, 93, 117, 29);
btnNext.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
ca.show(contentPane,"1");
System.out.println("button clicked");
}
});
panel.add(btnNext);
JPanel panel_1 = new JPanel();
contentPane.add(panel_1, "name_1353086933711396000");
JCheckBox chckbxNewCheckBox = new JCheckBox("New check box");
panel_1.add(chckbxNewCheckBox);
}
}
You need to call:
ca.show(contentPane, "name_1353086933711396000");
For this to work you will have to add the second panel like this:
contentPane.add("name_1353086933711396000", panel_1);
When using CardLayout make sure to keep navigation buttons on a separate container other then the 'cards' themselves, so that they can be visible throughout the navigation process. Here you could place a new navigation container in the frame's BorderLayout.SOUTH position. For sequential navigation, the methods previous and next are available.
Also avoid using absolute positioning (null layout). See Doing Without a Layout Manager (Absolute Positioning).
public CardLay() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(500, 400);
ca = new CardLayout(0, 0);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(ca);
JPanel panel1 = new JPanel();
panel1.add(new JButton("Test Button"));
contentPane.add("card1", panel1);
JPanel panel2 = new JPanel();
contentPane.add("card2", panel2);
JCheckBox chckbxNewCheckBox = new JCheckBox("New check box");
panel2.add(chckbxNewCheckBox);
JPanel navigationPanel = new JPanel();
JButton btnPrevious = new JButton("< PREVIOUS");
btnPrevious.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ca.previous(contentPane);
}
});
navigationPanel.add(btnPrevious);
JButton btnNext = new JButton("NEXT >");
btnNext.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ca.next(contentPane);
}
});
navigationPanel.add(btnNext);
add(contentPane);
add(navigationPanel, BorderLayout.SOUTH);
}
Recommended: How to Use CardLayout