Positioning JFrame - java

I am trying to position my JFrame to be in the center of the screen when it opens. Is there code that I can put here to make my program start in the center of the screen.
import javax.swing.JFrame;
public class StarFuryTest
{
public static void main(String[] args)
{
StarFury menuFrame = new StarFury();
menuFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
menuFrame.setSize(600,800);//Set the size of the frame
menuFrame.setVisible(true);
}
}
I am making a paint program.
Also what are the statements that turn off decorations and restricts resizing. What is the statement that enters fullscreen.

First, consider whether you really want to put your window in the center of the screen. No other application does that.
The correct thing to do is use setLocationByPlatform(true), which will allow the desktop to place your window as it sees fit.
If you feel your application is so much more important than all others that it absolutely has to be placed in the center of the screen, you can use setLocationRelativeTo(null), which is guaranteed to center the window.
Regardless of whether you call setLocationByPlatform or setLocationRelativeTo, make sure you do it before you make your window visible.

setLocationRelativeTo(null) will place the window in the center of the screen (http://docs.oracle.com/javase/7/docs/api/java/awt/Window.html#setLocationRelativeTo%28java.awt.Component%29).

Related

Full screen JFrame doesn't cover screen

I have searched for a solution to this but can't seem to find it.
If this has already been answered please link me to the answer. I am creating a JFrame setting it to full screen and changing the display mode.
This all works fine and the display mode is supported by my graphics card (I have already checked) so that is all ok. I am adding a canvas to the JFrame, creating a buffer strategy and using it to draw custom graphics to the screen. The issue is that when the display mode changes and the JFrame enters full screen mode it doesn't cover the full screen. This doesn't make sense as the display mode is 1024 x 768 and the canvas size is also 1024 x 768.
Instead the canvas sits in the top left corner of the screen in the same proportions as when the display mode wasn't changed. Furthermore, the graphics the don't draw properly. Everything works fine when I don't try to change the display mode and set full screen.
Here are the three lines of code that sets everything to full screen.
gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
gd.setFullScreenWindow(this);
gd.setDisplayMode(new DisplayMode(1024,768,32,48));
I am running windows 10 and my normal display mode is 3840x2160. Here is a screenshot of what happens when I run the code.
Although it doesnt look like it the display mode definitely changes as the screen goes black and then the screen becomes smaller and more blured.
Have you tried to maximize the window using setExtendedState? (Like in below example)
import javax.swing.JFrame;
public class MaximizedFrame
{
public static void main(String[] args)
{
JFrame frame = new JFrame("My Frame");
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
}
}

Resize code does not correspond with mouse movement

I have some code to resize a chatpanel dynamically, but it does not move according to the mouse. What happens is the mouse moves at a faster rate than the panel gets resized. For example, how I want it to be, is in any application, when you click on the border between two windows, and drag it, the mouse stays along with the piece you are clicking on, and currently this is not happening. here is my code. please let me know if you need more
public void mouseDragged(MouseEvent e) {
if(getCursor().getType() == Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR).getType()) {
owner.adjust((int)MouseInfo.getPointerInfo().getLocation().getY());
System.out.println("vertpanel: "+(int)MouseInfo.getPointerInfo().getLocation().getY());
}
}
public void adjust(int adjustment) {
int height = this.getHeight();
System.out.println((((double)(adjustment))/height)+":"+(((double)(height-adjustment))/height));
output.setHeightPercent((((double)(adjustment))/height));
output.componentResized(new ComponentEvent(this, 1));
input.setHeightPercent((((double)(height-adjustment))/height));
input.componentResized(new ComponentEvent(this, 2));
}
there is one main panel, a chatpanel, and within it, there are two smaller panels, a chat input and a chat output
Can't tell exactly what you are doing based on your code.
I would suggest that you should NOT be manually setting the dimensions of the output and input coponents. You should let the layout manager determine how to resize each component as the parent container is resized.
So in your resize code you would need to invoke revalidate() on the parent container as it is resized.
Check out Resizing Components. You should be able to use the ComponentResizer class as long as you use setAutoLayout(true).

Can you put JFrames inside Full Screen Exclusive Mode?

To be honest, I didn't quite know how to express my question in the title. So if someone has a clearer idea of what i'm trying to ask, then please be so kind as to edit it, for the greater good of mankind.
I have the following code:
public class Main {
public static void main(String[] args) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
JFrame frame = new JFrame();
Window window = new Window(frame);
JButton btn = new JButton("Quit");
window.add(btn);
if(gd.isFullScreenSupported())
gd.setFullScreenWindow(window);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
gd.setFullScreenWindow(null);
}
});
}
}
What I want to do is make a library system, illustrated in full screen mode. Inside the full screen mode, there should be simple frame windows with text fields in them and so on... No heavy 2D/3D graphics required here...
My problem is, the quit button is resized to fit the entire screen. I've tried to use setBounds, setSize, etc, on the frame, window and even button... But it doesn't seem to let me be able to center the button in the middle.
So my question: Is it possible to make JFrame application windows inside a JFrame application window which is set to full screen exclusive mode? Or is it only possible to use full screen exclusive mode together with 2D/3D methods like drawing?
Note: The only thing I intend to use full screen mode for is to set it to a black background, and have a Jframe window ontop of this black background in the center of the application. It is to give the illusion that the application is actually a system.
Thank you.
P.S. please note that the quit button was merely for my own testing purposes. It won't be part of the actual system, so my question does not revolve around how to resize this particular quit button.
Fullscreen Exclusive Mode is not meant to have Swing components inside. It is meant as a high performance way to draw graphics in Java (and can benefit as much as possible of underlaying hardware if done right).
What you want to do could be done by using an undecorated JDesktopPane and maximize it over the dimensions of the screen. Then proceed with using a JInternalFrame to have a JFrame like window inside that JDesktopPane.
I've included links to the respective API sections, they should get you started.
I think that what you are after is an MDI Application. If that is what you are after you could take a look here.
Your problem is that you do not use layout manager correctly.
Learn about layout managers - the modules that put and size/resize the visual components on screen. Then decide how do you want your button to look like and then decide which layout manager to use. It will do its job.
You know what i also had the exact same problem and the only thing i know from my experience is that you can use jinternal frame and set its property undecorated to true then add your custom title bar according to your requirement.

Changing The Underlying Background Color Of A Swing Window

As discussed here, when resizing a Swing application in Vista (and Windows 7, which is what I'm using) you get a black background in the right/bottom corner while Swing's repaint catches up to the changes.
Playing with other applications (Windows Explorer (Native), Firefox (C++?), and Eclipse (Java)) I notice that they all have this same problem - contrary to what the folks in the link above say - but they minimize the problem by having a grey fill color, which is far less visually jarring than the black that appears in Swing.
I'm wondering if there's some way to change this so that Swing behaves like these other applications? I tried setting the background color of the JFrame, but to no avail.
Additional Info
Jonas discovered (see their informative answer below) that this is an issue with JFrames, but not AWT Frames - maybe that will help someone figure this out.
I have noticed the same problem. This color is gray at IE, in Opera it's black, and in Eclipse it's gray. It seam to be more visible in Swing, because it seam to be little slower at repainting and the color is as you said, black. This problem is more visible if you use the upper left corner to resize.
I coded an example and tried to understand where this black color is defined. A JFrame has many layers, so I set a different background on every layer.
import java.awt.Color;
import javax.swing.JFrame;
public class BFrame {
public static void main(String[] args) {
new JFrame() {{
super.setBackground(Color.CYAN);
this.getRootPane().setBackground(Color.BLUE);
this.getLayeredPane().setBackground(Color.RED);
this.getContentPane().setBackground(Color.YELLOW);
this.setSize(400,340);
this.setVisible(true);
}};
}
}
But this example didn't help. And maybe the color is set by a superclass to Frame.
java.lang.Object
java.awt.Component
java.awt.Container
java.awt.Window
java.awt.Frame
My teory is that, since Swing paints itself, but uses a native Window, then is the native background painted before the resize, and the background of Swing is painted after the resize. But for native applications, the background is painted before the resize.
UPDATE: I tried with a Frame now, and it's not having the same problem. The background seam to be painted before the resize.
import java.awt.Color;
import java.awt.Frame;
public class B2Frame extends Frame {
public static void main(String[] args) {
new Frame() {{
setBackground(Color.YELLOW);
setSize(400,340);
setVisible(true);
}};
}
}
The frame is responsible for painting its background so you need to make sure you let it do its job.
You demonstrate this by setting:
System.setProperty("sun.awt.noerasebackground", "true");
This will cause the background to always be black on resize expansions. (So don't do it.)
The following worked for me:
(AWT only) Set up double buffering using createBufferStrategy(2) - wrapped in addNotify() otherwise you'll run into exceptions during Frame creation
(Step 1 is only necessary in AWT as Swing is double buffered by default.)
Always (important) call super() in your Frame.paint() implementation
Set the background colour with setBackground() then the background should always be the same colour when expanding the frame
Sample code:
class InnerFrame extends Frame {
public void addNotify() {
super.addNotify();
// Buffer
createBufferStrategy(2);
strategy = getBufferStrategy();
}
public void paint(Graphics g) {
super(g);
//...
}
//...
}
I also noticed this. For me this issue was solved with changing layout manager (I've used Free Form Layout before) and it worked pretty well (system color painting).
But eventually I switched back to FFL. Also some well known apps face this problem (f.e. SKYPE), but I actually don't mind it ...

How would you make a frame visible if the mouse is inside it and invisible when it's not in Java?

So if I was writing pseudo code:
if(mouseInsideFrame==true)
frame.setVisible(true);
else
frame.setVisible(false);
What method would I use for the mouseInsideFrame in the if statement?
Thanks
I came across a post on java.net that covers visibility options, including this one using a private AWT API.
public class TransparentFrame {
private static final float OPAQUE = 1.0f;
private static final float TRANSLUCENT = 0.1f;
public static void main(String[] args) {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 400);
frame.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
com.sun.awt.AWTUtilities.setWindowOpacity(frame, OPAQUE);
}
#Override
public void mouseExited(MouseEvent e) {
com.sun.awt.AWTUtilities.setWindowOpacity(frame, TRANSLUCENT);
}
});
frame.setVisible(true);
}
}
This is OK for toy code, but obviously I wouldn't use a private com.sun class for portable production code.
Update: Same method as before, but with more explicit step-by-step explanation.
Other respondents wonder what you want to achieve with this and question the design behind an app that unexpectedly jumps up at the user. I guess it's a matter of how dead set you are to implement this functionality exactly as you described. The technique itself may be useful for other purposes too, which is my main motivation for my new, improved revision of this answer.
As far as I know, a frame that's not visible can't capture mouse events. So it won't know if the mouse is inside it or not.
There's a loophole around this problem: If you make your frame visible but borderless and fully transparent, it will be visible in the technical sense but invisible to the user for practical purposes.
The borderless part is easy: setUndecorated(true).
It would be great if JFrame had a method like setOpaque() or setTranslucent() where you could make it fully transparent, but alas, it doesn't.
Another answer mentions a solution based on a Sun private class which does permit you to make the window transparent. This will work for current and probably near-future Sun JREs but is far from guaranteed to work with other and future JREs, so I can't recommend it. Sun expliticly advises against using their private classes this way.
There's an alternate, somewhat hacky alternative: The frame is left fully visible but it displays the image of a screenshot of the screen behind it. Because this means we're effectively looking through the frame, it's effectively invisible. This solution is described here: http://onjava.com/pub/a/onjava/excerpt/swinghks_hack41/index.html?CMP=OTC-FP2116136014 . The author and I both admit to this being a a bit clumsy; it also involves a lot more code than should be necessary. But it's based on standard Java coding and should be supported unchanged in many Java environments upward of about version 1.4 or so.
The tip describes how to create a Component that displays the screen background. That's fine for when you want the frame to be invisible, but what happens when you want it to be normally visible?
The thing to do is to give the JFrame's ContentPane a CardLayout and add both the TransparentBackground component and your intended main visible component (likely a JPanel) to it. With that set up, switching between "invisible" and visible involves simply:
setUndecorated(false) // (true)
cardLayout.last() // (first)
This switching, of course, will be controlled by a MouseListener you can add to the JFrame.
Out of the top of my head, there is a fairly easy way to get the position of the mouse on the screen (I think it has something to do with Toolkit). Now, if you can combine that with a way to find out your frame's position on the screen (if you don't already know), you have your solution.
I'm curious what you're trying to do though.
Given what you are trying to do, I would say you need two frames (or perhaps just JPanels and frame that does a lot of changing. One is to capture the mouse moving over it (make it transparent, undecorated or otherwise acceptably out of the way) and when the mouse moves over it, show the new frame (or panel) and then hide that when the mouse moves out of it.
The other answers here give you the basics on how to capture the mouse events and set the frame undecorated and transparent.
Normally you could use listeners. Specifically:
frame.addMouseListener(new MouseListener() {
public void mouseEntered(MouseEvent evt) {
frame.setVisible(true);
}
public void mouseExited(MouseEvent evt) {
frame.setVisible(false);
}
});
But the problem is that since your JFrame is not visible, there is no way to listen to mouse events!!!! At least, from what I know....

Categories

Resources