Reputation: 3
I have some problem drawing a simple line to a Frame
through a JButton
.
The problem occurs only when I do this with a JButton
.
If I directly use the JPanel
inside the Frame
, everything is OK.
JFrame
:
import javax.swing.*;
import java.awt.*;
public class Fenetre extends JFrame {
public Fenetre(){
super("Test");
init();
pack();
setSize(200,200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
private void init() {
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
JButton button = new JButton("Draw line");
button.addActionListener((e)->{
Pane s = new Pane();
panel.add(s);
s.repaint();
});
panel.setBackground(new Color(149,222,205));
add(button,BorderLayout.SOUTH);
add(panel,BorderLayout.CENTER);
}
public static void main(String[] args){
new Fenetre();
}
}
And the JPanel
with paintComponents()
:
import javax.swing.*;
import java.awt.*;
public class Pane extends JPanel {
public void paintComponents(Graphics g){
super.paintComponents(g);
g.drawLine(0,20,100,20);
}
}
Upvotes: 0
Views: 739
Reputation: 347334
A number of issues jump out at me immediately:
paintComponent
, not paintComponents
(note the s
at the end), you're too high up in the paint chain. There's also no need for either method to be public
, no one outside the class should be calling it.Pane
provides no sizing hints, so it's "default" size will be 0x0
Instead, it should look more like...
public class Pane extends JPanel {
public Dimension getPreferredSize() {
return new Dimension(100, 40);
}
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.drawLine(0,20,100,20);
}
}
When adding components, Swing is lazy. It won't run a layout/paint pass until it has to or you ask it to. This is an optimisation, as you may add many components before needing to perform a layout pass.
To request a layout pass, call revalidate
on the top level container you've updated. As a general rule of thumb, if you call revalidate
, you should also call repaint
to request a new paint pass as well.
public class Fenetre extends JFrame {
public Fenetre(){
super("Test");
init();
//pack();
setSize(200,200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
private void init() {
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
JButton button = new JButton("Draw line");
button.addActionListener((e)->{
Pane s = new Pane();
panel.add(s);
panel.revalidate();
panel.repaint();
//s.repaint();
});
panel.setBackground(new Color(149,222,205));
add(button,BorderLayout.SOUTH);
add(panel,BorderLayout.CENTER);
}
public static void main(String[] args){
new Fenetre();
}
}
That should at least get your panel
to show up now
Upvotes: 1