Reputation: 151
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);
}
}
Upvotes: 3
Views: 7205
Reputation: 474
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 send me an email if I can be of further assistance. [email protected] (I like helping people with their programming and I learn from it too.)
Upvotes: 0
Reputation: 347334
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"));
}
}
}
Upvotes: 5
Reputation: 285430
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.
Upvotes: 1