How can I use multiple JPanels in one Java swing application? [duplicate] - java

How to make an added JPanel visible inside a parent JPanel?
I am using Netbeans for designing my UI.
I have a MainFrame.java, which contains two panels; namely headerPanel and bodyPanel.
In headerPanel I have put three buttons,let it be button1, button2 and button3.
Also I have created three separate files extending JPanel, name it panel1, panel2 and panel3.
Then I added all my three panels inside bodypanel in MainFrame.java in constructor.
bodyPanel.add(panel1);
bodyPanel.add(panel2);
bodyPanel.add(panel3);
I want that on clicking the respective buttons only respective panels should appear in the bodypanel in mainframe, i.e. if I click button1 then panel1 should be displayed.
I have already tried the following code in button1 mouse listener method:
bodyPanel.validate();
bodyPanel.getComponent(0).setVisible(true);
But panel1 does not appear. I did it cause added components in a panel are allotted index. So first I tried to get the components and then make it visible. It did not work.

Use a CardLayout, as shown here.

your requirement truely full filled by CARD LAYOUT
see this example link
and below example Link
the perfect code for your problem case is
package panels.examples;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Container;
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;
public class MainFrame extends JFrame implements ActionListener
{
JPanel headerPanel;
JPanel bodyPanel;
JPanel panel1,panel2,panel3;
JButton button1,button2,button3;
Container con;
CardLayout clayout;
public MainFrame()
{
//con=getContentPane();
clayout=new CardLayout();
headerPanel=new JPanel();
bodyPanel=new JPanel(clayout);
button1=new JButton("button1");
button2=new JButton("button2");
button3=new JButton("button3");
//add three buttons to headerPanel
headerPanel.add(button1);
headerPanel.add(button2);
headerPanel.add(button3);
button1.addActionListener(this);
button2.addActionListener(this);
button3.addActionListener(this);
panel1=new JPanel();
panel1.add(new JLabel("Panel1"));
panel1.setBackground(Color.pink);
panel2=new JPanel();
panel2.add(new JLabel("Panel2"));
panel2.setBackground(Color.gray);
panel3=new JPanel();
panel3.add(new JLabel("Panel3"));
//add above three panels to bodyPanel
bodyPanel.add(panel1,"one");
bodyPanel.add(panel2,"two");
bodyPanel.add(panel3,"three");
setLayout(new BorderLayout());
setSize(600,450);
add(headerPanel,BorderLayout.NORTH);
add(bodyPanel,BorderLayout.CENTER);
// headerPanel.setBounds(0,0,600,100);
bodyPanel.setBounds(0,100, 600, 500);
setVisible(true);
}
public static void main(String args[])
{
new MainFrame();
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==button1)
{
clayout.show(bodyPanel, "one");
}
else if(e.getSource()==button2)
{
clayout.show(bodyPanel, "two");
}
else if(e.getSource()==button3)
{
clayout.show(bodyPanel, "three");
}
}
}
out put

Use the CardLayout. Below is a Helper class that I have written. Hope it helps.
import java.awt.CardLayout;
import javax.swing.JPanel;
/**
*
* #author Dchan(Dulitha Wijewantha)
*
* This class is used to switch Cards in a CardLayout
*
* #version $Revision: 1.0 $
*/
public class CardLayoutHelper {
private JPanel panel;
private CardLayout layout;
/**
*
* #param panel JPanel
*/
public CardLayoutHelper(JPanel panel) {
this.panel = panel;
this.layout = (CardLayout) this.panel.getLayout();
}
public CardLayoutHelper(JPanel panel, JPanel... panels){
this(panel);
for (int i = 0; i < panels.length; i++) {
JPanel jPanel = panels[i];
panel.add(jPanel.getName(), jPanel);
}
}
/**
*
* #param currentPanel
* - The panel that will be switched into the view
*/
public void switchPanel(JPanel currentPanel) {
panel.removeAll();
panel.add(currentPanel, currentPanel.getName());
layout.show(panel, currentPanel.getName());
panel.revalidate();
panel.repaint();
}
public void switchPanel(String name){
layout.show(panel, name);
panel.revalidate();
panel.repaint();
}
}

Related

Java FlowLayout

I am writing some Java code that allows the user to see a frame with JLabel, JTextField and JButton.
I want the JLabel to be called "Count" and I have a problem with FlowLayout.
I want the interface to look like this:
Instead, I have this:
This is my code:
package modul1_Interfate_Grafice;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Exercitiu04 implements ActionListener {
private JFrame frame;
private JLabel labelCount;
private JTextField tfCount;
private JButton buttonCount;
private int count = 0;
public void go() {
frame = new JFrame("Java Counter");
labelCount = new JLabel("Counter");
labelCount.setLayout(new FlowLayout());
frame.getContentPane().add(BorderLayout.CENTER, labelCount);
tfCount = new JTextField(count + " ", 10);
tfCount.setEditable(false);
labelCount.add(tfCount);
buttonCount = new JButton("Count");
labelCount.add(buttonCount);
buttonCount.addActionListener(this);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(350, 150);
frame.setLocation(400, 200);
}
#Override
public void actionPerformed(ActionEvent event) {
count++;
tfCount.setText(count + "");
}
public static void main(String[] args) {
Exercitiu04 a = new Exercitiu04();
a.go();
}
}
Solve it.
Instead of labelCount.setLayout(new FlowLayout());` i should have had
frame.setLayout(new FlowLayout());
From description of JLabel class,
JLabel is:
A display area for a short text string or an image, or both.
But here: labelCount.add(tfCount) and here labelCount.add(buttonCount) you're trying to put a textfield and a button into a label. In this case, positions of button and textfield are controlled by FlowLayout but position of the text in the label is not.
Instead of this, you should put all of your elements in common JPanel, like this:
...
frame = new JFrame("Java Counter");
frame.setLayout(new BorderLayout());
JPanel wrapper = new JPanel(); // JPanel has FlowLayout by default
labelCount = new JLabel("Counter");
labelCount.setLayout(new FlowLayout());
wrapper.add(labelCount);
tfCount = new JTextField(count + " ", 10);
tfCount.setEditable(false);
wrapper.add(tfCount);
buttonCount = new JButton("Count");
buttonCount.addActionListener(this);
wrapper.add(buttonCount);
frame.add(BorderLayout.CENTER, wrapper);
...
And, like MasterBlaster said, you should put swing methods in EDT.
There are only two things you should know about FlowLayout:
a) It is a default layout manager of the JPanel component
b) It is good for nothing.
This trivial layout cannot be achieved with FlowLayout.
When doing layouts in Swing, you should familiarize yourself
with some powerful layout managers. I recommend MigLayout and
GroupLayout.
package com.zetcode;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;
/*
Simple UI with a MigLayout manager.
Author Jan Bodnar
Website zetcode.com
*/
public class MigLayoutCounterEx extends JFrame {
public MigLayoutCounterEx() {
initUI();
}
private void initUI() {
JLabel lbl = new JLabel("Counter");
JTextField field = new JTextField(10);
JButton btn = new JButton("Count");
createLayout(lbl, field, btn);
setTitle("Java Counter");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void createLayout(JComponent... arg) {
setLayout(new MigLayout());
add(arg[0]);
add(arg[1]);
add(arg[2]);
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
MigLayoutCounterEx ex = new MigLayoutCounterEx();
ex.setVisible(true);
});
}
}
The example is trivial. You just put the three components into the
cells.
Screenshot:
You shouldn't use setSize when dealing with FlowLayout. Instead use pack(). It makes the window just about big enough to fit all your components in. That should tidy things up for you

Nothing gets shown in the JFrame

I want to create a gui, which has on the top two horizontal components(a combobox and a button) and on the bottom I would like to add several components. I created everything like that:
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSeparator;
public class minimumExample extends JFrame {
private JButton addItem;
private JComboBox itemBox;
private String[] itemSelect = { "test1", "test2" };
private JPanel addUpperPane;
private JPanel addLowerPane;
public void createControlPane() {
setLayout(new BorderLayout());
addUpperPane = new JPanel(new BorderLayout(5, 5));
addLowerPane = new JPanel(new GridLayout(0, 1));
addItem = new JButton("Add item");
itemBox = new JComboBox(itemSelect);
addItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
getContentPane().setLayout(new GridLayout(0, 1));
if(itemBox.getSelectedItem().toString().equals("test1")) {
addLowerPane.add(new Button("Lolonator"));
validate();
repaint();
}
}
});;
addUpperPane.add(itemBox);
addUpperPane.add(addItem);
addUpperPane.add(new JSeparator(JSeparator.HORIZONTAL));
//put everything together
add(addUpperPane);
add(addLowerPane);
repaint();
}
private void makeLayout() {
setTitle("Test App");
setLayout(new BorderLayout());
setPreferredSize(new Dimension(1000, 500));
createControlPane();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
/**
* starts the GUI
*/
public void start() {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
makeLayout();
}
});
}
public static void main(String[] args) throws IOException {
minimumExample ex = new minimumExample();
ex.start();
}
}
My problem is that nothing gets shown and I also thing that the layouts are not correct. Any recommendations what I should change to fix my problem?
I appreciate your answer!
UPDATE
Here is a simple wireframe of how my gui should look like:
UPDATE 2
Changing everything to:
addUpperPane.add(itemBox, BorderLayout.EAST);
addUpperPane.add(addItem, BorderLayout.WEST);
addUpperPane.add(new JSeparator(JSeparator.HORIZONTAL));
//put everything together
add(addUpperPane, BorderLayout.NORTH);
add(addLowerPane, BorderLayout.SOUTH);
Gives me that:
Any recommendations how to remove the gap?
Since you used BorderLayout you need the specify the location of each component of the layout what you are doing is that you are only adding all the component on the same position of the layout which by default is CENTER.
solution:
addUpperPane.add(itemBox,BorderLayout.EAST);
addUpperPane.add(addItem,BorderLayout.WEST);
addUpperPane.add(new JSeparator(JSeparator.HORIZONTAL));
//put everything together
add(addUpperPane,BorderLayout.NORTH);
add(addLowerPane,BorderLayout.SOUTH);
Also this doesn't make since setLayout(new BorderLayout()); that JFrame's default layout is already BorderLayout so no need to set the layout to it again.
EDIT:
If you want your component to be side by side then FlowLayout is the way to go:
addUpperPane = new JPanel(); //default component of JPanel is FlowLayout
addUpperPane.add(itemBox);
addUpperPane.add(addItemT);
EDIT number 2:
problem:
getContentPane().setLayout(new GridLayout(0, 1)); //remove it
sample:
addItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(itemBox.getSelectedItem().toString().equals("test1")) {
addLowerPane.add(new Button("Lolonator"));
revalidate();
}
}
});;
The solution of Rod_Algonquin is right.
If you are going to build more GUI I can recommend MigLayout to you. It helps you to write nice GUIs which less lines of readable code.
Their homepage: http://miglayout.com/

Java JPanel moves slightly on its own + extra

I have a problem. Now I'm working with 3 panels, mainPanel and 2 others ( btnPanel and iconPanel).
So the problem is when I push button "reset" I delete iconPanel and add it again it moves slightly to right on its own. Maybe someone can check my code where the problem?
Also I dont want to create another question so I give 2 extra questions.
Do I delete JPanel properly?
If I delete JPanel with components inside they also will be removed from memory?
P.s. Im beginner so dont judge me :)
Main.java
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Main extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("Made by Mac4s");
frame.setVisible(true);
frame.setSize(310, 654);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setResizable(false);
MainScreen screenObj = new MainScreen();
screenObj.setPreferredSize(new Dimension(310, 650));
frame.add(screenObj);
}
});
}
}
MainScreen.java
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class MainScreen extends JPanel {
private JButton resetBtn;
private JPanel btnPanel;
private JPanel iconPanel;
public MainScreen() {
JPanel mainPanel = new JPanel(new BorderLayout());
this.setBackground(Color.BLACK);
setBtnPanelAndComp();
setIconPanelAndComp();
add(mainPanel);
}
private void setBtnPanelAndComp() {
btnPanel = new JPanel(new BorderLayout());
btnPanel.setBackground(Color.GREEN);
btnPanel.setPreferredSize(new Dimension(295, 30));
setButtons();
this.add(btnPanel, BorderLayout.NORTH);
}
private void setButtons() {
resetBtn = new JButton("Reset");
resetBtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
resetIconLabel();
}
});
btnPanel.add(resetBtn, BorderLayout.WEST);
}
private void resetIconLabel() {
this.remove(iconPanel);
this.repaint();
this.revalidate();
setIconPanelAndComp();
}
private void setIconPanelAndComp() {
iconPanel = new JPanel(new BorderLayout());
iconPanel.setBackground(Color.YELLOW);
iconPanel.setPreferredSize(new Dimension(295, 580));
this.add(iconPanel, BorderLayout.SOUTH);
}
}
"the problem is when I push button "reset" I delete iconPanel and add it again it moves slightly to right on its own."
The reason this happens is because a JPanel has a FlowLayout by default. You're trying add to a BorderLayout position that is non-existent.
this.add(iconPanel, BorderLayout.SOUTH);
The FlowLayout has default gaps on the edges, so when you set the size of the frame, those gaps aren't respected. To over come this, it is also preferable to pack() the frame, instead of setSize()
The reason BorderLayout works (doesn't shift) is because preferred sizes aren't respected.
If you set the layout in the constructor to this.setLayout(new BorderLayout()); You won't have the shift.
public MainScreen() {
JPanel mainPanel = new JPanel(new BorderLayout());
this.setLayout(new BorderLayout()); <----
setBtnPanelAndComp();
setIconPanelAndComp();
add(mainPanel);
}
Notes
You should setVisible() after adding components. That's why your frame jumps when you first open it. You are setting the frame visible, then moving it around with the location, and adding components.

Replacing a JPanel with a different JPanel

Hi this is a bit of a basic question. In my code I create a gui in a constructor then nest a ActionListener class to handle button changes. This code will create the gui and the action listener runs through the actionPerformed method correctly. However, I've tried multiple ways to change the panel in the gui but I feel like the way I have the program set up it is not possible for this to work. Sorry if this is a repeat but after searching for a while on S.O. I haven't found a good example that would help me with my problem.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import org.math.plot.Plot2DPanel;
import org.math.plot.plotObjects.BaseLabel;
public class GraphGui extends JFrame {
//default width and height of the GUI
private static final int WIDTH = 1200;
private static final int HEIGHT = 700;
GraphPlot gp = new GraphPlot();
Plot2DPanel plotPanel =gp.determinePlotToPlot("duration");
/**
* This is the constructor that initializes the JFrame and the layout of the GUI.
* The radio buttons are also created here and grouped accordingly.
*/
public GraphGui() {
//title of GUI
setTitle("VibeTech Graph Gui");
//First JRadioButton for date vs duration
JRadioButton durToDate = new JRadioButton("Duration vs. Date");
durToDate.addActionListener(new RadioButtonListener());
durToDate.setActionCommand("duration");
durToDate.setSelected(true);
//JRadioButton for weight vs date
JRadioButton weightToDate = new JRadioButton("Weight vs. Date");
weightToDate.addActionListener(new RadioButtonListener());
weightToDate.setActionCommand("weight");
//JRadioButton for plan type vs date
JRadioButton planToDate = new JRadioButton("Plan vs. Date");
planToDate.addActionListener(new RadioButtonListener());
planToDate.setActionCommand("level");
//button group of the buttons to display them as one group
ButtonGroup group = new ButtonGroup();
group.add(planToDate);
group.add(weightToDate);
group.add(durToDate);
//create JPanel to add objects to
JPanel jplRadio = new JPanel();
jplRadio.setLayout(new GridLayout(0, 1));
//add radio buttons
jplRadio.add(planToDate);
jplRadio.add(weightToDate);
jplRadio.add(durToDate);
Plot2DPanel dvt = new Plot2DPanel();
dvt.addLinePlot("Duration over Time", gp.getDate(), gp.getDuration());
BaseLabel title = new BaseLabel("Duration over Time", Color.RED,
0.5, 1.1);
title.setFont(new Font("Courier", Font.BOLD, 20));
dvt.addPlotable(title);
dvt.setAxisLabels("Time", "Duration");
setLayout(new BorderLayout());
add(jplRadio, BorderLayout.WEST);
add(plotPanel, BorderLayout.EAST);
setSize(WIDTH, HEIGHT);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
//main method to run program
public static void main(String [ ] args)
{
//create new GUI
#SuppressWarnings("unused")
GraphGui test = new GraphGui();
}
//create a radio button listener to switch graphs on button press
class RadioButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("duration")) {
plotPanel = gp.determinePlotToPlot("duration");
} else if (e.getActionCommand().equals("weight")) {
plotPanel = gp.determinePlotToPlot("weight");
} else if (e.getActionCommand().equals("level")) {
plotPanel = gp.determinePlotToPlot("level");
}
//here is where I tried to do removes, adds, and validates but
//I have trouble getting to the frame itself to remove the JPanel
//component. I think this is a setup problem.
}
}
}
You would need to add the panel and revalidate/repaint the JFrame for it to appear:
add(plotPanel, BorderLayout.EAST);
revalidate();
repaint();
Better to use CardLayout to manage this type of functionality.
Try using CardLayout for switching between panels. Here is my solution for a similar question: https://stackoverflow.com/a/9377623/544983

java swing dynamically adding components [duplicate]

This question already has answers here:
java - How would I dynamically add swing component to gui on click?
(5 answers)
Closed 9 years ago.
I am new to Java Swing. I have some doubt regarding adiing components dynamically in Swing.
Basically I hav one Main JPanel consisting of two sub JPanel (leftpanel and rightpanel ) which alligned horizontally.In left JPanel I hav some JButtons, when I will click on JButton I nedd to show some JLabel, JTextArea etc in right JPanel. I tried a code but its not working .When I click on the button its going inside the event listener function but JLabel I am not able to view.
I am giving my code below. Pls look at this and correct me. thanks in advance
package my;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/**
*
* #author root
*/
public class myAplliwithPanel extends JFrame{
JPanel rightPanel;
public myAplliwithPanel() {
initGui();
}
public void initGui()
{
JPanel mainPanel=new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.X_AXIS));
JPanel leftPanel=new JPanel();
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS));
rightPanel=new JPanel();
rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.Y_AXIS));
JButton dbBut=new JButton("DB");
JButton appliBut=new JButton("Appli");
appliBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JLabel label=new JLabel("dsggs");
rightPanel.add(label);
}
});
JButton backendBut=new JButton("Backend");
leftPanel.add(dbBut);
leftPanel.add(appliBut);
leftPanel.add(backendBut);
mainPanel.add(leftPanel);
mainPanel.add(rightPanel);
add(mainPanel);
setTitle("System Manger");
setSize(400, 400);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
myAplliwithPanel myObj = new myAplliwithPanel();
myObj.setVisible(true);
}
});
}
}
You need to call revalidate after adding (or removing) components:
rightPanel.add(label);
rightPanel.revalidate();
should do the trick.
call
rightPanel.revalidate();
rightPanel.repaint();
after adding
just add this line after you add the label
rightPanel.updateUI();
when you add any component at runtime you need to update the ui using this method

Categories

Resources