Reputation: 1438
In the code below, I create a JFrame
, set the size to 800 by 800 pixels, set the layout to BorderLayout
, then add a JPanel
.
In the JPanel
, I use paintComponent
to draw a 20x20 pixel image in 7 locations.
At position 0-0, the icon appears in the upper right corner.
The icon is 20 pixels high, and the frame and panel are both 800 pixels high, so drawing the icon at x-780 should align the icon with the bottom of the window. But the icond doesn't even appear.
The remaining icons are drawn a x-770, x-760, x-758, and x-750. x-758 appears aligned with the bottom of the window. So I conclude that x[0] on the JPanel
start at the JFrame
's x[42]
I think I've set the BorderLayout
correctly. I do call setSize()
in the JPanel
's constructor. I thought setting an explicit size might screw it up. But after commenting that line out, the program shows the same behavior.
Can you show me what I'm doing wrong?
Frametest.java
package frametest;
import java.awt.BorderLayout;
import javax.swing.JFrame;
public class FrameTest extends JFrame{
public static final int HEIGHT = 800;
public static final int WIDTH = 800;
public FrameTest(){
setLayout(new BorderLayout());
add(new Panel(WIDTH, HEIGHT), BorderLayout.CENTER);
pack();
setTitle("Frame Test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(WIDTH, HEIGHT);
setResizable(false);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
new FrameTest();
}
}
Panel.java
package frametest;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class Panel extends JPanel{
private int height;
private int width;
Image icon1 = new ImageIcon(this.getClass().getResource("icon1.png")).getImage(); //Note that the png file is 20 x 20 pixels.
public Panel(int width, int hieght){
setBackground(Color.BLUE);
//setSize(width, hieght);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(icon1, 0, 0, this); //appears in the upper-right corner
g2d.drawImage(icon1, 20, 780, this); //does not appear
g2d.drawImage(icon1, 40, 770, this); //appears with bottom pixels cut off
g2d.drawImage(icon1, 70, 760, this); //appears with the bottom pixels cut off
g2d.drawImage(icon1, 100, 758, this); //appears aligned with bottom of the window
g2d.drawImage(icon1, 130, 750, this); //appears slightly above the bottom of the window
g2d.drawImage(icon1, 780, 20, this); //appears aligned with the right side of the screen.
}
}
Upvotes: 0
Views: 1730
Reputation: 8410
You are setting the size of the JFrame
. This includes the Frame Decoration, the Menu Bar (if you have one), and so on. If you want your JPanel to have the Dimensions 800 x 800
, set the preferred Size of your JPanel and use JFrame.pack()
.
To do so, remove the following line from Frametest.java
:
setSize(WIDTH, HEIGHT);
Then, in Panel.java
, change this line from
//setSize(width, hieght);
to:
setPreferredSize(new Dimension(800, 800));
Instead of this, you can also overwrite getPreferredSize()
:
public Dimension getPreferredSize ()
{
return new Dimension(800, 800);
}
Upvotes: 2
Reputation: 10623
It sounds like the problem is because of the border around the JFrame. Things like the menu bar at the top will take away some space from the available space to display things in the JFrame.
Try adding getPreferredSize()
to your JPanel, and calling pack()
on your JFrame.
Upvotes: 1
Reputation: 46871
Use frame.pack()
(as you are already using) instead of frame.setSize()
that fits the components as per component's preferred size. Just remove setSize()
calls.
Override getPreferredSize()
to set the preferred size of the JPanel
in case of custom painting.
sample code:
class Panel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
...
}
@Override
public Dimension getPreferredSize() {
return new Dimension(..., ...);
}
}
Upvotes: 1