How to make JFrame active (focused)? - java

When dialog window displayed it does not focused if other window is active (i.e. you need to focus it by mouse pointer to be able to deal with it). How can I make a focus to displayed dialog?
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class GuiTest {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setAlwaysOnTop(true);
JOptionPane.showMessageDialog(frame, "test info", "test header",
JOptionPane.INFORMATION_MESSAGE);
//frame.toFront();
//frame.requestFocus();
frame.dispose(); // When a frame is disposed, the exit action will be
// called.
}
}

JOptionPane.showMessageDialog stops the EDT (Event Dispatching Thread) until the dialog is closed.
You could instead use another JFrame instead of a JOptionPane
package util;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class GuiTest {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GuiTest window = new GuiTest();
window.frame.setVisible(true);
Dialog d = new Dialog();
d.show();
window.frame.requestFocus();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public GuiTest() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class Dialog extends JFrame {
private JFrame frame;
public void show() {
if (frame == null) {
frame = new JFrame();
frame.setTitle("Dialog");
frame.setBounds(100, 100, 450, 300);
frame.add(new JTextField("Hello"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
frame.setVisible(true);
}
}

try to run it and right after that make any other window active
Once a window loses focus you need to either:
click on the window to give it focus
Use the desktop manager to access the application. In Windows this is done by using Alt+Tab to cycle through open applications.
The problem is that only a JFrame is added to the desktop manager so if you want the ability to use Alt+Tab then you need to make the frame visible BEFORE showing the option pane.
Of course the JFrame will now be visible on the screen so you can use the setLocation(...) method with a negative value to hide the frame from the visible desktop.

Related

How to end Swing program with always-on-top dialog?

How to finish the program? I mean that after executing it and closing the dialog the Java process does not finish. It can be viewed in Eclipse so the red icon is still active and the program does not finish.
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class Main {
public static void main(String[] args) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setAlwaysOnTop(true);
JOptionPane.showMessageDialog(
frame, "test info", "test header", JOptionPane.INFORMATION_MESSAGE);
}
}
Dispose the frame after the dialog is set visible.
import javax.swing.*;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setAlwaysOnTop(true);
JOptionPane.showMessageDialog(
frame, "test info", "test header", JOptionPane.INFORMATION_MESSAGE);
// When a frame is disposed, the exit action will be called.
frame.dispose();
}
}
You can use following close the process. But it is little bit hard.
System.exit(0);
Because you did not call method like:
frame.show(); or frame.setVisible(true);
If you call one of the methods then the frame will show up and then if you close the frame, it will stop to run.
code update:
private static void createAndShowGUI() {
JFrame frame = new JFrame("frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setAlwaysOnTop(true);
frame.setSize(200, 200);
frame.setVisible(true);
JOptionPane.showMessageDialog(frame, "test info", "test header", JOptionPane.INFORMATION_MESSAGE);
}

Swing : Exit application actionListener

I am trying to figure out how can we exit the application with button click.
The problem i faced which makes me unable to exit the application is because i am using "extend JFRame" from the main class.
For an example,
app.class
public class app{
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
JFrame frame = new MainFrame("Exercise one");
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
.. .. ..
frame.setVisible(true);
})
}
}
MainFrame.java
public class MainFrame extends JFrame(){
public MainFrame(String title){
super(title)
//set layout manager
setLayout(new BorderLayout());
//swing components
JButton exit = new JButton("Exit");
//add container
Container container = getContentPane();
container.add(exit);
//create actionlist logic
exit.addActionListener(new ActionListener()){
#Override
public void actionPerformed(ActionEvent arg0){
// on click , this logic will end the application
}
}
}
}
I fully understand how i can cancel the application from app class.But in scenarios where i want to cancel the application from MainFrame.Can it be done ?
Thank you in advance.
The defaultCloseOperation is only processed by the frame when it encounters a WINDOW_CLOSING event, neither setVisible or dispose trigger this event, which means the the defaultCloseOperation won't be processed
The only way to ensure that this operation is triggered is to manually dispatch a WINDOW_CLOSING event
frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
One of the main reasons for wanting to follow this path is that it ensures the application is following the configured defaultCloseOperation and making up it's own mind (like calling System.exit manually)
The following demonstrates hiding, disposing and dispatching approaches. Only the dispatch approach will close the window and terminate the JVM
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.AbstractAction;
import static javax.swing.Action.NAME;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
frame.add(new JButton(new HideAction(frame)), gbc);
frame.add(new JButton(new DisposeAction(frame)), gbc);
frame.add(new JButton(new DispatchAction(frame)), gbc);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
System.out.println("Closing");
}
#Override
public void windowClosed(WindowEvent e) {
System.out.println("Closed");
}
});
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class HideAction extends AbstractAction {
private JFrame frame;
public HideAction(JFrame frame) {
this.frame = frame;
putValue(NAME, "Hide");
}
#Override
public void actionPerformed(ActionEvent e) {
frame.setVisible(false);
}
}
public class DisposeAction extends AbstractAction {
private JFrame frame;
public DisposeAction(JFrame frame) {
this.frame = frame;
putValue(NAME, "Dispose");
}
#Override
public void actionPerformed(ActionEvent e) {
frame.dispose();
}
}
public class DispatchAction extends AbstractAction {
private JFrame frame;
public DispatchAction(JFrame frame) {
this.frame = frame;
putValue(NAME, "Dispatch");
}
#Override
public void actionPerformed(ActionEvent e) {
frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
}
}
}
If I run this in my IDE, unless I use the dispatch option, the JVM is left running and I have to terminate the session to close it fully.
I also noted that calling dispose only triggers the WINDOW_CLOSED event, while the dispatch method will trigger the WINDOW_CLOSING event
Problem solved.
Credits to #XtremeBaumer.
Basically, when using "classname" extend JFRame.
We can input dispose() which will kill the application completely. This will causes the JFrame window to be destroyed and cleaned up by the operating system. :)
Indeed, dispose() is the right solution. I also suggest to add a pack() call so the UI shows up properly:
public class MainFrame extends JFrame {
public MainFrame(String title) {
super(title);
...
// create actionlist logic
exit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("--> closing app programmatically");
MainFrame.this.dispose();
}
});
this.pack();
}
}
You can test the events with a WindowListener on the MainFrame. They are invoked as if the user pressed the close button:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new MainFrame("Exercise one");
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
// .. .. ..
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.out.println("--> closing...");
}
public void windowClosed(WindowEvent e) {
System.out.println("--> closed...");
}
});
}
});
}

Java bringing window to front doesnt let me type in textfield

I want to be able to type in textfield when my frame brought foreground. Program is set to bring my Frame to the foreground after 5 seconds and set focus on textfield. I start the program then click another window. My frame shows up after 5 seconds with cursor blinking. But when i type something it doesnt actually taken as input by textfield. I also implemented FocusListener to confirm that focus set to textfield when frame brought to foreground. My operating system is Windows 10.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class TestMain implements FocusListener {
/**
* Create the GUI and show it. For thread safety, this method should be
* invoked from the event-dispatching thread.
*/
public JFrame frame = null;
private void createAndShowGUI() {
// Create and set up the window.
frame = new JFrame();
frame.addFocusListener(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
JLabel label1 = new JLabel("Label");
panel.add(label1);
JTextField textField1 = new JTextField();
textField1.setPreferredSize(new Dimension(300, 40));
panel.add(textField1);
textField1.addFocusListener(this);
label1.addFocusListener(this);
frame.addWindowListener(new WindowAdapter() {
// Program Closing Alert
public void windowActivated(WindowEvent e) {
System.out.println("window activated");
textField1.requestFocusInWindow();
}
});
frame.getContentPane().add(panel, BorderLayout.CENTER);
// Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
TestMain mn = null;
// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
mn = new TestMain();
mn.createAndShowGUI();
System.out.println("START");
try {
Thread.sleep(5000);
mn.frame.setAlwaysOnTop(true);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void focusGained(FocusEvent e) {
System.out.println("Focus Gained by " + e.getComponent().getClass().getName());
}
#Override
public void focusLost(FocusEvent e) {
System.out.println("Focus Lost by " + e.getComponent().getClass().getName());
}
}
UPDATE : When i add
frame.setLocationByPlatform( true );
after
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
it works only for the first time. if i change main function as
try {
Thread.sleep(5000);
mn.frame.setAlwaysOnTop(true);
mn.frame.setAlwaysOnTop(false);
Thread.sleep(5000);
mn.frame.setAlwaysOnTop(true);
mn.frame.setAlwaysOnTop(false);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
it doesnt work for the second time
You do bring focus to the JTextField but you dont b ring focus to the frame itself. Bringing the frame to the front and bringing the focus to the frame is different. A solution similar can be found here: How to set focus the already running application?
Moving your frame doesn't focus your textfield. You should add toFront() after set always on top so if the Window is visible, brings the Window to the front and may make it the focused Window.
try {
Thread.sleep(5000);
mn.frame.setVisible ( true );
mn.frame.toFront ( );
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

How to make sure Swing UI is actually displayed on screen?

When I click on button another JFrame class is getting opened. The JFrame will be visible on the screen after 2 seconds but the isVisible returns true before that. I want to start timer when the JFrame actually getting displayed on the screen. How can I achieve this ? I tried to used isShowing() and isDisplayable() but it's not giving expected result.
You could use something like this:
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
public class MainApp {
JFrame frame = new JFrame("Main");
JButton button = new JButton("Toggle auxiliary");
JFrame auxFrame = new JFrame("Auxiliary");
public MainApp() {
button.addActionListener(evt -> {
// Delay displaying for 2 seconds
Timer timer = new Timer(2000, event -> {
auxFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
auxFrame.setSize(320, 240);
auxFrame.setVisible(true);
});
timer.start();
auxFrame.addWindowListener(new WindowAdapter() {
#Override
public void windowOpened(WindowEvent e) {
// Stop timer after the auxiliary frame is displayed
timer.stop();
}
});
});
frame.add(button);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(320, 240);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(MainApp::new);
}
}

Java, Swing and Xubuntu, JFrames not correct

I'm completely new to Linux and have been trying to get my (Windows built) Java Swing projects to work correctly on XUbuntu on a separate machine from executable jar files I built.
I've reduced the problem to a minimum amount of code
import java.awt.Dimension;
import javax.swing.*;
public class JFrameTest extends JFrame {
public JFrameTest(String title) {
super(title);
JLabel lab = new JLabel("Label");
this.getContentPane().add(lab);
this.setMinimumSize(new Dimension(200, 200));
this.pack();
this.setVisible(true);
}
public static void main(String args[]) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JFrameTest frame = new JFrameTest("Title");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
On Windows I see:
In Xubuntu I just see a grey box and the label, not the Title or close icons etc. I also have to kill (-9) the jvm after I've ctrl zedded from the command line. I launched it with java -jar filename.jar
My Linux machine is running Xubuntu 11. I've installed the sun Java 6_24 JRE. I Googled for this and found something similar relating to Compziz(?) but this was allegedly fixed a while back. I'm a bit stuck now. I have got one Swing app that works OK in that it responds to buttons OK but still doesn't show the Title etc. Any help would be much appreciated.
I don't use Xubuntu, but the general rule is that any code that updates a GUI should be executed on the Event Dispatch Thread. See the section from the Swing tutorial on Concurrency.
The examples from the Swing tutorial all use a format like this:
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
public class SSCCE extends JPanel
{
public SSCCE()
{
add( new JLabel("Label") );
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new SSCCE() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
Suggestion: Start the GUI on the EDT. Vis.
import java.awt.Dimension;
import javax.swing.*;
public class JFrameTest extends JFrame {
public JFrameTest(String title) {
super(title);
JLabel lab = new JLabel("Label");
this.getContentPane().add(lab);
this.setMinimumSize(new Dimension(200, 200));
this.pack();
this.setVisible(true);
}
public static void main(String args[]) {
// Costruct & show the GUI on the EDT
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JFrameTest frame = new JFrameTest("Title");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}
}
For more information see Concurrency in Swing.

Categories

Resources