Add method in JPanel created using GUI builder - java

I have GUI created using netbeans GUI builder. I want to add there an object (let's try with button) after pressing a JButton
The very simple code which I wrote in ActionListener and works:
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
panel2.add(new JButton("X"));
panel2.validate();
}
});
Howewer in Gui created by netbeans this doesnt work:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
jPanel1.add(new JButton("X"));
jPanel1.validate();
System.out.print("aa");
}
But it prints "aa" so action listener works.
It looks like a similar problem to one showed here:
http://bytes.com/topic/java/answers/857720-adding-icon-jpanel
but I can't see even that rectangle about which JosAH wrote.
I'll appreciate any suggestion.

Create a placeholder panel in your editor, and then add the panel to that. I think the problem is to do with layouts and such, since some layouts require some layout data to be present on adding the component (i.e., the second field in add(c, ...) is set). So, create a placeholder JPanel using the GUI creator tool, name it so you have a reference to it, and then add the component to that panel. Give it a layout such as FlowLayout which requires no layout data. You may also want to remove all the insets on the panel so you don't get massive spacing, which you can probably do in the UI editor.

Related

JPanel deforms my Layout

Im using NetBeans to do a work for school. There i have an huge JPanel that contains a huge JFrame. That JFrame as 5 small JFrames, 1 is the menu with buttons, the other ones are boxes with text that will swap when i choose in the buttons.
When one box is showing the other ones are invisible im using the following code (dont know if it is the best):
public ConversorUI() {
initComponents();
PanelVazio.setVisible(true);
PanelTemp.setVisible(false);
PanelComp.setVisible(false);
PanelMoedas.setVisible(false);
this.pack();
}
My problem is, when i run my program i have a big space with nothing and only below it the components appear. I want them to appear in the top of my window. What can I do ?
ANSWER
After some time searching i just realized i could Set Layout from JPanel to Card Layout and create JPanels over each other activating them with the code:
private void DinheiroButtonActionPerformed(java.awt.event.ActionEvent evt) {
//Remove Panels
CAIXA.removeAll();
CAIXA.repaint();
CAIXA.revalidate();
//Add Panels
CAIXA.add(DinheiroBox);
CAIXA.repaint();
CAIXA.revalidate();
}
Looks like you are using Java Swing , right ?
Any way you do something wrong if you have JPanel that contains JFrames. To build correct UI you have to add JPanels inside JFrame.
Also, to reach correct component order and placing you need configure corresponded layout, here is description.
You can load one jframe at e time
Because every jframe you added have own place and visibility doesnt do anything to remove
Try to save every jframe and for changing
Delete old one and add new one
Why are you using multiple JFrames to do this? From what I can see it would be a better idea to use JPanels that can take care of the individual tasks, such as the menu and buttons etc.
I'm relatively new to using javax.swing myself, but from my knowledge you can only have 1 frame at a time per window (like the other person said).
From what i've been able to discern from your project, you possibly don't even need multiple panels. You just need one panel for the menu with buttons, and multiple Labels or JLabels that display text according to the button. You can use the setText method in writing your addActionListener, something like this:
buttonName.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
labelName.setText("blah blah blah");
//and whatever else you may need to do
}
});

Elements don't appear in a Panel with a GridLayout or FlowLayout, but with a setBounds they do

I'm doing a program that is composed by multiple panels in a JFrame.
I need to do every elements in differents classes (It's because in my school, we need to have every elements separeated in different classes for clean code), but every example that I see with my kind of problem, they do everything in one class.
And I think that my problem comes from having multile classes so I show you my classes.
I have a panel in wich I need to put 2 panel, here is the code :
public class Inscription extends JPanel{
private PanneauBoutons panneauBoutons = new PanneauBoutons();
private PanneauFormulaire panneauFormulaire = new PanneauFormulaire();
public Inscription(){
this.setLayout(new BorderLayout());
this.setBorder(BorderFactory.createLineBorder(Color.RED, 2));
this.add(panneauFormulaire,BorderLayout.CENTER);
this.add(panneauBoutons,BorderLayout.SOUTH);
this.setVisible(true);
}
}
And here is the Panel panneauFormulaire :
public class PanneauFormulaire extends JPanel{
private JLabel labelMatricule;
private JTextField zoneTexteMatricule;
public PanneauFormulaire(){
this.setLayout(new GridLayout(8,2,10,10));
this.setBorder(BorderFactory.createLineBorder(Color.black));
labelMatricule = new JLabel("Matricule : ");
this.add(labelMatricule);
zoneTexteMatricule = new JTextField(30);
this.add(zoneTexteMatricule);
this.setVisible(true);
}
So the problem Inscription don't appear on the main Frame if I don't do setBounds, but I want a BorderLayout...
(I tested and with a set bounds I can see the borders, so I think that it means the panel are really added to the Frame so why without setBounds I see anything?).
And the other problem is that the panel PanneauFormulaire don't appear on the Inscription panel...
So if I miss something, can you help me? thank you
And here it is the class that extends JFrame :
public class FenetrePrincipale extends JFrame {
private Container cont;
private Inscription inscriptionForm;
public FenetrePrincipale(){
super("IESN");
setBounds(100,100,1200,960);
getContentPane().setLayout(null);
setLocationRelativeTo(null);
setResizable(false);
...
inscription.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
cont.removeAll();
inscriptionForm = new Inscription();
inscriptionForm.setOpaque(true);
cont.add(inscriptionForm);
invalidate();
repaint();
}
});
You should NOT be using a null layout and setBounds(). Swing was designed to be used with layout managers.
but when I click on an option in the menu, the current panel need to be change by another one,
Then you should be using a CardLayout.
Read the section from the Swing tutorial on How to Use CardLayout for working examples. So download the example and use it as the starting point of your project. The code will be better structured then what you currently have and it is easier to change working code than it is to fix broken code.
so why without setBounds I see anything?
That is because you set your layout to null in getContentPane().setLayout(null);.
Java containers comes with a default layout which you are allowed to set to a different one. How the components are arranged in the container are dependent on the layout you use. The layout will directly affects the location, alignment, spacing, dimension, preferredSize of the components.
However, if you choose not to use any layout (.setLayout(null)). Swing will not know how you want the components to be arranged, hence you see nothing in your content pane.
Since you wanted "absolute control" over the components, you will be expected to set the bounds (location and dimension) of each added component manually by yourself. This is why you are not seeing any components (even if you already added it) until you set the bounds for them.
Java, elements don't appear in a Panel with a GridLayout or FlowLayout, but with a setBounds they do
Every layout has their own characteristics and for some of them the order of your codes does makes a difference. Hence, I will advise you to go through what each layout can do for you. Then, depending on your needs, choose one (or a combination of a few) and study how to use it.
And here it is the class that extends JFrame :
You probably won't want to extends to a JFrame. You can always make a customized Container like JPanel and add it to the frame.
(Why would you want to paint your paintings on a frame instead of a piece of paper?)

Removing a label in Java

I have this piece of code, which should remove a label, when a button is pressed:
final JLabel label = new JLabel("Label text");
rightPanel.add(label);
final JButton remove = new JButton("Remove label");
leftPanel.add(remove);
add.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
rightPanel.remove(label);
}
});
But when I click on the button, it doesn't remove the label text. Only when I resize the window (for example set it to full screen), the label text dissapears.
From this previous answer located here, put forth by camickr, you need to do the following:
The code would be (assuming the use of a JPanel):
panel.remove(...);
panel.revalidate();
panel.repaint(); // sometimes needed
You need to remove the component and then tell the panel to layout the remaining components.
Perhaps not an answer to your question but what I consider helpful advice: only add/remove components when it is absolutely necessary. If you get creative, you'll find that there are often better solutions than adding/removing components. For example, instead of removing a JButton, consider disabling it instead.
In your situation, you could always just do label.setText(""). This way you don't need to revalidate() and repaint().
I very rarely call revalidate() and repaint() in my code. I think it's better to update the existing components than to remove/add them.

Java Swing dynamic loading of classes into panels

My program looks like this!
I want to have the bottom part dynamically load a frame into the bottom frame depending on the item selected in the ComboBox. For example, if the first item is selected I want a panel from the PresentValue.java file displayed. The idea is that I have one java file for each selection that displays what I design in its respective java file.
These two java files should be put into the "bottom" box from my first screenshot, depending on the selection from the combobox.
I'm more used to Android programming and there I would simple call the replace method from fragments to swap out the fragment loaded... looking for the analogy here.
final JComboBox selectorBox = new JComboBox(selection);
selectorBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
int selectionID = selectorBox.getSelectedIndex();
}
});
but cant find a way to do what I want to do. Please explain.
For each Java file that you have, the output of that Java file should be a JPanel. Not a JFrame.
Before you display anything, execute all of the Java files you have. Create all of the possible JPanels.
Create your JFrame in your GUI, then use the remove and add methods of JFrame to remove or add the desired JPanel.
Here's an example from one of my GUI's.
public void updatePartControl() {
Thread thread = new CountdownThread(model, this, displayPanel);
thread.start();
frame.remove(alarmPanel.getPanel());
frame.add(displayPanel.getPanel());
frame.validate();
frame.pack();
frame.setBounds(getBounds());
}
The setBounds method resets the bounds if the display JPanel is bigger or smaller than the alarm JPanel.
Your application should have one JFrame. You use multiple JPanels to create your GUI.
Changing the bottom component will depend on the layout manager that are using. CardLayout is purpose designed for swapping panels.
public void actionPerformed(ActionEvent arg0) {
int selectionID = selectorBox.getSelectedIndex();
if (selectionID == 0) {
cardLayout.show(basePanel, SELECTED_1);
}
// handle other selections
}

NetBeans form designer: Change layout after call to initComponents

I have a class that extends javax.swing.JPanel, it contains a single JButton. I've created the class in NetBeans designer. As such, I have a initComponents() function thats called from the class constructor.
What I want to do is when/if a function is called, I want to add a second button, and change the layout of the two buttons. Doing simply:
public void addSecond() {
javax.swing.JButton secondButton = new javax.swing.JButton();
add(secondButton , java.awt.BorderLayout.CENTER);
}
Doesnt work, the new button doesnt show up. I tried a call to invalidate() as well but no luck.
How do I trigger a re-evaluation of the layout?
If said function is called more than once, what parts of the layout/buttons do I need to call dispose() on? Any other cleanup I should worry about?
Would this be easier to handle if I don't use the NetBeans designer?
You need to set the layout of the panel before you add the button with BorderLayout.CENTER. Also, you must remove and add the first button again and invoke the revalidate() method on the panel.
Change your addSecond() method as below and it should work.
private void addSecond() {
JButton secondButton = new JButton("Button - 2");
this.setLayout(new BorderLayout());
remove(firstButton);
add(firstButton, BorderLayout.NORTH);
add(secondButton, BorderLayout.CENTER);
revalidate();
}
when you changed the components in a way that changes the layout, you need to trigger the layout manager again by calling revalidate(). You can call it as often as you want.
For simple layouts just calling repaint() may be sufficient.
And actually unless you're doing dynamically changing panels (i.e. adding/removing components on the fly) you should use the netbeans designer, so all the Swing elements are in one place.
-- EDIT --
And you can only put one component into BorderLayout.CENTER per panel. If you put more than one element into the same position of a panel, what gets painted is not well defined, i.e. it may be either of the elements (or both).

Categories