JFrame freezes on Windows 8.1 when resized - java

Also posted on coderanch.com.
import javax.swing.*;
public class Tmp {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JTextField());
frame.setVisible(true);
}
});
}
}
A problem regarding resizing this JFrame.
This is how it looks by default right after program starts:
When I try to resize it like shown on a picture and move a mouse pointer to the top of a screen (like on picture below) I see this:
When I release the mouse the frame is resized but unresponsive. And there is a black space on it.
This is how it looks:
This happens on Windows 8.1 and java 1.7.0_45 (it also happens on Windows 7).
The problem does not occur when using other ways of resizing a frame in Windows.
It only happens when "Show window contents while dragging" is active in system settings.
Why is it happening?
How can this be fixed?

This sounds a lot like the bug reported here. Supposed to be fixed in JDK8 and 9, and according to the issue tracker the bug fix is backported into version 7u80.

i have windows 7 with jdk1.7.0_25 and your code worked as fine for me
i have 3 solution :
1-i think Oracle is wrong in update of 45 you can replaced 45 with 25
2-any graphical user interface in java uses from OS and maybe windows 8 not compatible with java 7 yet
3-you can add a listener for frame resize and call repaint(); in body of listener or set size to actual size
also you can try to using setUndecorated(true) and custom mouse listener which implements frame resize

Related

Components of JFrame are only in correct position after resize (sometimes)

there is this JFrame containg a JPanel containing a processing sketch. The code looks something like this:
import javax.swing.JFrame;
import javax.swing.JPanel;
import processing.core.PApplet;
public class TestCase {
public static void main(String[] args) {
ProcessingFrame pFrame = new ProcessingFrame();
pFrame.setVisible(true);
}
}
#SuppressWarnings("serial")
public class ProcessingFrame extends JFrame{
public ProcessingFrame(){
this.setSize(600, 400);
this.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
ProcessingSketch pSketch = new ProcessingSketch();
panel.add(pSketch);
this.add(panel);
pSketch.init();
this.setVisible(true);
}
}
public class ProcessingSketch extends PApplet{
public ProcessingSketch(){
//...
}
public void setup(){
size(600, 400);
background(200);
}
public void draw(){
rect(250,100,100,200);
}
}
Too often (about 50%) the panel and/or sketch is not rendered to the appropriate location. Sometimes they are just about half of the frame size off to the right, sometimes I see just the bottom of the sketch in the frame.
After I resize the frame with the mouse, everything looks fine. I would like to set the JFrame to undecorated, but there is no way to resize the windows to put everything into place.
This is what I tried to solve that:
JFrame.repaint() as suggested here: Java items appear only after the window is resize. - No effect.
I thought i could just resize the window by hand and then change to undecorated. Following the answer of this question: Modifying a JFrame from within a Listener. But the processing sketch crashes because I have to dispose the JFrame.
Any other ideas?
This sounds like a threading issue. Processing uses its own animation thread, so I'm not really surprised you're having issues, and I'm not really surprised they're sporadic. That's the nature of threads.
In fact, the latest version of Processing removed the ability to add a Processing sketch to a Swing application like this. If you really want to fix this problem, you should update to the latest version of Processing and use it as a Java library. That's more work, but it's more "correct" than continuing with this old way.
But since I know that's not what you want to hear, the first thing I would try is calling the JFrame.revalidate() function. You have to do this after the Processing sketch has been initialized, which might be tricky with the aforementioned threading issues. You might have to put that in a delay of some kind, or maybe do it from the setup() function.
If that doesn't work, you could try programatically resizing your JFrame after some delay. That's pretty hackish, but again, the "correct" way to proceed is to update your Processing and stop embedding it the old way.

Java how to make JFrames start off as a maximised window

I want to know how to make a java JFrame start out maximised. I don't want it to be fullscreen (no window around it) I just want it to start out like a normal program such as a web browser.
I already know about using:
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
To get the screen size, but when you apply this Dimension to the JFrame it can still be dragged around even though it takes up almost all of the screen. You can press the maximse button to stop this but I would rather that the window started out maximised.
Also, I fear for the effects that maximising the window would have upon the contents of the window.
How do I go about doing this?
Use java.awt.Frame.setExtendedState():
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
}

How to make a window smaller than 125 x 50 in Java?

I'm trying to create a 50x50 window in Java but the window won't go smaller than 125x50, even if I try to manually resize it.
Here's my code currently:
import javax.swing.*;
public class smallwindow {
public static void main(String args[]) {
JFrame frame = new JFrame("");
frame.setSize(50, 50);
frame.setVisible(true);
}
}
I am running this with the latest version of Java on Mac OS X.
Is there any way to do this with a JFrame, or would I need to use something else, like maybe AWT?
**edit: is there a way to do this while retaining the titlebar, window management buttons, etc.?
You would have to do the following on the JFrame:
frame.setUndecorated(true);
Guys, I did a little more looking into it, apparently there is a method called setMinimumSize
Basically, all you need to do is add
Dimension minimumSize = new Dimension(50, 50);
frame.setMinimumSize(minimumSize);`
I've found that if the size is less than about 75x75, then resizing it will suddenly change the minimum width to around 75. The solution is to just to do frame.setResizable(false)
But anyways, thanks for all your help!
but is there anyway to do this such that you still retain the tilebar, window management buttons, etc.?
You can use the Metal LAF which includes the title bar:
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame(...);

Disable default ALT key action in JFrame under Windows

I would like to let my JFrame under Windows not act upon an ALT key press. To clarify, when you execute the following snippet of code:
import javax.swing.*;
public class FrameTest {
public static void main(String[] args) throws Exception {
JFrame frame = new JFrame();
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
and press the ALT key and then the arrow down key, you get a menu in the upper left corner in which you can choose to minimize, move, close etc. the frame (at least I get that). I would like to disable this: ie. the JFrame should not "listen" to these ALT presses.
I believe that certain Windows components react by default on the ALT key because when I add a menu bar to my frame, and explicitly set the look & feel to the system look & feel, the menu (File) is now automatically selected after pressing the ALT key:
import javax.swing.*;
public class FrameTest {
public static void main(String[] args) throws Exception {
JFrame frame = new JFrame();
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
menuBar.add(menu);
frame.setJMenuBar(menuBar);
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); // set Windows look and feel
frame.setVisible(true);
}
}
and when I remove UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) from the example above, this behaviour is not exhibited when pressing the ALT key: the menu is not selected, but the JFrame is.
When no look & feel is set, the "Metal" look and feel is used. It is clear by looking at the menu bar in my previous example that you go from "native look" to "Metal look" when you remove UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) from the code. However, I don't see a change in the JFrame, no matter what look & feel I set, it always looks like a native Windows frame.
So, my question is: how can I disable this ALT behaviour on my JFrame? I guess I can do it by actually changing the look and feel of the JFrame. Is that possible? If so, how?
Thanks!
Just for history:
You can do this. Window manger handles all the events to the current keyboard focus manager and it decides what to do with the particular key. Every swing application has only one keyboard focus manager that's why your changes will affect the whole application and not the particular frame. The code below should do the trick:
frame.addFocusListener(new FocusListener() {
private final KeyEventDispatcher altDisabler = new KeyEventDispatcher() {
#Override
public boolean dispatchKeyEvent(KeyEvent e) {
return e.getKeyCode() == 18;
}
};
#Override
public void focusGained(FocusEvent e) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(altDisabler);
}
#Override
public void focusLost(FocusEvent e) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(altDisabler);
}
});
Actually, what you are seeing here is pretty much outside your nice, Swing-y Java world. The window frame (except for MDI interfaces) will always be drawn by the window manager of the underlying operating system. And that's also the reason why the Alt key behaves like you observe. This key is intercepted by the WM in this case and it decides that you want to bring up the system menu of the program. That's totally unrelated to Java.
For several reasons you can't change the "look and feel" of the window frame, the main one being that this is outside Swing's PLAF system. You can remove the window frame, leaving behind a naked window (freezing in the cold November wind), then you also shouldn't get a system menu anymore.
Furthermore you could try handling the Alt keypress and not delegating that very keypress further (the application gets it before the WM does, so you can mess with these things). My Java-Fu is a little rusty right now, though, so no idea if and how this can be achieved.
It sounds like you're hitting upon some default interactions with the Windows window manager. It is possible that if you draw your own titlebar and borders that Windows will no longer set these default handlers on the Alt key.
You might want to try Substance, which gives you much more control over these sorts of things, while still working with the standard Swing components.
Or, try this before you make your frame visible:
JFrame.setDefaultLookAndFeelDecorated(true);

GUI objects not showing in Java on Mac

I've only just begun writing GUI programs, this being my second one. With both projects (both homework assignments) I have had the same issue. The GUI objects (such as JTextField) do not show when the application runs until after I resize the window or move keyboard focus to them. If I do not do one of those two things, then I'll just have an empty application window.
Any ideas why this is happening and what I could do to solve it? I'm working on Mac OS 10.6.1.
My code is below. Feel free to comment on my coding style, but please focus on the problem I'm having.
import javax.swing.*;
import java.awt.*;
public class ToDo extends JFrame {
private int height = 30,
width = 300;
public ToDo() {
this.setSize(400,400);
this.setVisible(true);
this.setLayout(null);
this.setResizable(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("To Do List");
JTextField todoItem[] = new JTextField [10];
Container contentpane = this.getContentPane();
contentpane.setLayout(null);
for(int i=0; i<10; i++) {
todoItem[i] = new JTextField();
todoItem[i].setBounds(10,(height*(i)+10),width,height);
contentpane.add(todoItem[i]);
}
}
public static void main(String[] args) {
new ToDo();
}
}
You have to add the elements before the component is made visible.
Put this as your last line:
this.setVisible(true);
alt text http://img10.imageshack.us/img10/8210/capturadepantalla200911s.png
This is not OSX related, it happens in Windows also.
There are some rules about how you should never touch Swing objects from outside the Swing thread once they've been realized. I always ignore these rules, but it could well be you've been bitten by them under Mac OS.
As a step in the officially right direction, try to not do setVisible() until you've assembled the whole thing, i.e. at the bottom of the constructor.
Reference material: http://www.math.vu.nl/~eliens/documents/java/tutorial/ui/swing/threads.html
A guess: add the component before setBoundsing it.
I could be wrong--been a long time since I've done a GUI in java--but I'm guessing your issue is making the JFrame visible before you finish adding elements. I think you need to either do that afterwards, or call update on the frame.
EDIT - Also, not sure setting the layout to null is a good idea. I've always used GridBag, but it might lose its default if you set it to null.

Categories