Window Size is smaller than it should be - java

Alright so I've got this JFrame with a screen on it. I've set the size to 800 by 800. However the window is created smaller than that. It's not a problem with the taskbar because it's not fullsize.
package sharph;
import java.awt.Dimension;
import javax.swing.JFrame;
public class Main extends JFrame {
public static String Title = "Game 1";
public static Dimension screenSize = new Dimension(800,800);
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle(Title);
frame.setSize(screenSize);
frame.setLocationRelativeTo(null);
frame.setResizable(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
Screen screen = new Screen();
screen.setSize(screenSize);
frame.add(screen);
frame.setVisible(true);
}
}
In the screen class the paint method draws a box around where the border should be:
//Draw border
g.setColor(Color.RED);
g.drawRect(1, 1, 799, 799);
When I run it, the window is smaller than the box and the bottom and right sides are cut off.
Note the second picture I manually re-sized to show the border difference.
I realize that I have drawn the box 1 pixel smaller on each side, but the difference is much more than 2 pixels.

This happens because the content needs to squeezed into the size of the frame minus its borders.
Checkout this question and this question for a more detailed explanation
The layout manager is also overriding the size property you set on the Screen component. In either case, you should be overriding the getPreferredSize method of the Screen class
Also, you shouldn't be relying on magic numbers or assumptions about the actual size of the component, but should, instead, be using getWidth and getHeight instead (I know, it's just for demonstration purposes)

Instead of "screen.setSize(screenSize);" type "screen.setPreferredSize(screenSize);" and then after you type "frame.setVisible(true);" type "frame.pack()". You can also remove "frame.setSize(screenSize);" if you want to.

Related

JLabel does not fully allign with JFrame

I have a JFrame with a JLabel on top called "coloredLabel", an instance of the class it's in is running on both of them. a random amount of objects move around on the frame and label and don't directly interact with them.
The only problem is that there is a bit of the frame visable above the label, what I want is that the label fully alligns with the frame, without pasting over the objects (which are painted in with an override paint method and mentioned as "game.newBall" and "game.moveBall". "test" is the name of the class.
Here is how my main thread looks, the frame and the label are declared within it:
public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame("Bounce 2.0");
JLabel coloredLabel = new JLabel("");
test game = new test();
frame.add(game);
frame.setSize(300, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
coloredLabel.setOpaque(true);
coloredLabel.setBackground(game.backgroundColor);
coloredLabel.setPreferredSize(new Dimension(1000000,1000000));
frame.getContentPane().add(coloredLabel,BorderLayout.LINE_START);
game.add(coloredLabel);
for(int a = randInt(0,9); a<10; a++)
game.newBall(randInt(0,300),randInt(0,400));
while (true) {
double height = frame.getContentPane().getSize().getHeight();
double width = frame.getContentPane().getSize().getWidth();
int n = 0;
while(game.exists(n)==true){
game.moveBall(n,width,height);
n++;
}
game.repaint();
Thread.sleep(10);
}
}
So my question is:
How do I allign the JLabel with the JFrame? so there is no space in between the JLabel and the frame.
I searched for this on this site, but couldn't find the same problem or something similar enough so I could fix this.
solved - game.setBackground(...);
The only problem is that there is a bit of the frame visable above the label,
game.add(coloredLabel);
I'm guessing "game" is a JPanel. By default a JPanel uses a FlowLayout and by default the FlowLayout has horizontal and vertical gaps of 5 pixels.
Get rid of the gap in the FlowLayout. Read the API for the constructors/methods of the FlowLayout to customize its behaviour.
But of course the bigger issue is the design of your app. I don't understand your point of using the label and attempting to take up all the space of the frame. Just set the background of the game panel by using:
game.setBackground(...);
Also class names should:
start with an upper case character and
be descriptive.
"test" is neither.

Java JFrame Boundaries

I'm trying to write a code that does the following:
If I click on the String C(JLabel) whose starting position is (100,100), the String moves WITHIN the boundaries of JFrame. The code itself wasn't hard to implement but I'm having issues with setting the (x,y) for JLabel so that any Part of the String "C" doesn't get cut off.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class adfadf extends JFrame{
JLabel text = new JLabel("C");
Container container = getContentPane();
public adfadf(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
container.setLayout(null);
MyMouseListener mml = new MyMouseListener();
text.addMouseListener(mml);
text.setLocation(100,100);
text.setSize(30,30);
add(text);
setSize(400,400);
setVisible(true);
}
public static void main(String[] args) {
new adfadf();
}
}
class MyMouseListener extends MouseAdapter{
#Override
public void mouseClicked(MouseEvent e){
JLabel text = (JLabel)e.getSource();
int x = (int)(Math.random()*(400-30));
int y = (int)(Math.random()*(400-30));
text.setLocation(x,y);
}
}
How should I change
int x = (int)(Math.random()*(400-30));
int y = (int)(Math.random()*(400-30));
in order to achieve what I want?
First, understanding that a JFrame is much more complex then it seems
To start with, a JFrame has a JRootPane, that contains the contentPane and JMenuBar and glassPane
This is further complicated by the fact the window's decorations are actually painted WITHIN the visible bounds of the frame, meaning that the visible area available to your content is actually smaller than the frame's size.
You can have a look at How can I set in the midst?, Graphics rendering in title bar and How to get the EXACT middle of a screen, even when re-sized for more details and examples of this.
But how does this help you? Well, now you know that you have a space of less than 400x400 to display your label in, but how much?
The simple solution is to stop using "magic" numbers, and take a look at something which is been used by the frame, the contentPane. The contentPane is managed by the the JFrame (via the JRootPane) so that it sits within the frame decorations, so you could do something more like...
JLabel text = (JLabel)e.getSource();
int width = getContentPane().getSize().width;
int height = getContentPane().getSize().height;
int x = (int)(Math.random()*(width-30));
int y = (int)(Math.random()*(height-30));
text.setLocation(x,y);
The reason for looking at the contentPane in this instance is simply because, that's the container that the label is actually added to.
This is one of the reasons why we suggest you don't use "magic" numbers, but look at the actual known values at the time you need them.

Java JFrame setSize doesn`t work properly

I am making a JFrame with the size of 500x500 pixels.
I make a blue background and add a red square in the right-bottom corner from (490,490) to (500,500).
Image:
I don't see the red square on the screen.
I switched the frame from not resizable to resizable and if I make the window larger the red dot is there.
Is the frame size the same as application's window size?
How can I make the application's window to be the exactly 500x500?
Your content pane should override the getPreferredSize() method, returning a Dimension object with width and height of 500 pixels:
public class MyContentPane extends JPanel {
private Dimension dimension;
public MyContentPane() {
this.dimension = new Dimension(500, 500);
}
#Override
public Dimension getPreferredSize() {
return this.dimension;
}
}
// How to use your new class
SwingUtils.invokeLater(() -> {
JFrame frame = new JFrame("Title");
frame.setContentPane(new MyContentPane());
frame.pack();
frame.setVisible(true);
});
The size of your JFrame will be calculated by Swing by taking in consideration the preferred size of the components inside it.
The frame is the size of the entire window, including the title bar required by the OS. When drawing things in the JPanel in the JFrame, the (0, 0) coordinate is in the top left corner if the JPanel, which begins just below the title bar. It sounds like your title bar is taller than 10 pixels, so 490 as a y component is actually off the window, since the visible height of the JPanel is windowHeight - titleBarHeight.
Should user the following
#Override
PreferedSize()
Remember preferedSize method is method of the super class JFrame.
this may be useful for you?
JPanel aa = new JPanel(new GridBagLayout());
aa.setMaximumSize(new Dimension(500,500));
aa.setMinimumSize(new Dimension(490,490));
aa.setBorder(BorderFactory.createLineBorder(Color.black));

How to accurately get the coordinates of a JFrame's contents?

This is my JFrame code:
public static int width = 800;
public static int height = 600;
public static void main(String[]args){
JFrame frame= new JFrame("RETRO");
frame.add(new Screen());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(width,height);
frame.setVisible(true);
frame.setResizable(false);
}
Basically when I want something to move to the edge of the screen, I have to add extra pixels for it work (I'm guessing because it includes the frame itself instead of just the display size? However the origins work fine (x=0, y=0)). Example:
public double getX(){
if(x<0)
x=0;
if(x+getImage().getWidth(null)>Game.width-6)
x=Game.width-6-getImage().getWidth(null);
return x;
}
public double getY(){
if(y<0)
y=0;
if(y+getImage().getHeight(null)>Game.height-26)
y=Game.height-26-getImage().getHeight(null);
return y;
}
Is there a way around this? I don't think the JFrame would be the same size on everyone's computer, not to mention the guesswork. Rather have it much neater and flexible by using an exiting variable from the JFrame component. Does there exist something like a frame.getDisplayWidth and Height function?
Don't set the size of the frame, set the preferred size of the contents.
Pack the frame
Get co-ordinates according to the position in the content
How do you set a 'preferred size' for the contents? I'm using a Screen class (extended JPanel) for rendering.
screen.setPreferredSize(new Dimension (600,400));
frame.setContentPane(screen);
frame.pack();
// frame will now be the size it needs to display the contents
// and the frame's own decorations (title bar etc.)
// ..now add a nice tweak.
frame.setMinimumSize(frame.getSize());
It seems you want to do something like a full screen app. JFrame's setDecorated(false) would do away with title and borders. setBounds does the sizing.
Instead of explicitly setting the size of the frame, try to set the preferred size of the content (in your case, the Screen object).
Also, just in case you need to find out the actual size of the frame decorations (title bar and borders), there is no need for guess work -- you can get this information by calling JFrame.getInsets()

drawing boxes in java

I have wrote a program that simulates memory allocation with first fit and best fit algorithms .
Now I want to associate my program with a drawing of set of boxes representing available memory segments
Before Allocation
After Allocation
So it just redraws but resizes one box and colors it ... What is the easiest way to do so ?
I have a set of boxes with different sizes that will be drawn dynamically according to input when the user does some action one of the boxes will be resized and recolored and so on.
I think this is best approached using graphics.
Instantiate a BufferedImage of a size to fit all boxes.
Get a Graphics instance by calling either of getGraphics() or createGraphics().
For each memory block:
Call Graphics.setColor(Color) according to allocation status, then..
Graphics.fillRect(int,int,int,int) or fillPolygon(Polygon) to draw the memory block.
If needed, use an AffineTransform to scale the sizes. This would require a Graphics2D object to draw on.
Use JPanel add JLabels like 0verbose but the layout to go with in my opinion is BoxLayout or GridBagLayout.
With FlowLayout you would have to make sure the size of the container is of a proper width to place one component under another, as by default it places components in a row.
From Java tutorial about FlowLayout "The FlowLayout class puts components in a row, sized at their preferred size. If the horizontal space in the container is too small to put all the components in one row, the FlowLayout class uses multiple rows."
Use a JPanel as container with vertical FlowLayout BoxLayout, and add to it a JLabel for each memory block.
If the memory blocks can be rendered all the same size, a JComponent (or even easier a JProgressBar) could be used to represent each memory block. Those could then be put into a GridLayout or BoxLayout to organize the placement. E.G.
MemoryAllocation.java
import java.awt.*;
import javax.swing.*;
import java.util.Random;
class MemoryAllocation {
public static JProgressBar getMemoryBlock(int full) {
JProgressBar progressBar = new JProgressBar(
SwingConstants.VERTICAL, 0, 100);
progressBar.setValue(full);
progressBar.setPreferredSize(new Dimension(30,20));
return progressBar;
}
public static void main(String[] args) {
SwingUtilities.invokeLater( new Runnable() {
public void run() {
JPanel memoryView = new JPanel(new GridLayout(0,10,1,1));
Random random = new Random();
for (int ii=0; ii<200; ii++) {
int amount = 100;
if (random.nextInt(5)==4) {
amount = 100-random.nextInt(75);
}
memoryView.add( getMemoryBlock(amount) );
}
JOptionPane.showMessageDialog(null, memoryView);
}
});
}
}
Screen Shot

Categories

Resources