I am trying to learn Swing and have made a panel (with help from other StackOverflow code). I added a checkerboard design on a frame, but I have found that the frame is not as big as it should be.
Here is my code:
#Override
protected void paintComponent(Graphics g) {
int width = getWidth(), height = getHeight();
g.clearRect(0, 0, width, height);
g.setColor(Color.BLACK);
for (int i=0;i<=width;i+=50) {
g.drawLine(0,i,width,i);
}
for (int i=0;i<=height;i+=50) {
g.drawLine(i,0,i,height);
}
label.setText("H = "+ getHeight() +" W = "+ getWidth()); // check actual size
add(label);
}
private void gui(Pan window) {
frame = new JFrame();
Container container = frame.getContentPane();
container.add(window);
frame.setSize(400, 400); // size written here
frame.setVisible(true);
}
If you run it, you'll see the size of the window. It will be 362 by 384, instead of 400 by 400 as written in the code.
If I change the dimensions to 500 by 500, the window will be 462 by 484.
Q: Why are the dimensions off by 38 and 16?
It will be 362 by 384, instead of 400 by 400
Because the size of the frame include the title bar and borders. Don't use the setSize() method.
Instead override the getPreferredSize() method of your custom panel to return the size that you want the panel to be.
Then you use:
frame.pack();
Then the size of the frame will be the preferred size of your panel, plus the size of the title bar and borders.
Related
This question already has answers here:
Can not draw oval on a JPanel
(2 answers)
Closed 2 years ago.
I'm trying to add a circle to my JPanel, but it won't draw the cricle.
the code below creates a JFrame, creates a JPanle and calls a function to add a circle to the JPanel(pgame), but it doesn't actually add it.
Help appreciated
fgame = new JFrame("Backgammon");
fgame.setSize(1000, 1000);
pgame = new JPanel();
pgame.setPreferredSize(new Dimension(1000, 687));
pgame.setLayout(new GridLayout(3, 10));
pgame.setBorder(BorderFactory.createEmptyBorder(309,460,150,460));
Circle Circlepanel = new Circle();
pgame.add(Circlepanel);
Circlepanel.setVisible(true);
fgame.add(pgame,BorderLayout.CENTER);
fgame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fgame.setTitle("Backgammon");
fgame.pack();
fgame.setVisible(true);
public class Circle extends JPanel {
public void paint(Graphics g) {
g.drawOval(500, 500, 100, 100);
g.setColor(Color.RED);
g.fillOval(500, 500, 100, 100);
}
}
First of all variable names should NOT start with an upper case character. Most of you names are correct, but not all. Learn Java conventions and be consistent!
Your create a GridLayout
pgame.setLayout(new GridLayout(3, 10));
Which will attempt to allocate space for 3 components vertically in the frame.
Then you create a Border:
pgame.setBorder(BorderFactory.createEmptyBorder(309,460,150,460));
which will give your component a height of 459 and a width of 920.
Finally you try to draw the oval at (500, 500) from the top left of the panel.
g.drawOval(500, 500, 100, 100);
Well, the problem is that you have weird random numbers and the size of your component isn't large enough to paint the oval in the space of the component.
To demonstrate this add and retest:
Circlepanel.setBackground( Color.YELLOW );
You will see a yellow panel. Next change:
//pgame.setLayout(new GridLayout(3, 10));
pgame.setLayout(new GridLayout(1, 0));
and you will see a taller yellow panel in the middle of the frame because you are only allocating space for a single component.
Next change:
//pgame.setBorder(BorderFactory.createEmptyBorder(309,460,150,460));
pgame.setBorder(BorderFactory.createEmptyBorder(50,50,50,50));
and you will see part of the oval because you have reserved less space for the border.
Next change:
//g.fillOval(500, 500, 100, 100);
g.fillOval(0, 0, 100, 100);
and you will see the oval at the top of the panel.
The point is that specifying the:
grid size
border size
oval location
all affect the size of the component and how it is painted.
Other issues:
override the getPreferredSize() method of your Circle class to return the desired size of the panel
custom painting is done by overriding paintComponent(), not paint();
you need to invoke super.paintComponent(..) at the start of the method.
Read the section from the Swing tutorial on Custom Painting for more information and working examples.
I'm building a simple 2D game in Java.
I'm using the JFrame class, but I don't think the width and height are what I specified, or perhaps the graphics are incorrect.
Here are some snippets of my code:
public final static int WIDTH = 600, HEIGHT = 900;
JFrame frame = new JFrame();
frame.setSize(WIDTH, HEIGHT);
g.setColor(Color.BLACK);
g.fillRect(0, 0, WIDTH, HEIGHT - 10);
The JFrame is displaying a black background. However, based on the arguments I gave to the fillRect function, there should still be a 10px tall sliver of white at the bottom of the frame. This is not the case. The white sliver only really starts to show after a 30px decrease from the height of the frame.
Thanks for your help.
The JFrame size includes the borders so you need to allow for them. To facilitate dealing with this don't specify the width and height of the JFrame. I recommend doing the following.
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(width,height));
frame.add(panel);
// add other components in the panel
frame.pack();
// center on screen.
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Now your panel will be the specified size.
Note, if your going to paint, make certain you override paintComponent(Graphics g) in JPanel and do your painting there.
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// your code here
}
I need to achieve the effect of "lights off" while displaying animation. It's currently been done with transparent Jframe, black background with 50% opacity the size of the monitor. then, there is this canvas component which should draw RGBA buffered-image.
Problems pops up when the the JFrame opacity effects the Canvas as well, making it semi transparent. That's what i'm trying to avoid.
//** Window class extends Canvas
public Window(){
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
int hostMonitorWidth = gd.getDisplayMode().getWidth();
int hostMonitorHeight = gd.getDisplayMode().getHeight();
Dimension dimension = new Dimension(hostMonitorWidth, hostMonitorHeight);
super.setPreferredSize(dimension);
window = new JFrame();
window.setUndecorated(true);
window.setOpacity(0.55f);
window.setLayout(new GridLayout());
window.setSize(hostMonitorWidth, hostMonitorHeight);
window.add(this);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setLocationRelativeTo(null);
window.setVisible(true);
window.requestFocus();
window.setFocusableWindowState(true);
super.createBufferStrategy(3);
}
public void draw(){
BufferStrategy buffer = super.getBufferStrategy();
java.awt.Graphics g = buffer.getDrawGraphics();
g.setColor(Color.BLACK);
g.fillRect(0,0, super.getWidth(), super.getHeight());
g.drawImage(batch.getImage(), 0, 0, super.getWidth(), super.getHeight(), null);
g.dispose();
buffer.show();
}
I have tried couple combinations of the following code with Jpanel, Layered Panes, Jlabel and what not. It's always seems to keep the opacity / throwing unexplainable exceptions / not working for any reason.
Am i doing it the correct way? what am i missing here?
Don't use setOpacity, use setBackground on the JFrame and pass it a alpha based color. This will allow the frame to become transparent without affecting the other components.
You may, however, find that Canvas doesn't like alpha based colors (as it only has an opaque state)
I have an image that is too tall for my JFrame even when it is maximized. I want to dynamically resize it so that the image will never be clipped by the top or bottom of the JFrame. I have inserted the image within a JLabel as an ImageIcon. I have tried setting the maximum size to no avail. How do I ensure that the height of the image will never be larger than the JFrame? I would ideally like to keep the ratio of height to width constant. The image is in a portrait orientation. Any ideas?
public class myClass extends JFrame {
private void initGUI(){
pane = getContentPane();
pane.setLayout(new BorderLayout());
next = new JButton("Next");
previous = new JButton("Previous");
page = new JLabel(loadImg());
page.setMaximumSize(this.getSize());
pane.add(next, BorderLayout.EAST);
pane.add(previous, BorderLayout.WEST);
pane.add(page, BorderLayout.CENTER);
}
}
I would ideally like to keep the ratio of height to width constant.
Check out Darryl's Stretch Icon. It will shrink/grow depending on the space available, while maintaining the width/height ratio.
You can try overriding the paintComponent(Graphics g) method and drawing the resized image yourself.
page = new JLabel(loadIMG()){
#Override
paintComponent(Graphics g)
{
//So we don't kill default behaviour
super.paintComponent(g);
int scaledWidth, scaledHeight;
//pseudo-code
scale and store into scaledWidth and scaledHeight;
render with g.drawImage(icon, x, y, scaledWidth, scaledHeight, null);
}
};
I am creating an app that uses an undecorated border and wanted to add a shadow to the my JFrame. I got the shadow working but in the process the text got all screwed up.
Due to the size of the program I can not post all of my code but the problem does go away when I remove this line.
setBackground(new Color(0, 0, 0, 0));
So what could cause the text to display blurry and incorrectly? It is bolder and some of the letters seem to be taller.
And I cannot post a picture since I do not have a level 10 reputation.
Here is more of my code:
int extendBy=30;
setMaximumSize(new Dimension(width + extendBy, height + extendBy));
setMinimumSize(new Dimension(width + extendBy, height + extendBy));
setPreferredSize(new Dimension(width + extendBy, height + extendBy));
setUndecorated(true);
setBackground(new Color(0, 0, 0, 0)); // all hell breaks loose here
setContentPane(new ShadowPane());
getContentPane().setBackground(Color.BLACK);
setLocationRelativeTo(null);
setLayout(null); // I know setting null this is bad practice
edit: acquired 10 reputation so here is a pic (look at W or A or k):
Try to override the paintComponent method for this JTable.
How to do it: Overriding paintComponent
For Your case i would use anti-aliasing to get rid of those unwanted effects.
jTable1 = new javax.swing.JTable(){
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON );
}
};