I was wondering why Nimbus would be conflicting somehow with Virtual keys. Check out the sample I made below:
public class buttontest implements ActionListener {
JMenuItem close =new JMenuItem("Close");
public static void main (String[] args){
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (UnsupportedLookAndFeelException e) {
// handle exception
} catch (ClassNotFoundException e) {
// handle exception
} catch (InstantiationException e) {
// handle exception
} catch (IllegalAccessException e) {
// handle exception
}
}
public buttontest(){
JFrame test = new JFrame();
JMenuBar bar=new JMenuBar();
JMenu file=new JMenu("File");
close.setMnemonic(KeyEvent.VK_C);
file.setMnemonic(KeyEvent.VK_F);
test.setExtendedState(test.getExtendedState() | test.MAXIMIZED_BOTH); // Maximized Window or setSize(getMaximumSize())
test.setDefaultCloseOperation(1);
bar.add(file);
file.add(close);
test.setJMenuBar(bar);
test.setVisible(true);
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==close){
System.exit(0);
}
}
}
The way its wrote, you can try to use the Virtual keys. You will see that Alt F works to open the File menu but Alt C doesnt close the application. In other way, if you comment the Nimbus code both virtual Keys will work.
I made one research regarding to this "bug" (or maybe something wrong Im doing that Im not aware) but until now I found nothing. Has someone ever passed through this?
You have to use setAccelerator() method for JMenuItem:
close.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.ALT_MASK ));
From Javadoc:
JMenuItem#setAccelerator(KeyStroke)
Sets the key combination which
invokes the menu item's action listeners without navigating the menu
hierarchy. It is the UI's responsibility to install the correct
action. Note that when the keyboard accelerator is typed, it will work
whether or not the menu is currently displayed.
Additional note:
Replace LookAndFeelInfo to UIManager.LookAndFeelInfo as it's an inner class inside UIManager.
Call the constructor in the main method.
Change the parameter of setDefaultCloseOperation(1) to 3 as 3 = JFrame.EXIT_ON_CLOSE, but 1=JFrame.HIDE_ON_CLOSE which hides the frame, personally, I hate it, because close button created for closing frame, not hiding it, like Skype.
Add actionListener to close button :close.addActionListener(this);
Related
I would like to add an ActionListener that closes the BufferedWriter. Overall, my program is saving variable values to a file. These values get read into python scripts that are run in this Java GUI. However, I cannot get the (button click) ActionListener to work. I can only get a WindowListener (for frame closing) to work.
For a WindowListener I use the following code,
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
try {
bufferFileWriter.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
});
For an ActionListener, which gives error: java.io.ioexception stream closed, I use the following code:
setVarFileBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Save the variable values when VarFileBtn pressed
try {
bufferFileWriter.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
});
What code should I use to have a listener identify a button setVarFileBtn has been clicked, and subsequently close a BufferedWriter? Am I missing certain Java Swing code concepts in order to make the BufferedWriter write's get saved to a file?
I solved the problem. My error occurred because I had two ActionListener's for the same button. The listener not shown was for writing the variable values. Once I simply added this, to the first listener:
try {
bufferFileWriter.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
the variable values were written to my file.
In order to get the button that is being pressed, you need to get the action command from the event. You can do this like:
new ActionListener() {
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().equals("Save")) {
// perform save code
}
}
}
"Save" is whatever the name of the JButton is.
I've already this project, but I'm having more problems. The dialog for SetMusicDialog opens, but it won't close when I try to exit out. I have a System.exit, but I'm not sure why the window won't close.
import java.awt.*;
import java.io.*;
public class SetMusicDialog extends Dialog
{
public static String sng;
public SetMusicDialog()
{
super ((Dialog)null, "Set Music");
Panel mpanel;
Font l = new Font("Helvetica", Font.ITALIC, 12);
setFont(l);//sets font
setBackground(Color.cyan);
Panel f = new Panel();
f.add("West", new Button("Death Grips"));
f.add("East", new Button("Siren"));
add("South",f);
pack(); // make it just fit
resize(preferredSize());
move(200,200);
}
public boolean handleEvent1 (Event evt)
{
switch (evt.id)
{
case Event.WINDOW_DESTROY:
System.exit(0);
dispose();
return true;
case Event.ACTION_EVENT:
if("Death Grips".equals(evt.arg))
{
sng= "breakmirrors.wav";
}
else if("Siren".equals(evt.arg))
{
sng= "bip.wav";
}
dispose();
}
return false;
}
}
You can add this:
addWindowListener( new WindowAdapter() {
public void windowClosing(WindowEvent e){
dispose();
System.exit(0);
}
});
windowClosed won't detect if the user tries to close the window. It will only run if the window has been closed. So use windowClosing.
Also, by using WindowAdapter you do not need to write all the methods of WindowListener.
I added this code in your constructor, and it works properly.
If you are using AWT, you should create a WindowListener as MadProgrammer stated. Basically, a WindowListener is a class that has methods that are run when certain window-related actions occur. To write code that will run when a Dialog (which extends Window) is closed:
//d is a dialog
d.addWindowListener(new WindowListener() {
//You'll need to implement all the abstract methods. leave them empty.
#Override
public void windowClosed(WindowEvent e) {
//Your code
}
});
Basically, you're anonymously implementing the abstract class WindowEvent. Make sure you implement all the other methods too, or you will get compiler errors. Your IDE should automatically implement all the methods.
The code below is a testable class that should print out some text when control+A has been pushed on the keyboard, and will also display an image in the system tray. This is all dependent on the system tray being supported by your operating system.
My issue is that the text is not being printed out when I push control+A, it is only printed when I press the item in the system tray.
/**
*
* #author Tyluur
* #since Aug 23, 2013
*/
public class Testable {
public static void main(String... args) {
registerTrayItems();
}
private static void registerTrayItems() {
if (SystemTray.isSupported()) {
SystemTray tray = SystemTray.getSystemTray();
TrayIcon icon = null;
MenuShortcut shortcut = new MenuShortcut(KeyEvent.VK_A);
MenuItem menuItem = new MenuItem("Toggle", shortcut);
menuItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.err.println("The action has been called!");
}
});
PopupMenu popup = new PopupMenu();
popup.add(menuItem);
try {
icon = new TrayIcon(new ImageIcon(new URL("http://i.imgur.com/xQoz2TN.png")).getImage(), "Typer", popup);
tray.add(icon);
} catch (MalformedURLException | AWTException e) {
e.printStackTrace();
}
}
}
}
The reason your code is not working is because Java is not 'globally' listening for your key event, but only when the menu has your focus and is shown.
This is also the reason why there is no possibility to write a pure Java keylogger. Java only allows you to capture window-directed messages.
A workaround would be to implement one of these options:
Use JNI/JNA/whatever native wrapper to access global key hooking
Use an invisible window, always being on top and not shown in the system tray that captures the events. I would not suggest using this one as it may either not work like a charm or annoys your user.
The top approach is not a hard one but will require you to use native access and therefor your application becomes platform-specific.
Good luck!
From the API, it looks like you should try this constructor for the MenuItem()
MenuShortcut shortcut = new MenuShortcut(KeyEvent.VK_A, false);
as the default is to require that the Shift key be pressed too.
Hi I've got a little Swing Application with a Menu.
First two attributes containing the menues text are created, then the lookandfeel is set to windows and at last the menues are filled.
Here is the source code:
private JMenu[] Menue={new JMenu("File")};
private JMenuItem[][] MenuItemsString ={{new JMenuItem("Import"),new JMenuItem("Export")}};
...
public window(){
super ("Q3MeshConverter");
plate = new JPanel(new BorderLayout());
try{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");// set Windows lookandfeel
}
catch(Exception x){
}
menuBar = new JMenuBar();
...
setJMenuBar(menuBar);
JMenu[] Menu =Menue;
JMenuItem[][] MenuItems =MenuItemsString;
for(int m=0;m<Menu.length;m++){// loop trough the Menu(es)
menuBar.add(Menu[m]);
for(int mi=0;mi<MenuItems[m].length;mi++){// loop through the MenuItems
Menu[m].add(MenuItems[m][mi]);
MenuItems[m][mi].addActionListener(this);
}
}
...
setContentPane (plate);
}
And that's the ugly output:
Why does it looks like this?
There is no magic how a component created before the LAF change can know about it, you have to tell it :-)
SwingUtilities.updateComponentTreeUI(someComponent);
Set the look and feel in your main method:
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) { }
}
Basically i want to be able to allow the user to save bookmarks which are then put into a list on a submenu on a menubar. How would i go about programming a general function for any number of bookmarks that may be added, i basically want the items to put the URL into a textbox when clicked. Would i need to create a new class for this, or is there an inbuilt function?
My program is a simple RSS reader written in Java using Swing.
You need to add a MenuListener to the menu item that you want to be dynamic.
In the void menuSelected(MenuEvent e) method, implement the construction of the submenus.
In a first implementation, you can first reset the content of your menu and then rebuid it from scratch instead of updating it :
JMenu menu = new JMenu("Bookmarks");
menu.addMenuListener(new MyMenuListener());
private class MyMenuListener implements MenuListener {
public void menuCanceled(MenuEvent e) { }
public void menuDeselected(MenuEvent e) { }
public void menuSelected(MenuEvent e) {
JMenu menu = (JMenu) e.getSource();
populateWindowMenu(menu);
}
}
void populateWindowMenu(JMenu windowMenu) {
windowMenu.removeAll();
// Populate the menu here
}