Weird focus behaviour with JDialog.toBack() - java

I have a main frame and a kind of toolbar in a JDialog window. I want that "toolbar" to be always on top of MY program only, so I wrote this code :
public class Test {
private static JFrame mainFrame;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
mainFrame = new JFrame("test");
mainFrame.setSize(800,600);
mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
mainFrame.setVisible(true);
MyDialog d = new MyDialog();
}
});
}
public static class MyDialog extends JDialog {
public MyDialog() {
super(mainFrame);
setAlwaysOnTop(true);
setSize(80,60);
setVisible(true);
mainFrame.addWindowListener(new WindowAdapter() {
#Override
public void windowActivated(WindowEvent e) {MyDialog.this.setAlwaysOnTop(true);}
#Override
public void windowDeactivated(WindowEvent e) {
MyDialog.this.toBack();
}
});
}
}
}
To summarize, I create a mainFrame, then a JDialog owned by mainFrame. the JDialog will listen to the mainFrame. When mainFrame is desactivated, the dialog is set "toBack". When activated, it is set "alwaysOnTop".
Everything sounds fine, except that when I try to switch from my program to another, the focus seems to go from MyApp to Firefox (for instance), then from Firefox to the JDialog. How can I avoid that ?

Related

How do you get AWT graphics to appear on Window open?

I want to be able to have a window listener that when the window is opened, some graphics appear. This comes with some problem though, because you can't set a window listener while the window is set to visible (or at least that's what I've found), but if you wait to set the window to visible until after you set the listener you can't set the Graphics.
This is the code with the window set to visible at the start:
public class FrameTest {
static Frame myFrame;
static Graphics myGraphics;
public static void main(String[] args) {
//Initializing Window
myFrame = new Frame();
myFrame.setTitle("Frame Test");
myFrame.setSize(570, 570);
myFrame.setVisible(true);
myGraphics = myFrame.getGraphics();
myFrame.requestFocus();
//Close Button
myFrame.addWindowListener(new WindowAdapter()
{
public void windowOpened(WindowEvent e)
{
System.out.println("opened");
myGraphics.setColor(Color.red);
}
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
}
}

opening a frame by clicking on the button

In my project I am trying to open LoginFrame from WelcomeFrame by clicking a button and I want myWelcomeFrameto be closed as well.
I have successfully opened theLoginFrameby usingsetVisible(true).
To close theWelcomeFrameI have writtenframe.SetVisible(false)where frame is the object ofWelcomeFrame` but this line shows an error: frame cannot be resolved ....
Here's my code.. Please help
public class WelcomeFrame extends JFrame{
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
WelcomeFrame frame = new WelcomeFrame(); //object of WelcomeFrame
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
JButton btnNewButton = new JButton("Librarian Portal\r\n");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
LoginFrame l=new LoginFrame();
l.setVisible(true);
frame.setVisible(false); //error:frame cannot be resolved
}
});
Because object of WelcomeFrame is not accessible.
You need to create another object before trying to call setVisible method.
WelcomeFrame closing_frame = new WelcomeFrame();
closing_frame.setVisible(false);
public class WelcomeFrame extends JFrame{
private JPanel contentPane;
private WelcomeFrame frame;
after
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame = new WelcomeFrame();
I think it'll help you
a CardLayout is more adapted to your needs; the general idea is to create a jPanel instead of a JFrame, the CardLayout enables you to switch between them by showing only one at a time. if this is what you need have alook here

opening only one window on actionPerformed

I've looked through topics on how to open only one window when a button is clicked but none of the solutions there helped, perhaps because my code was structured a bit differently.
So I have a main window class extending JFrame and one of the buttons is supposed to open a new window when clicked. I have defined the widgets/panels etc for the new window in a separate class. At the moment, every time I click on the button a new window is opened. I want to make it so that if a window is already opened then it would switch to that window once the button is clicked again.
Here is a bit of my code:
public class MainWindow extends JFrame{
/*
* create widgets and panels
*/
Button.addActionListener(new ActionListener() { // the button that opens
//a new window
#Override
public void actionPerformed(ActionEvent e) {
Window2 ww = new Window2(); //creating the new window here
}
});
}
NB. The Window2 class is also extending JFrame, if that's of any help.
Thanks
pull out ojbect creation from actionPerformed method beacuse each time you click button it's create new object. below can help you :-
Make a Window2 class singalton for more detail about singalton click here.
2 . add null check as below :-
....
Window2 ww = null; // static or instence variable
......
#Override
public void actionPerformed(ActionEvent e) {
if(ww==null)
{
ww = new Window2();
ww.someMethod();
}
else
{
ww.someMethod();
}
}
});
Here is a full working example:
Window2.java
public class Window2 extends JFrame {
private static final long serialVersionUID = 7843480295403205677L;
}
MainWindow.java
public class MainWindow extends JFrame {
private static final long serialVersionUID = -9170930657273608379L;
public static void main(String[] args) {
MainWindow mw = new MainWindow();
mw.go();
}
private void go() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
private void createAndShowGUI() {
JButton button = new JButton("Click me");
button.addActionListener(new ActionListener() {
private Window2 ww = null;
#Override
public void actionPerformed(ActionEvent e) {
if (ww==null) {
ww = new Window2(); //creating the new window here
ww.setDefaultCloseOperation(HIDE_ON_CLOSE);
ww.setTitle("Window2 created on " + new Date());
ww.setSize(500, 200);
}
pack();
ww.setVisible(true);
}
});
setLayout(new BorderLayout());
add(button);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
pack();
setVisible(true);
}
}
What you can try is make two windows and put the actionPeformed method in the main class so that when the button is pressed it displays the second window

JDialog modal=true vs ModalityType.APPLICATION_MODAL

Initially I used following code in desktop Swing application. MyDialog is inner class and frame is JFrame.
private class MyDialog extends JDialog {
public MyDialog (String title) {
super(frame, title, true);
...
}
Then I have modified this code to support both desktop and applet. So it becomes like this. owber is JFrame or JApplet either.
private class MyDialog extends JDialog {
public MyDialog (String title) {
super(SwingUtilities.windowForComponent(owner), title, ModalityType.APPLICATION_MODAL);
...
}
The issue is that I run code as desktop but modality behavior is different. After application is started I click Eclipse in task bar, so application is hidden behind Eclipse. Now in task bar I click the application icon:
JFrame and JDialog are shown immediately on top of Eclipse
in taskbar there are two options JFrame and JDialog, but for both only JDialog appears on top of Eclipse and JFrame does not.
And JDialod does not have following constructor which would be most appropriate to me:
JDialog(Window owner, String title, boolean modal)
I have tried different fields from ModalityType but none of them give same desired result as snippet #1. What is wrong with my approach and why behaviour is different?
UPD for mKorbel:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class WindowForComp {
private JFrame mainwindow;
private CustomDialog customDialog;
private void displayGUI() {
mainwindow = new JFrame("MyFrame");
customDialog = new CustomDialog(mainwindow, "Modal Dialog", true);
mainwindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
JButton mainButton = new JButton("Just a button");
mainButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
customDialog.setVisible(true);
}
});
}
});
contentPane.add(mainButton);
mainwindow.setContentPane(contentPane);
mainwindow.pack();
mainwindow.setLocationByPlatform(true);
mainwindow.setVisible(true);
}
public static void main(String... args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new WindowForComp().displayGUI();
}
});
}
}
class CustomDialog extends JDialog {
public CustomDialog(JFrame owner, String title, boolean modal) {
super(SwingUtilities.windowForComponent(owner), title, ModalityType.APPLICATION_MODAL);
System.out.println(SwingUtilities.windowForComponent(owner));
JPanel contentPane = new JPanel();
JLabel dialogLabel = new JLabel("I am a Label on JDialog.", JLabel.CENTER);
contentPane.add(dialogLabel);
setContentPane(contentPane);
pack();
}
}
It appeared that SwingUtilities.windowForComponent(JFrame) was returning null, so the dialog didn't have a parent.
SwingUtilities.windowForComponent(JFrame) returns null
Now I use this method instead and it works perfectly (modality):
public static Window windowForComponent (Component c) {
if (c instanceof Window) return (Window)c;
return SwingUtilities.windowForComponent(c);
}

Close JFrame from a JButton process remain alive

I have a class developed with windowbuilderpro that i want to close also from a JButton further than with the standard X button on the window, so here the example of the class :
public class MainWindow {
public JFrame frame;
public MainWindow() {
initialize();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
public void show() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
//Show the main Frame
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
When i close the window from the X button the window close correctly and the process terminate.
When i close instead from a JButton that have this listener :
mntmExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Close the application main form
frame.setVisible(false);
frame.dispose();
}
});
the frame window close correctly but the process remain alive ... Why ?
As you can see there is an AWT-Shutdown thread that start and terminate continuously, How can i achieve the same behaviour of the X button that close also the application process ?
Notes :
System.exit(0); is not suitable because it terminate the application also if there are another background running thread and i don't want that . The MainWindow class should close and release it's resource, the same behaviour that have closing the application with the X button that close the MainWindow instance but if there are background thread running it doesn't kill they but wait until they finished their work...
Enviroment :
JDK 7
Eclipse 3.7.1
not sure what you really needed, that looks like that you create new JFrame again an again, don't do that, create JFrame once and re-use this Container
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // do nothing
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); // same as setVisible(false)
then for visibily you can only to call frame.setVisible(true);
for more Confortable is override WindowListener, then you can control some Events
All threads in this code stop when either the x button or the Exit button are activated. Are you getting different behavior?
import java.awt.event.*;
import javax.swing.*;
public class MainWindow {
public JFrame frame;
JButton mntmExit = new JButton("Exit");
public MainWindow() {
frame = new JFrame("Close Me!");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
mntmExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Close the application main form
frame.setVisible(false);
frame.dispose();
}
});
frame.add(mntmExit);
frame.pack();
show();
}
public void show() {
//Show the main Frame
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MainWindow mw = new MainWindow();
mw.show();
}
});
}
}
Just add one line:
System.exit(0);

Categories