I have a swing program which creates a fullscreen borderless window -- I am running on Windows 7. I need the program to be able to focus and bring itself to the front. However, when I attempt to use the method found here, How to bring a window to the front?, instead of bringing the window to the front the window just flashes in the taskbar and does not accept input. Below I wrote a small program that demonstrates the issue:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class WindowTest extends JFrame{
WindowTest(){
setTitle("Window Test");
setSize(600, 600);
setLocationRelativeTo(null);
setUndecorated(true);
setExtendedState(JFrame.MAXIMIZED_BOTH);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
final WindowTest wt = new WindowTest();
wt.setVisible(true);
Timer t = new Timer(3000,new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
wt.toFront();
wt.repaint();
}
});
}
});
t.setRepeats(false);
t.start();
wt.addKeyListener(new KeyListener(){
#Override
public void keyPressed(KeyEvent arg0) {
if(arg0.getKeyCode() == KeyEvent.VK_ESCAPE){
wt.dispose();
System.exit(0);
return;
}
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
});
}
});
}
}
This will create a borderless, maximized window, and then three seconds later will attempt to bring it to the front. If you change to another window before that, the taskbar button will flash but the window will not be brought to the front.
toFront(quite common issue) doesn't works for JFrame, this is basic property for JDialog
basically is possible to move toFront() only one JFrame, have to use setExtendedState, but with side effects flickering and jumping on the scren, use JDialog instead
don't use KeyListener, because JFrame isn't focusable for KeyEvent, have to use KeyBindings
for example
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class WindowTest extends JFrame {
private static final long serialVersionUID = 1L;
private JFrame frame = new JFrame();
public WindowTest() {
frame.setTitle("Window Test");
frame.setSize(600, 600);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setExtendedState(JFrame.ICONIFIED);
Timer t = new Timer(3000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
frame.setExtendedState(JFrame.NORMAL);
}
});
}
});
t.setRepeats(false);
t.start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
final WindowTest wt = new WindowTest();
}
});
}
}
There's another trick that can be used in case you don't want to minimize and then maximize the window. I have no idea why it works, but if you move the mouse before making the window visible it will come to the front. It's pretty weird, I know, but it seems to work for JRE 1.4 through 1.8 at least. In order to minimize the effect on the mouse you can first see where it is and only move it a little. Your code might look something like this:
PointerInfo mInfo = MouseInfo.getPointerInfo();
Point mWhere = mInfo.getLocation();
(new Robot()).mouseMove(mWhere.x + 2, mWhere.y + 2);
frame_.setVisible(true);
I realize this is a rather late response for the person who posted the question but others may still be looking for the answer.
Related
I must use a swing-ui designer tool to create my UI, that only supports graphically editing JPanels. Those panels (they basically contain complex button designs) to work like a JButton. I cannot use anything other than JPanel as base class of these panels (UI editor limitation).
What is the most generic solution to do this?
Create a custom button that uses the panel's draw method instead of
it's own?
Create a base-panel class that reimplements the whole
button?
Another more elegant solution?
Here is a quick demo, to show you how you could use borders to simulate a button.
The demo also reacts to mouse and key events :
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
public class JPanelButton extends JPanel {
Border raisedetched = BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
Border loweredetched = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
public static void main(final String[] args) {
JFrame frame = new JFrame();
final JPanelButton panel = new JPanelButton();
panel.raiseBorder();
panel.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(final MouseEvent e) {
panel.lowerBorder();
}
#Override
public void mouseReleased(final MouseEvent e) {
panel.raiseBorder();
}
});
panel.setFocusable(true); // you need this or the panel won't get the key events
panel.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(final KeyEvent e) {
panel.lowerBorder();
}
#Override
public void keyReleased(final KeyEvent e) {
panel.raiseBorder();
}
});
frame.setContentPane(panel);
frame.setSize(100, 100);
frame.setVisible(true);
}
public void raiseBorder() {
setBorder(raisedetched);
}
public void lowerBorder() {
setBorder(loweredetched);
}
}
Simply add MouseListener.
JPanel jp = new JPanel();
jp.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e) {
System.out.println("Clicked");
}
});
If this answer isn't specific enough, leave a comment and I'll give you more explanation.
My program launches a JFrame from an already running parent JFrame. The second JFrame has autonomy from the first except for one condition - I require a button in the parent JFrame to be disabled when (and only when) the second JFrame is open to prevent additional JFrames being launched.
So my question is, how can I listen to the second JFrame's 'existence' from the parent JFrame in order to manipulate whether my button is active or not?
My parent JFrame launches the secondary JFrame as follows:
try {
second_frame Jframe = new second_frame(variable);
Jframe.second_frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
followed by:
btn_open.setEnabled(false);
to disable the button once the second JFrame has been launched.
So how can I now listen to the second JFrame's window status from the first JFrame in order to re-enable the btn_open button.
One way is to add a WindowListener to the second frame. You can call button.setEnabled() every time the frame closes or opens. (There are implemented methods for that)
Here is an example:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Example {
JButton button = new JButton("Open");
public static void main(String args[]) {
new Example();
}
public Example() {
JFrame frame = new JFrame();
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new secondFrame();
}
});
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
}
class secondFrame extends JFrame implements WindowListener {
public secondFrame() {
setSize(200, 200);
setVisible(true);
addWindowListener(this);
}
#Override
public void windowActivated(WindowEvent arg0) {
}
#Override
public void windowClosed(WindowEvent arg0) {
}
#Override
public void windowClosing(WindowEvent arg0) {
button.setEnabled(true);
}
#Override
public void windowDeactivated(WindowEvent arg0) {
}
#Override
public void windowDeiconified(WindowEvent arg0) {
}
#Override
public void windowIconified(WindowEvent arg0) {
}
#Override
public void windowOpened(WindowEvent arg0) {
button.setEnabled(false);
}
}
}
In my UI i have a JPopMenu with values as ,
for e.g A,B,C
The scenario is,
I opened the JPopupMenu and kept it open.
At back end with a timer running , it updates the content B to some other alphabet at frequent interval.
3.I want the JPopupMenu to get updated while it is kept open.
In current behavior if i close and open JPopupMenu the updated value shows up.
I tried repaint()but it doesn't do anything.
What is the best way to do this?? Am new to swings please help.
Menu items can change their content at run time just fine. Without seeing your code it's hard to tell what you're doing wrong, but here's a working example:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
public class PopupTest {
private static final String[] messages = {
"You are today's 1000th user!",
"You have won an internet!",
"Claim your prize!"
};
private PopupTest() {
JFrame frame = new JFrame("You have won");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel lbl = new JLabel("Check your prize!");
frame.setLocationByPlatform(true);
frame.add(lbl);
frame.pack();
final JPopupMenu menu = new JPopupMenu();
final JMenuItem item = new JMenuItem(messages[0]);
menu.add(item);
menu.add(new JMenuItem("Another item that does not work"));
final Timer timer = new Timer(1000, new ActionListener() {
int count;
#Override
public void actionPerformed(ActionEvent e) {
count++;
count %= messages.length;
item.setText(messages[count]);
}
});
menu.addPopupMenuListener(new PopupMenuListener() {
#Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
}
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
timer.stop();
}
#Override
public void popupMenuCanceled(PopupMenuEvent e) {
timer.stop();
}
});
lbl.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}
#Override
public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
private void maybeShowPopup(MouseEvent e) {
if (e.isPopupTrigger()) {
menu.show(e.getComponent(), e.getX(), e.getY());
timer.start();
}
}
});
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new PopupTest();
}
});
}
}
Try to use .revalidate() with .repaint() it might help.
The docs suggest that the revalidate method is called every time something like size changes and manually calling it with repaint seems to solve problems like these.
I would like to make it so that when i close my GUI it will run a method in my main class but then also close after?
please help thanks
Assuming you're using Java Swing:
JFrame frame = new JFrame();
frame.setTitle("Project Planner");
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent event) {
exitProcedure();
}
});
.
public void exitProcedure() {
frame.dispose();
System.exit(0);
}
Just add what you want to do before the dispose method.
Try an implementation of WindowAdapter in GUI's addWindowListener() method.
For this you need to register WindowListener to the associated JFrame. And override the windowClosing() method.
EDIT for choosing a String randomly out of an String array you can use java.util.Random API .For Example here is an array of String and each time the JFrame is closed , a String is picked out randomly out of this array and printed in method callMeBeforeExit.
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;
import java.awt.BorderLayout;
import java.util.Random;
class WorkBeforeClose extends JFrame
{
String[] strings = {
"Hello",
"World",
"Java",
"OOPs"
};
public void showGUI()
{
setTitle("Close me");
getContentPane().add(new JLabel("Close me"),BorderLayout.NORTH);
addWindowListener(new WindowAdapter()
{
#Override
public void windowClosing(WindowEvent evt)
{
callMeBeforeExit();
System.exit(0);//Don't write this line if you don't want your program to exit
}
});
setSize(200,200);
setVisible(true);
}
private void callMeBeforeExit()
{
Random random = new Random();
int i = random.nextInt(strings.length - 1);//Defines the Range of numbers to be chosen randomly.
System.out.println(strings[i]);
}
public static void main(String st[])
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
WorkBeforeClose wbc = new WorkBeforeClose();
wbc.showGUI();
}
});
}
}
I am trying to make a pop up window appear when the user clicks on the About menu.
Is that possible to do in Java? I have seen that clicking on a menu does not invoke actionPerformed. After a bit of searching i found that i should try to use this:
new AbstractAction("Do XY")
but NetBeans tells me that an identifier is expected. Is there any other way to do this, or does Java not allow buttons directly on the Menu bar?
Of course you can do this in Java. You could simply add a MenuListener to your menu.
Here is an example of such thing (it also implements the traditional "About" menu item):
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.SwingUtilities;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
public class TestAboutMenu {
protected void initUI() {
final JFrame frame = new JFrame("test");
JMenuBar bar = new JMenuBar();
JMenu help = new JMenu("Help");
help.addMenuListener(new MenuListener() {
#Override
public void menuSelected(MenuEvent e) {
showAboutDialog(frame);
}
#Override
public void menuDeselected(MenuEvent e) {
// TODO Auto-generated method stub
}
#Override
public void menuCanceled(MenuEvent e) {
// TODO Auto-generated method stub
}
});
JMenuItem about = new JMenuItem(new AbstractAction("About") {
#Override
public void actionPerformed(ActionEvent e) {
showAboutDialog(frame);
}
});
help.add(about);
bar.add(help);
frame.setJMenuBar(bar);
frame.setSize(400, 400);
frame.setVisible(true);
}
protected void showAboutDialog(final JFrame frame) {
JDialog dialog = new JDialog(frame);
dialog.add(new JLabel("About this program"));
dialog.setModal(true);
dialog.pack();
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestAboutMenu().initUI();
}
});
}
}
To do it you would propably need to write your own Menu bar class. But you could do such trick: Write mouse listener with mouseClicked() method. If you place your menu bar on top then you know it's bounds are: 0, windowWidth(), ~20 (menu bar height), windowWidth(). And then you check if position of mouse is in this rectangle. If yes - you show pop-up window. It's just on the spot idea so let me know if it works for you.