Java JPopupMenu Mac OS X - java

i have three problems with a JPopupmenu on Mac, all can be reproduced by the enclosed java
program or e.g. the netbeans java application.
The first thing is that Java applications don't block the dock when a popup menu is shown.
So when i right click in my java application to open a popup menu, i can still
move the mouse over the dock area and the dock appears.
In non java applications (Outlook, Textwrangler, Finder...) the dock won't
appear if a context menu is shown in these applications.
Is there a way to make a java application behave like a 'native' OS X application, so
the dock will not be shown in this context?
The next problem is more annoying.
if the context menu is shown by the java application and now the user switches (cmd-TAB or by
the dock) to another application lets say Outlook, the context menu of the java application is still
visible on top of the other application window.
Is there a way to hide the popup menu of the java application if another application has the focus?
And the last problem.
Lets say an application is in front of netbeans and now you right click into the netbeans window,
a popup menu from netbeans is shown, but if you move the mouse over the menu items, no menu item
will be highlighted. You're able to select a menu item by pressing the mouse, but by moving the
mouse over the menu items they are not highlighted.
Why are the menu items not highlighted, is there a workaround?
Mac OS X 10.6.8
Java: 1.6.0_35
package popupmenu;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
public class PopupMenuApp {
private JPopupMenu popup;
private class PopupListener extends 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()) {
popup.show(e.getComponent(), e.getX(), e.getY());
}
}
}
private void start() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
popup = new JPopupMenu();
popup.add(new JMenuItem("A popup menu item"));
frame.addMouseListener(new PopupListener());
frame.setSize(300, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setAlwaysOnTop(true);
}
});
}
public static void main(String[] args) {
PopupMenuApp app = new PopupMenuApp();
app.start();
}
}

For the second issue, adding a WindowFocusListener does the trick:
popupMenu.show(button, 0, bounds.height + 1);
frame.addWindowFocusListener(new WindowFocusListener() {
#Override public void windowGainedFocus(WindowEvent arg0) {}
#Override public void windowLostFocus(WindowEvent arg0) {
popupMenu.setVisible(false);
frame.removeWindowFocusListener(this);
}
});

Related

Open a new JFrame window from a button click in another JFrame window

Update: I've decided the simplest thing to do at the moment would be to use separate JPane's and not JFrame's for the sub-menu's. I'll create them all together and set the others to invisible, and toggle that way. The menus aren't that complex that this would be too much of a problem.
I am creating a GUI that opens another JFrame window from a button click in another. I am just not sure of the right way to approach closing the main window when one of the buttons is clicked, but not closing the whole program. Neither am I sure how to get the second window visible (the line of code I tried from another example isn't working). The second frame that is brought up will give the user options to do things and will actually call another program/class to run on a button clicked within it (the result of one of the options is a long program so I think I need to run it on another thread.). After the program has finished running, the user will have the option to return to the main menu, which would close the second menu (and kill it), or exit the program (and thus kill the main menu and clean everything up). From the main menu, they will also have the option to close the program, where everything will be cleaned up. This is what I have so far:
Main GUI:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
class GUIMain implements ActionListener {
GUIMain(){
JFrame jFrm = new JFrame("Data Mining Application");
jFrm.setSize(800,600);
jFrm.setLayout(new BorderLayout());
jFrm.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
prepareGUI(jFrm.getContentPane());
jFrm.pack();
jFrm.setVisible(true);
}
private void prepareGUI(final Container pane){
JPanel mainPanel = new JPanel(new GridLayout(3,2,50,50));
JButton b1 = new JButton("Pre-processing");
b1.addActionListener(this);
mainPanel.add(b1);
pane.add(mainPanel,BorderLayout.CENTER);
}
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new GUIMain();
}
});
}
#Override
public void actionPerformed(ActionEvent e) {
switch (e.getActionCommand()){
case "Pre-processing":
PreProcessingGUI window = new PreProcessingGUI();
window.getFrame.setVisible(true); //not working
break;
// etc
default:
break;
}
}
}
The class and JFrame that is called:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class PreProcessingGUI implements ActionListener {
PreProcessingGUI(){
JFrame jFrm = new JFrame("Pre-processing");
jFrm.setSize(800,600);
jFrm.setLayout(new BorderLayout());
jFrm.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
prepareGUI(jFrm.getContentPane());
jFrm.pack();
}
private void prepareGUI(final Container pane) {
//do stuff
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
PreProcessingGUI window = new PreProcessingGUI();
// Not surewhat to do here either as the program is not recognising the getFrame method
//window.getFrame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
#Override
public void actionPerformed(ActionEvent e) {
// do stuff
}
}
Well I don't work much with Swing but I can help you a bit:
When you try to show the second window in GUIMain.actionPerformed you seem to try to get the frame with a public variable having a method (getFrame).
window.getFrame.setVisible(true);
This variable doesn't exist! It is not defined anywhere. There is no magic here!
You should implement a getFrame() method in PreProcessingGUI and use it in instead of your variable.
In GUIMain.actionPerformed:
window.getFrame().setVisible(true);
In PreProcessingGUI
public class PreProcessingGUI implements ActionListener {
private JFrame jFrm; //You asssing is as you the constructor
PreProcessingGUI(){
jFrm = new JFrame("Pre-processing");
...
}
public getFrame(){
return jFrm;
}
...
In addition to that, I would say you should consider using JDialog (and optionally make it modal) instead of a JFrame.

Programing: open 2 popup windows with one click

is it possible in java or other programing language to open 2 popup windows with one click and one of them to be closed automatically after a certain time?
Thank you in advance!
yes in thing in the programing can be done
i show the 2 popup menu and you can close one of them after time by using timer or thread and you can change their size by using size method
i am not going to write all code because you ask if you can open 2 popup windows with one click or not
i iust open the 2 popup windows with one click
package experiments;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class CreateDialogFromOptionPane {
public static void main(final String[] args) {
final JFrame parent = new JFrame();
JButton button = new JButton();
button.setText("Click me to show dialog!");
parent.add(button);
parent.pack();
parent.setVisible(true);
button.addActionListener(new java.awt.event.ActionListener() {
#Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
new JFrame().setVisible(true);
new JFrame().setVisible(true);
}
});
}
}

Don't click until button is released

Hello i'm making a simple game right now, and I have it when your on the play screen you can press esc to open up the menu. There is a main menu button which takes you from the play screen to the main menu screen, and the problem is it takes them to the main menu screen, but then clicks the button which is in the same spot on the main screen as the ingame menu, so it clicks the button on the main menu before you are able to release the button. Here are some of my classes
this is my menu class (Main screen) http://pastebin.com/kc5Dx2bp
this is my play class (The play screen) http://pastebin.com/Gr3y9Amj
Is there a way to make it so you can't click another button until the mouse button is released?
Basically, you can use the ButtonModel to track finer changes to the button state then ActionListener gives you.
This example monitors the armed and pressed states of the model and takes action based on a certain condition.
This is a small trick, as the state you are looking for will occur not only when the button is released, but also when the button is first pressed. What we do is wait until the previous state had the button pressed and the buttons pressed state is false, then we know we have a button release
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import javax.swing.ButtonModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class TestButton05 {
public static void main(String[] args) {
new TestButton05();
}
public TestButton05() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
final JButton btn = new JButton("Clicked");
btn.getModel().addChangeListener(new ChangeListener() {
private boolean wasPressed = false;
#Override
public void stateChanged(ChangeEvent e) {
ButtonModel model = (ButtonModel) e.getSource();
if (model.isArmed() && !model.isPressed() && wasPressed) {
System.out.println("Released");
} else {
wasPressed = model.isPressed();
}
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(btn);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Create a boolean in your class called canClick.
Create a MouseListener.
Add the MouseListener to each button (button.addMouseListener(...);)
In the MouseListener, implement all needed methods.
Set the boolean to true or false as needed in each method.
When a button is clicked (ActionListener), check the boolean.
If false, cancel it (or just disable all buttons until true)
Something like that.

getRootPane() default button - Is this a bug?

I have made an SSCCE. Please note that it must be Windows Look&Feel.
import java.awt.*;
import javax.swing.*;
public class DefaultButtonBug {
private static final String LAF_WINDOWS = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(LAF_WINDOWS);
} catch (Exception ex) {
System.out.println("Setting the L&F failed so I cannot reproduce the bug.");
System.exit(1);
}
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JPanel content = new JPanel();
JButton defaultButton = new JButton("Default");
content.add(defaultButton);
JFrame frame = new JFrame();
frame.getRootPane().setDefaultButton(defaultButton);
frame.setContentPane(content);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
Launch this
The button should be focused. If not, click it.
Click on any other window, to make sure this current window loses the focus
The button keeps animating in blue tints, even when this window has no focus anymore!
The button 'pulsing' animation is something not present in the standard Java L&F.
Remark that when this button is no longer the default button (remove the appropriate line in the code), the button will be gray after the window loses focus and there is no animation whatsoever.
My question to you is: is this considered a bug? Because this makes the EDT keep doing stuff instead of being idle when the window is hidden behind another window too (I did some profiling). Indeed, that's the stuff that bothers me the most of all: hiding the window does not make the EDT go idle.
getRootPane() default button - Is this a bug?
not as described in a comment by #Guillaume Polet
but I'd be inclined to use KeyBindings, because any JComponents with FocusInWindow and added ActionListener can consume() ENTER key pressed, for all JButtons JComponents
focus is managable by getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT/*.WHEN_FOCUSED*/)
notice (Win OS) JButton has implemented TAB as an accelerator in KeyBindings, too.
from code
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class DefaultButtonBug {
private static final String LAF_WINDOWS = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(LAF_WINDOWS);
} catch (Exception ex) {
System.out.println("Setting the L&F failed so I cannot reproduce the bug.");
System.exit(1);
}
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JPanel content = new JPanel();
JButton focusedButton1 = new JButton("Focused");
focusedButton1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Focused pressed");
}
});
content.add(focusedButton1);
final JButton defaultButton2 = new JButton("Default");
defaultButton2.setIcon(UIManager.getIcon("OptionPane.informationIcon"));
defaultButton2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Default pressed");
}
});
defaultButton2.getModel().addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
ButtonModel model = (ButtonModel) e.getSource();
if (model.isRollover()) {
defaultButton2.setIcon(UIManager.getIcon("OptionPane.errorIcon"));
} else {
defaultButton2.setIcon(UIManager.getIcon("OptionPane.informationIcon"));
}
}
});
content.add(defaultButton2);
JFrame frame = new JFrame();
frame.getRootPane().setDefaultButton(defaultButton2);
frame.getRootPane().getInputMap(
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT/*.WHEN_FOCUSED*/)
.put(KeyStroke.getKeyStroke("ENTER"), "clickButton");
frame.getRootPane().getActionMap().put("clickButton", new AbstractAction() {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
defaultButton2.doClick();
}
});
frame.getRootPane().setDefaultButton(defaultButton2);
frame.setContentPane(content);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
learning item of day
on Win7/8 (Java6/7) are allowed mouse event on un_focused Java Window (for all standard L&F), can be listener from ChangeListener added to ButtonModel
doesn't work on WinXP
focused
un_fosused firing the same events a
EDIT
in Win7 compiled in JDK7_011 flashing JButtons (focused in Java window) with blue Color
flashing with blue color on second period
and

How to launch a file in the foreground?

Launch a file = launch program associated with given file and automatically open that file on start of the program.
Let's say I run IntelliJ IDEA, I run my code and main window (modal) of my program shows up. My program is in the foreground.
Then I launch a .pdf file (for now it means AcroReader will be executed) from my program. AA will show up in front of IntelliJ but behind my program.
Question
I would like AA (it is just an example here of course) to be shown in front of my program, not behind. How to do it?
Please note, this does not mean I would like to move my program to the background!
For launching files I use
java.awt.Desktop.getDesktop().open(new java.io.File(filepath));
My GUI is done in Swing.
Update 1
To rule out, any influence of custom widgets, events, and so on, I put simply JButton at the bottom of my window (JDialog) -- it is in Scala, but this piece is similar to Java syntax:
var dlg = new javax.swing.JDialog(null,"test",Dialog.ModalityType.DOCUMENT_MODAL);
dlg.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
var button = new JButton("Select Me");
var actionListener = new ActionListener() {
def actionPerformed( actionEvent : ActionEvent) = {
java.awt.Desktop.getDesktop().open(new java.io.File("test.pdf"))
}
};
button.addActionListener(actionListener);
dlg.add(button, BorderLayout.SOUTH);
dlg.setSize(300, 100);
dlg.setVisible(true);
Once clicked, AA is shown behind my app. Since it takes several seconds to run AA I also tried to click the button, and move the mouse away from my window. Exactly the same behaviour.
I also noted that AA is shown at the same relative position to my window, top left corner of AA is near bottom right corner of my app.
You may try something like this. On my machine (Ubuntu 10.4 LTS with Gnome2) it gives the evince (pdf-viewer) in the front, and if I close/hide evince - JDialog is placed back to the front.
On windows it may be very different, since actually without "dlg.toBack();" invocation behavior is the same.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class OpenFileTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
final JDialog dlg = new javax.swing.JDialog(null, "test", JDialog.ModalityType.DOCUMENT_MODAL);
dlg.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
JButton button = new JButton("Select Me");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
java.awt.Desktop.getDesktop().open(
new java.io.File("/home/user/Downloads/jfreechart-1.0.13-US.pdf"));
dlg.toBack();
} catch (IOException e1) {
throw new RuntimeException(e1);
}
}
});
dlg.add(button);
dlg.setVisible(true);
}
});
}
}

Categories