Reputation: 73
I wanted to draw a rectangle with 80% width and 80% height of the original window in the JPanel.
Here's my driver class
public class driver {
public static void main(String[] args) {
System.out.println("test");
Window myWindow = new Window();
myWindow.add(new GraphPanel());
myWindow.settings();
}
}
Here's my JPanel:
import javax.swing.*;
public class Window extends JFrame {
private static final int width = 1100;
private static final int height = 600;
public void settings(){
setSize(width,height);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
public static int[] getWindowSize(){
int[] output = new int[]{width, height};
return output;
}
}
and the rectangle canvas:
import java.awt.*;
public class GraphPanel extends Canvas {
public void paint(Graphics g){
setBackground(Color.WHITE);
setForeground(Color.DARK_GRAY);
int[] windowSize = Window.getWindowSize();
//Not working as intented
g.drawRect(windowSize[0]/10, windowSize[1]/10, 8*windowSize[0]/10, 8*windowSize[1]/10);
}
}
And here's the result, I can't post image so here's a link https://i.sstatic.net/VlQIk.png
As you can see, this is clearly not centered, the height is off by about 30 pixels and width about 20. I have no idea how this happened, so my question is, does anyone know what might have caused this?
Upvotes: 1
Views: 675
Reputation: 347234
You might want to start by having a quick read of this to get a better understand of why you current approach isn't going to work (the way you expect).
The first thing I would do is change your GraphPanel
so it defines it's preferredSize
, independent of the window. This way you give control to the layout management system instead.
Next, I would use the actual physical size of the component to base your calculations on
int width = (int) (getWidth() * 0.8);
int height = (int) (getHeight() * 0.8);
I'd also recommend moving the setBackground
and setBackground
out of the paint
method. This will cause a new pain cycle to occur and will make a mess of things.
public class GraphPanel extends Canvas {
private static final int PREF_WIDTH = 1100;
private static final int PREF_HEIGHT = 600;
public GraphPanel() {
setBackground(Color.WHITE);
setBackground(Color.DARK_GRAY);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_WIDTH, PREF_HEIGHT);
}
@Override
public void paint(Graphics g) {
super.paint(g);
int width = (int) (getWidth() * 0.8);
int height = (int) (getHeight() * 0.8);
int x = (getWidth() - width) / 2;
int y = (getHeight() - height) / 2;
//Not working as intented
g.drawRect(x, y, width, height);
}
}
I would then update your Window
class so it used pack
instead of setSize
. This will "pack" the window around the content, taking into consideration the frame decorations.
public class Window extends JFrame {
public void settings() {
pack();
setLocationRelativeTo(null);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Although, I'd question the point of extending from JFrame
, but I'm getting of topic.
Speaking of which, unless you're intending to high performance graphics which requires you to have complete control over the painting sub system, I'd recommend starting with Swing based components or even JavaFX
Upvotes: 0