JComponent does not draw JPanel

I have a custom component that extends JComponent that overrides the paintComponent (Graphics g) method, but when I try to add it to my JPanel it just doesn't work, nothing is drawn. Here is my code:

public class SimpleComponent extends JComponent{ int x, y, width, height; public SimpleComponent(int x, int y, int width, int height){ this.x = x; this.y = y; } @Override public void paintComponent(Graphics g){ Graphics2D g2 = (Graphics2D) g; g2.setColor(Color.BLACK); g2.fillRect(x, y, width, height); } } public class TestFrame{ public static void main(String[] args){ JFrame frame = new JFrame(); JPanel panel = new JPanel(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); panel.setPreferredSize(new Dimension(400, 400)); frame.add(panel); frame.pack(); frame.setResizable(false); SimpleComponent comp = new SimpleComponent(10, 10, 100, 100); panel.add(comp); frame.setVisible(true); } } 
+6
source share
2 answers

It works great - the component is added to JPanel, but how big is it? If you check this after the GUI has been displayed, you will most likely find that your component size is 0, 0.

 SimpleComponent comp = new SimpleComponent(10, 10, 100, 100); panel.add(comp); frame.setVisible(true); System.out.println(comp.getSize()); 

Consider your JComponent overriding getPreferredSize and returning a size that makes sense:

 public Dimension getPreferredSize() { return new Dimension(width, height); } 

If you want to use x and y, you can also override getLocation() .

Edit
You also need to set the width and height fields!

 public SimpleComponent(int x, int y, int width, int height) { this.x = x; this.y = y; this.width = width; // *** added this.height = height; // *** added } 
+4
source

Whoaa! Absolutely wrong answer!

The first absolute CARDINAL SIN you have done is to do all this in a non-EDT thread !!! There is no place to explain it ... There are only about 30 billion places on the Web to find out about it.

Once all this code is executed in Runnable in EDT (Thread Dispatch Thread), then:

You should not override preferredSize (although you can if you want) ... but you need to install it.

You absolutely must not set dimensions ( height and width , or setSize() ) directly!

What you need DO is to get java.awt.Container , panel in your example to "lay out itself" ... there is the Container.doLayout() method, but as the API documentation says:

Forces this container to lay out its components. Most programs should not call this method directly, but should call the verification method instead.

therefore the solution:

 SimpleComponent comp = new SimpleComponent(10, 10, 100, 100); comp.setPreferredSize( new Dimension( 90, 90 ) ); panel.add(comp); // the key to unlocking the mystery panel.validate(); frame.setVisible(true); 

By the way, please use my experience: I spent hours and hours tearing my hair, trying to figure it all out validate, invalidate, paintComponent, paint , etc ... and I still feel like I just scratched the surface.

-2
source

Source: https://habr.com/ru/post/927092/


All Articles