java swing dynamically adding components [duplicate] - java

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

Related

How to edit JTextField?

I want to write a simple Swing application with a button and a text field at the bottom. I'm using a JTextField but it is not clickable. I searched on the web and SO, but I could not find a solution. In question How to Set Focus on JTextField?, I found the following :
addWindowListener( new WindowAdapter() {
public void windowOpened( WindowEvent e ){
entry.requestFocus();
}
});
but this does not help. In this other question (How do you set a focus on Textfield in Swing?) I found Component.requestFocus() but this does not work either. I also tried
entry.setFocusable(true);
entry.setEditable(true);
entry.setEnabled(true);
without effects. My code:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class StackSample extends JFrame {
public StackSample() {
initUI();
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void initUI() {
JPanel panel = new JPanel(new BorderLayout());
add(panel, BorderLayout.CENTER);
JPanel bottomPanel = new JPanel(new FlowLayout());
panel.add(bottomPanel, BorderLayout.SOUTH);
JButton buttonDraw = new JButton("Draw");
bottomPanel.add(buttonDraw);
JTextField entry = new JTextField();
bottomPanel.add(entry);
setPreferredSize(new Dimension(250, 150));
setLocationRelativeTo(null);
}
private static final long serialVersionUID = 8359448221778584189L;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MyApp app = new MyApp();
app.setVisible(true);
}
});
}
}
Your JTextField is clickable. The only problem is that it's too small.
This is because you're using FlowLayout, which will make components as small as possible.
One solution is to simply switch to a layout that allows components to fill as much space as possible, such as BoxLayout:
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BoxLayout(bottomPanel,BoxLayout.X_AXIS));
You haven't specified a size for your JTextField, so it defaults to zero characters wide. Try using the constructor that specifies the number of columns.
Also, what is MyApp? I can't see any evidence that your StackSample is ever created or used.

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

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();
}
}

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.

How can I correctly place a JPanel onto a JFrame?

I'm currently studying Software Engineering at Uni and I'm struggling to come to terms with how to add a JPanel onto a JFrame properly. My JPanel has a couple of buttons as well as a JLabel which changes by clicking on one of the buttons and using an ActionListener.
I know there are several ways to do it, and here is what I've been trying but I can't for the life of me figure it out!
I know I am doing loads wrong but what is it?
Here is my code:
UIPanelOne:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.*;
public class UIPanelOne extends JPanel implements ActionListener {
private JButton yes, no, cancel;
private JPanel panel;
private JLabel l1, l2;
UIPanelOne() {
super();
setVisible(true);
//label dec
panel = new JPanel();
//buttons
yes = new JButton("Yes");
no = new JButton("No");
cancel = new JButton("Cancel");
//label dec
l1 = new JLabel("Hello");
//button dec
panel.setLayout(new BorderLayout());
panel.add(yes);
panel.add(no);
panel.add(cancel);
panel.add(l1);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == yes) {
l1.setText("OK then!");
}else if (e.getSource() == no){
l1.setText("Goodbye then!");
}else if(e.getSource() == cancel){
System.exit(0);
}
}
public JComponent getGUI(){
return panel;
}
}
UIFrame:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class UIFrame extends JFrame{
//constructor
public UIFrame(){
//layout
super("Can I help you?");
setSize(400,600);
setLayout(new BorderLayout());
setVisible(true);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
UIPanelOne hello = new UIPanelOne();
getContentPane().add(hello.getGUI());
}
}
UITest:
public class UITest {
public static void main(String[] args){
UIFrame frame = new UIFrame();
frame.pack();
}
}
I know alot of this is probably wrong and I'm a total amateur but I'm hoping to get better with some help!
Since your UIPanelOne extends JPanel class you can add your component's on that panel (no need for creation of new panel), create a new instance and pass that instance to add method of JFrame:
add(new UIPanelOne());
or
UIPanelOne hello = new UIPanelOne();
add(hello,BorderLayout.CENTER);
or
setContentPane(hello);
Avoid extending your classes with swing component's unless you want to define new method's for them (creation of custom component's) or if you wan't to override some of their method's.
You don't have to set BorderLayout for JFrame since it's default layout for JFrame (aleady set).
Call setVisible method for JFrame AFTER you add component's.
Also, read about Concurrency in Swing

Categories

Resources