Reputation: 2645
Can somebody please help me understand why my custom JComponent 'Bar', only displays when added directly to the JFrame, and not when added to a JPanel (which is then added to the JFrame)?
Thanks!
package main;
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Board {
public void start(){
JFrame frame = new JFrame();
JButton button1 = new JButton("Button 1");
Bar statusbar = new Bar();
JLabel status = new JLabel("Status: ");
JPanel topPanel = new JPanel();
topPanel.add(status);
topPanel.add(statusbar);
JPanel mainPanel = new JPanel();
mainPanel.add(button1);
mainPanel.add(statusbar);
frame.getContentPane().add(BorderLayout.NORTH, topPanel);
frame.getContentPane().add(BorderLayout.SOUTH, mainPanel);
frame.getContentPane().add(BorderLayout.CENTER, statusbar);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(200,100);
frame.setVisible(true);
}
}
Here is my Bar Class...
package main;
import java.awt.Graphics;
import javax.swing.JComponent;
public class Bar extends JComponent{
public void paint(Graphics g){
g.fillRect(0, 0, 100, 10);
}
}
Upvotes: 2
Views: 2181
Reputation: 44250
The dimension of the custom component is (0, 0)
.
When added to a container with a BorderLayout
layout manager, it will expand to fill the available space, and therefore become visible.
When added to a container with a FlowLayout
layout manager, it will not expand and will instead remain at its preferred size (i.e. (0, 0)
). And therefore, will not become visible, albeit it is still there.
This explains why the custom component is only displayed when added directly to the JFrame
, since it uses a BorderLayout
layout manager, whereas a JPanel
uses a FlowLayout
layout manager.
Upvotes: 3
Reputation: 9157
You're adding statusbar
to several different places in the component tree, Swing doesn't deal with that well (or at all).
Create a separate Bar
instances each time you use it, if you want their display to be synchronized, they should share the same model.
Ah, on a second glance, the problem here is that you never set a size (or preferred size) for the Bar
components, so they get squished to 0 by the layout manager.
Try:
public static class Bar extends JComponent {
private Bar() {
setPreferredSize(new Dimension(25, 5));
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillRect(0, 0, 100, 10);
}
}
You should also add a frame.pack()
before display.
(the multiple references to the same component thing is still true, too)
Upvotes: 3