How to add a panel class to my frame in main class - java

I am fairly new to oo, I have created a class which is most of the interface of my program, I have put it all together in a class. I then want to add my Panel class to my main class so my panels are attached to my Frame:
This is what I have tried, I am not receiving any errors, when I run my program but the panels are not displaying:
Panel Class:
public class PanelDriver extends JPanel {
public JPanel p1, myg;
public PanelDriver() {
JPanel p1 = new JPanel();
p1.setBackground(Color.CYAN);
// Graphicsa myg = new Graphicsa();
JTextArea txt = new JTextArea(5,20);
txt.setText("test");
p1.add(txt);
}
}
Main class:
public class GraphicMain {
public static void main(String[] args) {
JFrame frame = new JFrame("My Program");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
PanelDriver panels = new PanelDriver();
frame.getContentPane().add(panels);
GridLayout layout = new GridLayout(1,2);
}

you need a super call (because you extend JPanel you don't need to create a new one) and a layout in you Panel class like this:
public class CustomerTest extends JPanel {
public CustomerTest() {
super();
this.setBackground(Color.CYAN);
this.setLayout(new BorderLayout());
JTextArea txt = new JTextArea();
txt.setText("test");
this.add(txt);
this.setVisible(true);
}
}
and then in your main class use this, to set the frame visible and display the content. you have to set the layout for the frame after you created it:
JFrame frame = new JFrame("My Program");
GridLayout layout = new GridLayout(1, 2);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
CustomerTest panels = new CustomerTest();
frame.getContentPane().setLayout(layout);;
frame.add(panels);
frame.setVisible(true);

Your PanelDriver class creates a p1 JPanel, but doesn't add it to anything.
At least add it to the PanelDriver itself :
this.add(p1);
Note that as your code is, the frame isn't even displaying, look at the answer by #XtremeBaumer to fix that part.

Related

Java Swing - Show multiple panels

I'm using the Java Swing UI Designer in IntelliJ :( I designed something in the designer using multiple panels and spacers with 1 parent panel. When I add the main panel, the first one inside it shows, but the others don't.
Frame structure:
Panel1
GradientPanel
Panel
Spacers
What I designed
What I get
import keeptoo.KGradientPanel;
import javax.swing.*;
public class LogIn extends JFrame{
private KGradientPanel KGradientPanel1; //Automatically added by the designer
private JPanel panel1; //Automatically added by the designer
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle("CarbonTec Dashboard");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setSize(1800,1000);
frame.setContentPane(new LogIn().panel1);
frame.setVisible(true);
ImageIcon imageIcon = new ImageIcon("Icon.png");
frame.setIconImage(imageIcon.getImage());
}
}
First you need to know that your class is a JFrame, but in the main method you create a new JFrame.
Better would be to have a class Program that has the main method. In this main method you make a new instance of LogIn.
The Program class can look like this:
public class MainProgram {
public static void main(String[] args) {
LogIn logIn = new LogIn();
}
}
The LogIn class should then look like this:
import keeptoo.KGradientPanel;
import javax.swing.*;
public class LogIn extends JFrame{
private KGradientPanel KGradientPanel1 = new KGradientPanel(); //Automatically added by the designer
private JPanel panel1 = new JPanel(); //Automatically added by the designer
// This is the constructor.
public LogIn {
setTitle("CarbonTec Dashboard");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setSize(1800,1000);
setContentPane(panel1);
ImageIcon imageIcon = new ImageIcon("Icon.png");
setIconImage(imageIcon.getImage());
// Here you can add the gradient panel to panel1.
panel1.add(KGradientPanel1); // The name should be written in lower case.
setVisible(true);
}
But I don't know why you need the panel1, you could add the KGradientPanel directly.

Java Swing JTabbedPane layout

I am new to Swing and cannot find a page that helps me understand JTabbedPane. I cannot find a way to control the layout of components of the tabbed panels. I can layout each of my panels correctly as separate GUIs but not in a tabbed pane like I need to do. I would like to use the BorderLayout not FlowLayout.
Also, you can see I'm trying to use colors to keep track of my panels and their components. I cannot set the background of the JTabbedPane. It is still the default grey. Can someone tell me why this is?
Thank you for any advice you can give.
What I have so far appears to follow a 'flow layout' despite any changes I've tried
(Methods have been removed or nearly removed to keep code shorter)
public class GUIFrame extends JFrame {
public GUIFrame(String title) {
JFrame frame = new JFrame(title);
Container c = frame.getContentPane();
buildGUI(c);
setFrameAttributes(frame);
}
private void buildGUI(Container c) {
c.setLayout(new BorderLayout());
c.setBackground(Color.BLACK);
JTabbedPane tabs = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.WRAP_TAB_LAYOUT);
tabs.setBackground(Color.YELLOW);
c.add("Center", tabs);
tabs.addTab("Specialty", new SpecialtyPanel());
tabs.addTab("Treatment", new TreatmentPanel());
tabs.addTab("Doctor", new DoctorPanel());
tabs.addTab("Patient", new PatientPanel());
}
private void setFrameAttributes(JFrame f) {
f.setSize(500, 500);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String args[]) {
MedicalSystemIO test = new MedicalSystemIO();
new GUIFrame("Tabbed Title");
}
public class SpecialtyPanel extends JPanel implements ActionListener {
JTextField jteInput = null;
DefaultListModel<String> model = new DefaultListModel<String>();
JList<String> list = new JList(model);
JScrollPane pane = new JScrollPane(list);
public SpecialtyPanel() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createLineBorder(Color.black));
buildGUI(panel);
}
private void buildGUI(JPanel panel) {
JPanel jpaInput = createInputPanel();
JPanel jpaProcess = createProcessPanel();
JPanel jpaOutput = createOutputPanel();
//panel.setLayout(new BorderLayout());
add("North", jpaInput);
add("Center", jpaProcess);
add("South", jpaOutput);
}
private JPanel createInputPanel() {
JPanel jpaInput = new JPanel();
jpaInput.setBackground(Color.RED);
return jpaInput;
}
private JPanel createProcessPanel() {
JPanel jpaProcess = new JPanel();
jpaProcess.setBackground(Color.BLUE);
return jpaProcess;
}
private JPanel createOutputPanel() {
JPanel jpaOutput = new JPanel();
jpaOutput.add(pane);
return jpaOutput;
}
The SpecialtyPanel is shown that way (flow layout) as you are putting the components on it in the wrong way:
No need for passing a new panel into the buildGUI method as you want to put them directly on the SpecialtyPanel which already is a JPanel,
you commented out the setting of the BorderLayout and
you used the wrong notation of passing the layout constraints in the add methods.
Your constructor and build method should look like this:
public SpecialtyPanel() {
buildGUI();
}
private void buildGUI() {
setBorder(BorderFactory.createLineBorder(Color.black));
JPanel jpaInput = createInputPanel();
JPanel jpaProcess = createProcessPanel();
JPanel jpaOutput = createOutputPanel();
setLayout(new BorderLayout());
add(jpaInput, BorderLayout.NORTH);
add(jpaProcess, BorderLayout.CENTER);
add(jpaOutput, BorderLayout.SOUTH);
}
To have the panel another color than gray you have to color the component that is put on the tabbed pane as it covers the whole space. Add the desired color to the buildGUI method, e.g.:
private void buildGUI(JPanel panel) {
// ...
setBackground(Color.YELLOW);
}
As a JPanel is opaque by default (that means not transparent), you need to set panels on top (except those which you colored explicitly) to be transparent. In case of SpecialtyPanel:
private JPanel createOutputPanel() {
JPanel jpaOutput = new JPanel();
jpaOutput.add(pane);
jpaOutput.setOpaque(false); // panel transparent
return jpaOutput;
}

JScrollPane doesn't work while inside a JPanel

JScrollPane works perfectly when I give it a JPanel and then add the JScrollPane directly on to a JFrame with frame.getContentPane.add(). However, it doesn't work when I add the JScrollPane to a JPanel and then add the JPanel to the JFrame. I need to use the second method because I'm going to add multiple things inside the JPanel and JFrame and I need to keep it organized. Here is my code.
import java.awt.*;
import javax.swing.*;
public class Main {
/**
* #param inpanel asks if the JScrollPane should
* be inside of a JPanel (so other things can also be added)
*/
public static void testScroll(boolean inpanel) {
JFrame f = new JFrame();
f.setLayout(new BorderLayout());
f.setResizable(true);
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createLineBorder(Color.red));
//panel.setLayout(new BoxLayout(panel, 1));
panel.setLayout(new GridLayout(0,1));
for (int i = 0; i < 100; i++) {
JLabel l = new JLabel("hey"+i,SwingConstants.CENTER);
l.setBorder(BorderFactory.createLineBorder(Color.green));
l.setPreferredSize(new Dimension(200,200));
panel.add(l);
}
JScrollPane scrollPane = new JScrollPane(panel);
scrollPane.setBorder(BorderFactory.createLineBorder(Color.blue));
//**********THIS DOES NOT WORK HOW I WANT IT TO************
if(inpanel){
JPanel holder = new JPanel();
holder.add(scrollPane);
f.getContentPane().add(holder);
}
//************THIS DOES WORK HOW I WANT IT TO****************
else{
f.getContentPane().add(scrollPane);
}
f.pack();
f.setSize(500, 500);
f.setExtendedState(JFrame.MAXIMIZED_BOTH);
f.setVisible(true);
JScrollBar bar = scrollPane.getVerticalScrollBar();
bar.setValue(bar.getMaximum());
bar.setUnitIncrement(50);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
testScroll(false); //OR TRUE
}
};
SwingUtilities.invokeLater(r);
}
}
In the main method, if I pass false, it works like I mentioned before, but when I pass true it shows up without a scroll bar.
Picture when passing false
Picture when passing true
I need a way to add the JScrollPane to a JPanel and still have it work.
Thanks in advance!
Your problem is the holder JPanel's layout. By default it is FlowLayout which will not re-size its child components when need be. Make it a BorderLayout instead, and your scrollpane will resize when needed. If you need something more complex, check out the layout manager tutorials.

how to change a panel of CardLayout through another panel

In my program I have a wizard based layout. Implemented by CardLayout. So there is a set of classes that extend JPanels. I want to have buttons in each panel to navigate to other panels. fro example, when the program is showing panel one, I want to have a button to show panel 2.
I tired to create a method in main cardlayout panel holder so any other class can change the showing panel by this method, but it does not works and a stackoverflow error come up.
Here are my classes
Base Frame:
public class Base {
JFrame frame = new JFrame("Panel");
BorderLayout bl = new BorderLayout();
public Base(){
frame.setLayout(bl);
frame.setSize(800, 600);
frame.add(new LeftBar(), BorderLayout.WEST);
frame.add(new MainPanel(), BorderLayout.CENTER);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
new Base();
}
}
Main class that holds sub panels:
public class MainPanel extends JPanel {
private CardLayout cl = new CardLayout();
private JPanel panelHolder = new JPanel(cl);
public MainPanel() {
NewSession session = new NewSession();
ChooseSource chooseSource = new ChooseSource();
panelHolder.add(session, "Session");
panelHolder.add(chooseSource, "ChooseSource");
cl.show(panelHolder, "Session");
add(panelHolder);
}
public void showPanel(String panelIdentifier){
cl.show(panelHolder, panelIdentifier);
}
}
Sub panel 1
public class NewSession extends JPanel {
MainPanel ob2 = new MainPanel();
public NewSession(){
JButton newSessionBTN = new JButton("Create A New Session");
newSessionBTN.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
System.out.println("HI");
ob2.showPanel("ChooseSource");
}
});
add(newSessionBTN);
}
}
Sub panel 2
public class ChooseSource extends JPanel {
public ChooseSource(){
JLabel showMe = new JLabel("Show Me");
JButton back = new JButton("Back");
//MainPanel ob = new MainPanel();
back.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
//ob.showPanel("start");
}
});
add(back);
add(showMe);
}
}
As you can see I have button in each sub panel and those buttons must show the other panel after clicking. In later they will also transfer the data from one to another.
ERROR:
Exception in thread "main" java.lang.StackOverflowError
at java.awt.Component.setFont(Component.java:1899)
at java.awt.Container.setFont(Container.java:1748)
at javax.swing.JComponent.setFont(JComponent.java:2751)
at javax.swing.LookAndFeel.installColorsAndFont(LookAndFeel.java:208)
at javax.swing.plaf.basic.BasicPanelUI.installDefaults(BasicPanelUI.java:66)
at javax.swing.plaf.basic.BasicPanelUI.installUI(BasicPanelUI.java:56)
at javax.swing.JComponent.setUI(JComponent.java:663)
at javax.swing.JPanel.setUI(JPanel.java:153)
at javax.swing.JPanel.updateUI(JPanel.java:126)
at javax.swing.JPanel.<init>(JPanel.java:86)
at javax.swing.JPanel.<init>(JPanel.java:109)
at javax.swing.JPanel.<init>(JPanel.java:117)
at InnerPanels.NewSession.<init>(NewSession.java:21)
at StrongBaseLayout.MainPanel.<init>(MainPanel.java:22)
The error is longer than this, by repeating last two lines.
How can I make it working?
Also I had another idea to have a next and previous buttons at the bottom of the page to switch panels. But am not sure which one is optimal. Any idea?
Whenever you see an unexpected StackOverflowError always look for the presence of inadvertent recursion, and in fact, that's exactly what you have going on here since MainPanel creates a NewSession object which then creates a new MainPanel object which then creates a new NewSession object which then creates a new MainPanel object .... repeating ad infinitum or until stack memory (hence the stack overflow) runs out.
here:
public class NewSession extends JPanel {
MainPanel ob2 = new MainPanel(); // *****
and here:
public class MainPanel extends JPanel {
private CardLayout cl = new CardLayout();
private JPanel panelHolder = new JPanel(cl);
public MainPanel() {
NewSession session = new NewSession(); // *****
Don't do that. Instead take care to create one and only one of each object. Use setter methods or constructor parameters to help you do this.
For example, change to this:
public class NewSession extends JPanel {
MainPanel ob2;
NewSession(MainPanel mainPanel) {
this.ob2 = mainPanel;
and this:
public class MainPanel extends JPanel {
private CardLayout cl = new CardLayout();
private JPanel panelHolder = new JPanel(cl);
public MainPanel() {
NewSession session = new NewSession(this);
Regarding:
Also I had another idea to have a next and previous buttons at the bottom of the page to switch panels. But am not sure which one is optimal. Any idea?
I'm not sure what you mean here. Define "optimal".

Including a panel from external java file?

Is it possible to include a jpanel into an container from another java file? Let suppose I have 2 java files fileA.java and fileB.java. And I want to add the entire display content of fileB.java inside a container in fileA.java. Is this possible? Just a confusion running in for a very long time. Thanks in advance.
You could make the other file/cass extends JPanel and then since it is a JPanel, you can add it to any other file. For example:
FileA.java
public class FileA {
public FileA() {
JFrame jf = new JFrame();
jf.setLayout(new BorderLayout());
FileB b = new FileB();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setBounds(100,100,800,600);
jf.setVisible(true);
add(b, BorderLayout.CENTER);
}
public static void main(String[] args) {
new FileA();
}
}
FileB.java
public class FileB extends JPanel {
public FileB() {
setLayout(new BorderLayout());
add(new JLabel("Example"), BorderLayout.CENTER);
}
}
Or you can simply have a JPanel be a field in another file and access it with a getter method.
Example:
FileC.java
public class FileC {
private JPanel panel;
public FileC() {
panel = new JPanel();
panel.add(new JLabel("Example 2"));
}
public JPanel getPanel() {
return panel;
}
}
Yes, you can.
1- If fileB class extends JPanel, then create an instance of fileB and add it to whatever container you have:
fileB panel = new fileB();
container.add(panel);
2- If fileB has a JPanel as a field, then you need to access it either by itself if it's public field, or by a getter method otherwise:
fileB f = new fileB();
JPanel panel = f.getPanel(); // or f.panel if the panel is a public field
container.add(panel);

Categories

Resources