JInternalFrame acts weird when windows theme changed? - java

This is my sample code. I am trying to embed a JInternalFrame without titlebar display into a JFrame.
import javax.swing.*;
import javax.swing.plaf.basic.BasicInternalFrameUI;
class A{
public void doThis(){
JFrame fr = new JFrame();
fr.setSize(300,300);
JInternalFrame f = new JInternalFrame();
f.setSize(200,200);
BasicInternalFrameUI ui = (BasicInternalFrameUI) f.getUI();
ui.setNorthPane(null);
f.setVisible(true);
fr.add(f);
fr.setVisible(true);
}
}
class MainA{
public static void main(String a[]){
A obj = new A();
obj.doThis();
}
}
The code works fine and displays a JInternalFrame within a JFrame without titlebar as per the requirement as shown below.
I still have this UI running and at the same time when I try to change my XP theme (via Properties>>Appearance>>Theme), the UI automatically repaints itself to show the JInternalFrame with a titlebar again as shown below.
I just can't understand this bizarre behavior. I have no clue if this is an issue with Java Swing or if it is something related to the OS. Please help me with this!
Why is the UI repainting upon theme change with an enabled titlebar when I explicitly code for the titleBar to be set as null?
PS: OS used is Windows XP and I am not sure if the same behavior is observed in Linux or other versions of Windows

'do' is a keyword in Java, so that code does not compile for me. This code does.
import javax.swing.*;
import javax.swing.plaf.basic.BasicInternalFrameUI;
class A{
public void doIt(){
JFrame fr = new JFrame();
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fr.setSize(300,300);
JInternalFrame f = new JInternalFrame();
f.setSize(200,200);
fr.add(f);
BasicInternalFrameUI ui = (BasicInternalFrameUI) f.getUI();
ui.setNorthPane(null);
f.setVisible(true);
fr.setVisible(true);
}
public static void main(String a[]){
A obj = new A();
obj.doIt();
}
}
Some notes/questions:
Swing GUIs should be constructed & altered on the EDT.
Why does the code add a JInternalFrame directly to anything other than a JDesktopPane?
There are slight issues with sizing of the JInternalFrame when changing themes. I suspect it has to do with the lack of validate()/pack() in the code. Since that was not the question, I could not be bothered investigating it further.
Results
I got a 'null result' here using Windows 7. The title bar of the JInternalFrame did not re-appear at any time when changing through (in order):
Forbidden Planet (a custom, simple theme)
Windows 7 (Aero)
Architecture (Aero)
Windows 7 Basic (Basic & High Contrast)
Windows Classic (Basic & High Contrast)
Forbidden Planet

Related

Windows disappearing behind a full screen undecorated JFrame

I have a JFrame which I am setting to be full screen like so:
JFrame frame = new JFrame();
frame.setSize(1920, 1080); // Resolution of the monitor
frame.setUndecorated(true);
frame.setVisible(true);
Problem is, any popups (e.g. JDialogs) spawned from this frame open up behind the frame and I can only access them by alt-tabbing to them.
Furthermore, I am running a two monitor setup with each monitor treated as a separate display. If any windows are opened on top of the JFrame, and I move my mouse cursor to the second monitor, the windows disappear behind the JFrame. This is on RHEL 6.4, so perhaps it's a Linux window management issue? It should also be noted that I am running without gnome-panel, so it's a completely bare Linux desktop (no menu bar, no task bar).
Things behave normally when my JFrame is decorated. That is, pop ups open on top of it and windows no longer disappear behind it when I move my mouse cursor to the second monitor.
It's only when I set the JFrame to be undecorated and full screen that windows start getting lost behind it. It's like Linux is "locking" the undecorated JFrame to the monitor. I can't alt-drag it in this state either.
If I set the JFrame to be slightly smaller than the monitor resolution (e.g. 1 pixel smaller), then it is no longer "locked". I can alt-drag it and windows no longer get lost behind it.
Is there any way to prevent windows from getting lost behind the full screen, undecorated JFrame?
I've tried all solutions listed here, but none of them work:
JFrame full screen focusing .
EDIT
The above problem happens when running under Java 7. Running under Java 8 fixes the dialog issue, but the screen crossing issue is still there.
Use the below code to solve the above mentioned issue
public static void setfullscreen(final JFrame frm)
{
frm.dispose();
/**`enter code here`
* Set the Frame as Undecorated
*/
frm.setUndecorated(true);
/**
* set the Frame's resize property as false
*/
frm.setResizable(false);
frm.requestFocus();
/**
* sets the frame as visible
*/
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
frm.setVisible(true);
}
}
);
Dimension screenSize =
Toolkit.getDefaultToolkit().getScreenSize();
frm.setBounds(0,0,screenSize.width, screenSize.height);
}
/**
* Close the Full Screen Mode
* #param frm
*/
public static void closeFullScreen(final JFrame frm)
{
frm.dispose();
frm.setUndecorated(false);
/**
* sets the frame as resize
*/
frm.setResizable(true);
/**
* sets the frame as visible
*/
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
frm.setVisible(true);
}
}
);
}
</i>

JFileChooser inside a JFrame makes setVisible() freeze

I have an assignment to show JFileChooser as part of a JFrame. So showing it as a dialog box is out.
I'm doing the most basic approach to adding it as a component to a yet invisible frame, and then the setVisible() call freezes instead of showing the frame.
What irks me the most is that one time out of ten the frame appears with the FileChooser just fine. This makes me think this is a concurrency issue.
Here's the minimal source code that still has the issue.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
class ApplicationFrame extends JFrame {
JFileChooser fileChooser;
public ApplicationFrame(String frameName) {
super(frameName);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
fileChooser = new JFileChooser();
fileChooser.setControlButtonsAreShown(false);
panel.add(fileChooser, BorderLayout.CENTER);
getContentPane().add(panel);
}
}
public class lab7{
public static void main(String args[])
{
ApplicationFrame windowForApplication = new ApplicationFrame("lab7");
windowForApplication.setSize(600,600);
windowForApplication.setVisible(true);
}
}
If you put a println after the final setVisible, it doesn't get called.
If you comment out panel.add(), the frame displays just fine.
What else should I do to display the file chooser?
What irks me the most is that one time out of ten the frame appears with the FileChooser just fine.
All Swing component should be created on the Event Dispatch Thread. So the GUI creating code should be wrapped in a SwingUtilities.invokeLater(...).
Read the section from the Swing tutorial on Concurrency for more information and an example of how this is done.
Your code (as is) actually works for me without problem. I'm using JDK7 on Windows 7, so it could be a version/platform issue. Again make sure the code executes on the EDT.
Also, class names ("lab7") should start with an upper case character. Doesn't matter if this is a SSCCE or not, be consistent.

How do you add a jFrame to your main class in Netbeans?

So I have made a Jframe with a lot of elements and buttons and things in it, but I am new to using NetBeans. Upon creating the java application a main class.java was created and upon adding the jframe another jframe.java was created. How do I get the main class to open, read, and run my jframe.java? I can upload the specific code if need be.
Thanks in advance
To call a certain method from another class, you must first create a new object for that class, like this:
Jframe frame = new Jframe();
frame.setVisible(true); //or whatever the method is in jframe.class
Maybe rename the actual class name from jframe to something like frameone. I've heard that naming classes the same as classes in the Java API will cause trouble.
Or, you could put it all in one class, with either two separate methods or put it all in the main method. If this doesn't help, then please paste the exact code on pastebin.org and give a link.
Look at this sample example and learn how to set frame visible
import java.awt.*;
import javax.swing.*;
public class exp{
public static void main(String args[]){
JFrame jf=new JFrame("This is JFrame");
JPanel h=new JPanel();
h.setSize(100,100);
h.add(new JButton("Button"));
h.add(new JLabel("this is JLabel"));
h.setBackground(Color.RED);
jf.add(h);
jf.pack();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
}
}
Useful Links
Designing a Swing GUI in NetBeans IDE
Creating a GUI With Swing (As #MadProgrammer Commented)
Learning Swing with the NetBeans IDE
I'm new to this, but I got a form up. Woo hoo!
1) The project created my main function in japp1.java
2) I created a JFrame, file jfMain.java
3) While there was probably a way to reference it as it was, I didn't see how right away, so I moved it to a peer level with the japp1 file, both in a folder called japp1 which will cause them to get built together, having the same parent reference available.
src\
japp1\
japp1.java
jfMain.java
4) Then instead of creating a generic JFrame with a title, I created an instance of my class...
5) I gave it a size...
7) Then showed it...
public static void main(String[] args) {
// TODO code application logic here
JFrame frame = new japp1.jfMain();
frame.setPreferredSize(new Dimension(700, 500));
frame.pack();
frame.setVisible(true);
}
I had already put some code in my jframe... to show a messagedialog with JOptionPane from a mouseclick event on a button and set some text for some textfields.
Hope that helps.

Focus issues with java7 modal dialogs on mac osx

I've been validating a swing application that runs on an applet for mac osx.
During this validation I found the following issues with the modal dialogs:
When a dialog is open and is setModal(true) it blocks the content of the root window, but if you click somewhere on the root window, the dialog goes under it, but it should remain on the top of the root window.
If the dialog has a JTextInputField it does not receive focus even when you click on it.
So I created a small program to show the problem. Can you please help me to understand what is wrong here?
package com.macosx.tests;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class DialogExample extends JApplet{
private static final long serialVersionUID = 1L;
private JPanel panel;
private JButton openDialogBtn;
private void doStart() {
panel = new JPanel();
panel.setPreferredSize(new Dimension(500,500));
openDialogBtn = new JButton("open dialog");
openDialogBtn.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
ModalDialog dialog = new ModalDialog(panel, true);
dialog.setVisible(true);
}
});
panel.add(openDialogBtn);
setContentPane(panel);
}
class ModalDialog extends JDialog {
private static final long serialVersionUID = 1L;
public ModalDialog(Component parent, boolean modal) {
Dimension dimensionParentFrame = parent.getSize();
setSize(new Dimension((parent == null) ? 300 : dimensionParentFrame.width / 2, 75));
setModal(modal);
setModalityType(ModalityType.APPLICATION_MODAL);
JTextField txtField = new JTextField();
add(txtField, BorderLayout.CENTER);
}
}
#Override
public void start() {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
doStart();
}
});
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Use the above to create a .jar file (test.jar). Once that is done, create a html file with the following content:
<html>
<head>
<title>Dialog test Applet</title>
</head>
<body>
<applet id="DialogTestApplet" height="800" width="600"
code="com.macosx.tests.DialogExample"
archive="test.jar">
</applet>
</div>
</body>
</html>
When this is done, run the html file. You'll see an applet with a gray background and with a button. Then try to:
click on the button to open the dialog. After that, click somewhere on the gray area: the dialog goes under the browser window but it should remain on the top, right?
click on the button to open the dialog. After that click on the textfield of the dialog and try to write something: the textdialog does not receive focus.
So, what am I doing wrong here? Can someone with a mac computer test this please?
Thanks
Specs:
java.vendor Oracle Corporation
java.version 1.7.0_07
os.name Mac OS X
os.version 10.7.4
browser firefox 15
NOTE: please note that this is only happening when the applet runs on the browser and only on mac osx.
I found another workaround. When the window is opened, show an optionpane for a few milliseconds and close it. It give the focus to the optionpane and then back to the dialog, allowing to ignore the bug.
Add this snipet of code to your dialog constructor and it should work:
addWindowListener(new WindowAdapter(){
public void windowOpened(WindowEvent e){
JOptionPane pane = new JOptionPane();
final JDialog dialog = pane.createDialog("Please Wait");
Timer timer = new Timer(50, new ActionListener() {
public void actionPerformed(ActionEvent e) {
dialog.dispose();
}
});
timer.setRepeats(false);
timer.start();
dialog.setVisible(true);
}
You should put an "owner" window on your ModalDialog. To do that, you must call super(owner) in your ModalDialog constructor and you can retrieve the parent window of your component parent with SwingUtilities.getWindowAncestor(parent).
not Mac/OSX user but this is common issue about Focus and JDialog,
there are another issues in the case that JDialog is created on Runtime,
Focus is asynchronous based on properties came from Native OS
create this JDialog only once time and re_use this container for another action
JDialog#setVisible should be wrapped into invokeLater() too
is possible to force the Focus by JTextField#setText(JTextField#getText()) wrapped into invokeLater()
there is Dialog Focus, one of great workaround by #camickr
I confirm, I have the same bug with an old applet running in JDK7 on OS X. As the poster mentioned, the bug is seen only with the applet running in the browser (ff) and not with the appletviewer.
I can verify that this is a problem for Java 1.7 Update 7+ on the Safari 6 and Firefox running on Mountain Lion. Curiously it is not a problem on earlier versions of Safari that run on Lion but it is a problem in Firefox on the older OS. I am pretty desperate to find a fix for this as a number of my applet users are on Macs. One workaround that I have found (that is not sufficient by any means) is to minify the window and then reopen it. The textfields/textareas then become editable. Hopefully, we can find a better solution that gets around this annoying requirement.
I experienced the same problem on Mac with Java 7 update 9 with Safari and Firefox. When I opened a JDialog which contained a JTextField the JTextField was inaccessible.
I did find a solution. I inserted a delay from when the user pressed the “show dialog button” to executing the code that shows the button.
For example:
ActionListener al = new ActionListener(){
public void actionPerformed(ActionEvent ae){
TitleDialog dialog = new TitleDialog(main.findParentFrame()); // My JDialog which contains a JTextField.
dialog.setVisible(true);
}
};
javax.swing.Timer timer = new javax.swing.Timer(1000, al);
timer.setRepeats(false);
timer.start();
I experienced that if the delay was to short the solution would not work.
If one uses SwingUtilities.invokeLater instead of javax.swing.Timer it will not work. Maybe the delay of SwingUtilities.invokeLater is too short.
I found one more workaround. When JDialog is invoked from JavaScript it has a focus.
Create an applet's method which will show a dialog
Call this method from JavaScript.
Hope, it helps. By the way, web start samples from Java tutorial have the same issue http://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html
I want to use the workaround above (to open dialog from the dialog), but without showing any dialog.
Here is a code for not visible dialog.
final JDialog dialog = new JDialog();
dialog.setUndecorated(true);
dialog.setSize(0, 0);
dialog.setModal(true);
dialog.pack();
I have found a solution.
GetDirectory varGetDirectory = new GetDirectory(new JFrame(),true);
varGetDirectory.setVisible(true);
GetDirectory is JDialog containing a JFileChooser.
The weird thing is that all JDialog object should be called using new JFrame() as parent, otherwise clicking from one parent window, will bring the top modal JDialog backwards in the zOrder and somehow it cannot be set on top anymore.
My problem was the same as above. When I have created the JDialog from another JDialog, the new dialog appeared behind the other.
To bring it to top I have set the parent of all JDialogs as described above and it worked according to what expected.

How does NetBeans' Splash Screen feature work?

New to NetBeans and just noticed that in the File >> Project Properties >> Application dialog there is a text field labeled Splash Screen that allows you to specify a path to an image that you would like displayed when your program is launching.
I want to customize the way my splash screen works (adding a progress bar, etc.) and would like to code it from the ground up but don't know where to start. What are the best practices for Java/Swing-based splash screens?
Thanks for any and all input!
The project properties -> Application -> Splash Screen allows you to add an image to an application. This property sets a value in the MANIFEST.MF called SplashScreen-Image: e.g. SplashScreen-Image: META-INF/GlassFish316x159.jpg This property will automatically cause the image to display as a splash screen. It does not work inside NetBeans, and must be run outside the IDE.
There is a tutorial Splash Screen Beginner Tutorial that details how to use it more detail. The tutorial was done for NetBeans 6.8, but will work on 7.2.1 which is the latest at the time of this post.
I'm not sure how NetBeans does it, but Splash Screens are supported by the JRE since version 6. See http://java.sun.com/developer/technicalArticles/J2SE/Desktop/javase6/splashscreen/
Splash screen is just a instance of java.awt.Window or undecorated javax.swing.JFrame.
To create window just say new Window(null), then set size and position (using tookit you can calculate where the screen center is) and then say window.setVisible(true)
Due to this is your own window you can do what you want: set layout, image, add process bar to the SOUTH etc.
You can also use JFrame: new JFrame().setUndecorated(true)`
There are a couple of ways to do this.
To do a simple splash screen (an image) you can specify this in the command line of you java application.
Here is a simple example
java -splash:<file name> <class name>
However, if you want a progress bar, you are going to have to do something a little more complicated, and write some code yourself. This is done in the following way.
Create a JWindow (or Window or undecorated JFrame) component with your splash screen elements
Set it to visible
Do the rest of your Swing GUI startup code
Set your JFrame to visible, then immediately follow with setting the JWindow to visible(false)
This should show the splash almost immediately, and then hide once the your application is fully loaded.
To see some splash screen code, take a look here. The implementation in the link only shows how to achieve what you can with the -splash command, but it will give you a good start to also include the progress bar that you requested.
I hope this helps you, it is a small example of how to create yourself a simple splash screen using a dummy Progress Bar:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class SplashScreen extends JWindow
{
private static JProgressBar progressBar = new JProgressBar();
private static SplashScreen execute;
private static int count;
private static Timer timer1;
public SplashScreen()
{
Container container = getContentPane();
container.setLayout(null);
JPanel panel = new JPanel();
panel.setBorder(new javax.swing.border.EtchedBorder());
panel.setBackground(new Color(255,255,255));
panel.setBounds(10,10,348,150);
panel.setLayout(null);
container.add(panel);
JLabel label = new JLabel("Hello World!");
label.setFont(new Font("Verdana",Font.BOLD,14));
label.setBounds(85,25,280,30);
panel.add(label);
progressBar.setMaximum(50);
progressBar.setBounds(55, 180, 250, 15);
container.add(progressBar);
loadProgressBar();
setSize(370,215);
setLocationRelativeTo(null);
setVisible(true);
}
public void loadProgressBar()
{
ActionListener al = new ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt)
{
count++;
progressBar.setValue(count);
if (count == 50){
timer1.stop();
execute.setVisible(false);
//load the rest of your application
}
}};
timer1 = new Timer(50, al);
timer1.start();
}
public static void main (String args[]){
execute = new SplashScreen();
}
}
Cheers!
Also consider to build your application on top of the NetBeans Platform (a Swing-based RCP). One of the many benefits: it comes with a customizable splash screen with progress bar.
Sample progress bar:
http://platform.netbeans.org/tutorials/nbm-paintapp.html#wrappingUp
Port a Swing application to the NetBeans Platform:
http://platform.netbeans.org/tutorials/60/nbm-porting-basic.html
Further links:
http://netbeans.org/features/platform/index.html
http://netbeans.org/features/platform/all-docs.html
If your application is build using NetBeans Platform, then here's a tutorial about splash screen customisation: http://wiki.netbeans.org/Splash_Screen_Beginner_Tutorial
There is a sample Javafx equivalent of Splash screen. However this splash screen is basically a java swing applet that is called from javafx to be displayed to the user and simulates more or less eclipse and netbeans splash screen using progress bar and titles for the loaded contents. This is the link.
You must be able to get the code and separate out the splash screen code written in java swings and use it for yourself.
This is a custom java swings splash screen. and hence to center the splash screen it uses the traditional
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension labelSize = l.getPreferredSize();
setLocation(screenSize.width / 2 - (labelSize.width / 2),
screenSize.height / 2 - (labelSize.height / 2));

Categories

Resources