PDA

View Full Version : [SOLVED] JFrame and JPanel visibility issues



MrStill
November 7th, 2010, 11:53 PM
Hi, I am having this issue with JFrame/JPanel that I don't quiet understand. I have a JFrame that initially has an empty JPanel. On an event, I want to replace or fill this JPanel with another JPanel (preferably replace). I have several JPanel subclasses that will determine the content to be displayed.

The problem is that upon setting the JPanel which I want to display in my JFrame, nothing appears. I have checked the class name of the display and can verify that pane is actually changed to the correct subclass of JPanel; however, the content of that panel is not displayed.

Here is my code for the JFrame. The method called by the action listener is showGanttChart().


public class SchedulingHome extends javax.swing.JFrame {

public SchedulingHome() {
initComponents();
...
}
private void setDashboardDisplay(JPanel db){
this.remove(dashboard);
this.dashboard = db;
this.add(dashboard);
this.validate();
}
private void showGanttChart(){
setDashboardDisplay( new GanttChart() );
}
private void initComponents() {
// Generated by NetBeans
...
}
...
}

In case it proves useful, here is my code for GanttChart:


public class GanttChart extends JPanel {
public GanttChart() {
super();
initComponents();
}
private void initComponents() {
// more NetBeans init
jLabel1 = new javax.swing.JLabel();
jLabel1.setText("This is a Gant Chart");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout .Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(346, 346, 346)
.addComponent(jLabel1)
.addContainerGap(386, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout .Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILI NG, layout.createSequentialGroup()
.addContainerGap(222, Short.MAX_VALUE)
.addComponent(jLabel1)
.addGap(213, 213, 213))
);
}
}


I left out the initComponent() function, but can include it if needed.

Thanks
Joseph

muze4life
November 8th, 2010, 12:46 AM
"I left out the initComponent() function, but can include it if needed."
Imo you could do even better by posting the whole NetBeans project (zipped) so others can easily replicate your issue.

MrStill
November 8th, 2010, 02:57 AM
Upon a lot more inspection. NetBeans does some restrictive grouping of components in the initComponents() function. That being said, I changed the init function by using an easier Layout and the add/remove functions work with no change to the code I mentioned above. The lines of the netbeans generated code that I believe caused the problem are:



public void initComponents(){
...
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout .Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout .Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(476, Short.MAX_VALUE))
);
...
}

Reiger
November 8th, 2010, 07:43 AM
GroupLayout does things differently, it has its own API for this.
You can look it up in the Java 6 Javadoc. So the trick is to write a simple component (subclassing JPanel) which will expose its GroupLayout once initialised, then use that API for replacing components as may be needed.

I've got a class which does that by overriding the getLayout() call to explicitly return a GroupLayout (simple cast), and disabling setLayout() after initialisation. For convenience it contains methods to call through to the GroupLayout API directly (e.g. void replace(JPanel panel)) as well as get the current panel (panel()). As far as the GUI builder knows it's just a JPanel form which contains a single fully resizable JPanel.

MrStill
November 9th, 2010, 04:14 AM
GroupLayout does things differently, it has its own API for this.
You can look it up in the Java 6 Javadoc. So the trick is to write a simple component (subclassing JPanel) which will expose its GroupLayout once initialised, then use that API for replacing components as may be needed.

I've got a class which does that by overriding the getLayout() call to explicitly return a GroupLayout (simple cast), and disabling setLayout() after initialisation. For convenience it contains methods to call through to the GroupLayout API directly (e.g. void replace(JPanel panel)) as well as get the current panel (panel()). As far as the GUI builder knows it's just a JPanel form which contains a single fully resizable JPanel.

Thanks for the reply. I spent some time looking over the API for a solution that I could sell to my team mates. In the long run I choose to do this:



private void setDashboardDisplay(DashboardDisplay db){
GroupLayout layout = (GroupLayout)getContentPane().getLayout();
layout.replace(dashboard, db);
dashboard = db;
}


It looks similar to what you were speaking of, in the fact that I am extracting the GroupLayout and speaking to it directly; however, I have not provided an adapter which disables setLayout. Hopefully this will not cause issues in the future, as my JFrame does not change only the single JPanel contained within.