I'm trying to draw a line in a JFrame
, but line isn't drawn.
I tried to use the method setOpaque(true)
for contentPane
, lblNewLabel
and l
but nothing changed. I also tried call repaint();
outside this class but the situation is still the same. Here's the code:
public class DrawingClass extends JFrame
{
private JPanel contentPane;
public DrawingClass(int n, int s, int p) {
Line l= new Line();
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setBounds(700, 300, 480, 640);
contentPane = new JPanel();
contentPane.setOpaque(true);
setResizable(false);
setContentPane(contentPane);
contentPane.setLayout(null);
JLabel lblNewLabel = new JLabel("");
lblNewLabel.setIcon(new ImageIcon("image.png"));
lblNewLabel.setBounds(0, 0, 480, 640);
contentPane.add(lblNewLabel);
l.setBounds(0,0,480,640);
contentPane.add(l);
repaint();
}
class Line extends JPanel
{
public void paintComponent(Graphics g) {
g.setColor(Color.BLUE);
g.fillRect(10, 10, 15, 12);
}
}
}
I expect a little line on the top left of the JFrame, above the background wallpaper, but nothing happen. It shows only the wallpaper.
There are several errors in your code:
You're extending JFrame
but you're not changing its behavior, so why are you doing that? JFrame
is a rigid component, so it's never a good idea to extend from it, build your GUI based on JPanel
s instead. See: Extends JFrame vs. creating it inside the program
Don't explicitly set the size of the JFrame
, call pack()
on it and instead override getPreferredSize
from the JPanel
, see: Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?
You don't need to call setOpaque(...)
in this case.
Don't use a null-layout
, it might lead to strange errors, because null Layout is Evil and frowned upon
We don't have access to your image so we cannot test the ImageIcon
and it's also not related to your question. However you should load your images as resources
Don't explicitly set the bounds of each element, this is related to point (4) and you should use a Layout Manager or combinations of them to get your desired GUI.
Don't call repaint()
that way, it has no effect, it is supposed to repaint your UI when there's a change in it. However there is no change at the start of your program.
You're breaking the paint-chain by not calling super.paintComponent(...)
inside your paintComponent(...)
method. Check the Tutorial on Custom Painting in Swing so that you learn how to do it properly
And be careful, as paintComponents(...)
(With a trailing s
) is different from paintComponent(...)
(Look at your title)
So, after doing all of the above changes, we get to this simple program:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class DrawingClass {
private JPanel contentPane;
private JFrame frame;
public static void main(String args[]) {
SwingUtilities.invokeLater(() -> new DrawingClass().createAndShowGUI());
}
public void createAndShowGUI() {
frame = new JFrame(getClass().getSimpleName());
Line line = new Line();
frame.add(line);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
class Line extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(10, 10, 15, 12);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(480, 640);
}
}
}
Which produces the following output: