GetWidth () and getHeight () are 0 after calling setPreferredSize ()

I have been working on my project for several hours now, only to be constantly disappointed in this.

I have a parent JFrame that adds a JPanel to it, and it will be used to render and display my modeling that I am developing. There are no swing objects to be added to JPanel, as I will only use it to render shapes using a graphic object.

My code as such is below:

public class SimulationPanel extends JPanel { private BufferedImage junction; private Graphics2D graphics; public SimulationPanel() { super(); initPanel(); } private void initPanel() { this.setPreferredSize(new Dimension(600, 600)); //TODO: bug with not sizing the junction correctly. junction = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_3BYTE_BGR); graphics = junction.createGraphics(); setBackground(Color.white); System.out.println(getWidth()); } 

The code is specially broken into the second line of the initPanel () method, where I am trying to create a new BufferedImage.

Conclusion from the exception state: "Exception in thread" AWT-EventQueue-0 "java.lang.IllegalArgumentException: Width (0) and height (0) must be> 0"

I'm really not sure why that is. I tried using past answers from Stack Overflow, but they did not help.

This is my first post, so I hope this is not so bad.

Thanks.

+4
source share
3 answers

When you set the preferred size, you tell the various Java layout managers how you want the panel to be laid out after it is added to the container. But until it is added to the container, it will not have a width or height, and even after that it may not have the required width and height.

One option is to simply use 600 directly for the width and height of your new buffered image, and when you add a panel to the JFrame, make sure you call pack() in the JFrame to allow the window to be sized to the preferred size of your panel.

+4
source

Create a BufferedImage buffer inside your paintComponent component. There you will know the actual size of the component and consider this for rendering. The image acts as a cache of your component content, but you do not take into account that its size is part of the cached information.

 @Override protected void paintComponent(Graphics g) { // create cache image if necessary if (null == image || image.getWidth() != getWidth() || image.getHeight() != getHeight() ||) { image = new BufferedImage(getWidth(), getHeight()); imageIsInvalid = true; } // render to cache if needed if (imageIsInvalid()) { renderToImage(); } // redraw component from cache // TODO take the clip into account g.drawImage(image, 0, 0, null); } 
+3
source

The reason this will not work is because pack() not called (to set all width and height values) until the panel is triggered, so the height and width are not set yet. And BufferedImage throws an exception if the width or height are non-positive integers.

So why don't you just set the values โ€‹โ€‹yourself? Here's how to do it in your example:

 private void initPanel() { final int width = 600; final int height = 600; this.setPreferredSize(new Dimension(width, height)); junction = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); graphics = junction.createGraphics(); setBackground(Color.white); } 

Alternatively: If you have a requirement that the image should be resized using the component, you need to do this. I am sure that when pack() is called, it fires the ComponentListener.componentResized() event, so this should work when you trigger the component, even if you don't resize the component. So instead, do it in your code:

 private void initPanel() { this.setPreferredSize(new Dimension(600, 600)); this.addComponentListener(new ComponentListener() { public void componentResized(ComponentEvent e) { Component c = (Component) e.getSource(); Dimension d = c.getSize(); resizeImage(d); } }); this.setBackground(Color.white); } public void resizeImage(Dimension d) { junction = new BufferedImage(d.getWidth(), d.getHeight(), BufferedImage.TYPE_3BYTE_BGR); graphics = junction.createGraphics(); } 
+1
source

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


All Articles