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);
}
}
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.