I want when user press enter button on keyboard, then program should function like when click on ok button.
My code:
public class T3 extends JFrame implements ActionListener {
JButton okBtn;
public T3() {
this.setFocusable(true);
this.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
// if enter button is pressed in keyboard, then show "Enter Button pressed" message
}
#Override
public void keyPressed(KeyEvent e) {
// if enter button is pressed in keyboard, then show "Enter Button pressed" message
}
#Override
public void keyReleased(KeyEvent e) {
//To change body of implemented methods use File | Settings | File Templates.
}
});
add(createForm(), BorderLayout.NORTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 500);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new T3();
}
});
}
public JPanel createForm() {
JPanel panel = new JPanel();
okBtn = new JButton("Ok");
okBtn.addActionListener(this);
panel.add(okBtn);
return panel;
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == okBtn) {
System.out.println("Enter Button pressed");
}
}
}
Now, Not react !
KeyListeners don't work on containers when a child component has the focus. You will need an application wide KeyListener. Check out this SO question:
Setting up application wide Key Listeners
Related
Like I described in the title, I am required to make a JButton clicked if a key from a keyboard is pressed. For example :
ActionListenerClass actionListener = new ActionListenerClass();
KeyListenerClass actionListener = new KeyListenerClass();
JButton aButton = new JButton("A");
aButton.setActionCommand("A");
aButton.addActionListener(actionListener);
aButton.addKeyListener(keyListener);
When "A" is pressed from the keyboard, button A will perform a doClick() and send the action command to a private class of the action listener for event handling. Now I have read a lot of solution from stack overflow, and they all used key binding, which is to bind between an input map and an action map. The thing is I absolutely have to use a key listener with a private class but not the binding. The only thing I can guess now is the keyListener above have to somehow receive the keyboard input and perform doClick on the button it is binded to in a keyPressed method, which I have try and it didn't work at all.
Edit: Here's my entire code.
CalculatorViewController.java
import java.awt.*;
import java.awt.event.*;
import java.util.regex.Pattern;
import javax.swing.*;
/**Create the app GUI
* #author Bach Le
* #version 1.0
* #see java.awt, java.awt.event, javax.swing
* #since 12.0.1
*/
public class CalculatorViewController extends JPanel {
private JButton backSpaceButton;
public CalculatorViewController() {
Controller controller = new Controller();
KeyController keyController = new KeyController();
setBorder(BorderFactory.createMatteBorder(5, 5, 5, 5,Color.black));//Adding the panel border
backSpaceButton = new JButton("\u21DA");
backSpaceButton.setPreferredSize(new Dimension(52,55));
backSpaceButton.setOpaque(false);//set transparency
backSpaceButton.setContentAreaFilled(false);
backSpaceButton.setBorderPainted(false);
backSpaceButton.setActionCommand("Backspace Button");//set the action command
backSpaceButton.addActionListener(controller);//add action listener
backSpaceButton.setToolTipText("Backspace (Alt+B)");//set tooltip text
backSpaceButton.setFont(font);//set the font
backSpaceButton.addKeyListener(keyController);
add(backSpaceButton) ;
}
private class Controller implements ActionListener{
public void actionPerformed(ActionEvent e) {
//event handling here
}
}
private class KeyController implements KeyListener{
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==65) {
backSpaceButton.doClick();
}
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
}
2.Calculator.java
public class Calculator {
public static void main(String[] args) {
CalculatorViewController pane = new CalculatorViewController();
JFrame frame = new JFrame("Calculator");
frame.setContentPane(pane);
frame.setSize(380, 520);
frame.setLocationByPlatform(true);
frame.setResizable(true);
frame.setVisible(true);
}
}
Focus on CalculatorViewController, I am trying to make backSpaceButton clicked when A is pressed (Of course it is the actual backspace button but I will fix it later), so it will send its action command to the action listener registered to it, which will be processed in the method of Controller inner class. I am not sure the proper way to achieve this.
Adding a KeyListener will only work for components with focus. You would not want to add the KeyListener to the JButtons, because only one JButton will be in focus.
For just setting a value you could use setMnemonic but then you would have to use a modifier (such as 'alt) when you press the key.
The 'correct' way to do this is to use key bindings
Here is an example with two buttons.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ButtonKeys{
public void buildGui(){
JFrame frame = new JFrame("key buttons");
JPanel panel = new JPanel(new BorderLayout());
JButton a = new JButton("A");
a.addActionListener(evt->{ System.out.println("a pressed");});
JButton b = new JButton("B");
b.addActionListener(evt->{ System.out.println("b pressed");});
panel.add(a, BorderLayout.EAST);
panel.add(b, BorderLayout.WEST);
frame.setContentPane(panel);
frame.setVisible(true);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
KeyStroke us = KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, false);
panel.getInputMap().put(us, "A");
panel.getActionMap().put("A", new AbstractAction(){
#Override
public void actionPerformed(ActionEvent evt){
a.doClick();
}
});
KeyStroke us2 = KeyStroke.getKeyStroke(KeyEvent.VK_B, 0, false);
panel.getInputMap().put(us2, "B");
panel.getActionMap().put("B", new AbstractAction(){
#Override
public void actionPerformed(ActionEvent evt){
b.doClick();
}
});
a.setFocusable(false);
b.setFocusable(false);
}
public static void main(String[] args){
EventQueue.invokeLater( new ButtonKeys()::buildGui);
}
}
I made the buttons to not obtain focus because if they get focus then their input map will be used.
This code should work for you. For the KeyListener I used a KeyAdapter more here as it is more convenient if you simply need to use one of the methods. You can of course move the Listeners to separate own classes if needed, but the behavior would stay the same.
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton btn = new JButton("A");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Button clicked");
}
});
btn.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == 'A' || e.getKeyChar() == 'a') {
((JButton) e.getSource()).doClick();
}
}
});
panel.add(btn);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(0, 0, 800, 600);
frame.getContentPane().add(panel);
frame.setVisible(true);
}
If you really need to use a KeyListener, it would look like this:
btn.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == 'A' || e.getKeyChar() == 'a') {
((JButton) e.getSource()).doClick();
}
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
});
I'm running an application with similar behaviour to that in the test case below.
The problem is that when you switch focus to a different window by clicking on it and keeping the below application frame in view and then click directly into the text field with the focusGained listener, close the dialog and then all key input will be lost to the all of the text fields in the application.
If you click anywhere in the application first or the icon in the task bar to gain focus back then this does not occur.
This is Java 8 specific - in Java 7 it will not lose focus, not sure about java 9 but that is not an option anyway
The test case below demonstrates this behaviour.
public class FocusTest extends JFrame
{
JTextField noFocus;
public static void main(String[] args)
{
FocusTest ft = new FocusTest();
ft.setVisible(true);
}
public FocusTest()
{
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setBounds(100,100,300,150);
setLayout(new GridLayout(3,1, 2, 2));
setTitle("Losing keyboard...");
noFocus = new JTextField();
add(noFocus);
JTextField jft = new JTextField();
jft.addFocusListener(new FocusAdapter()
{
#Override
public void focusGained(FocusEvent e)
{
createDialog().setVisible(true);
noFocus.requestFocusInWindow();
}
});
add(jft);
JButton jb = new JButton("OPEN");
jb.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand().equals("OPEN"))
createDialog().setVisible(true);
}
});
add(jb);
}
private JDialog createDialog()
{
final JDialog jd = new JDialog(this, true);
jd.setLocationRelativeTo(this);
jd.setLayout(new BorderLayout());
jd.getContentPane().add(new JTextField(), BorderLayout.CENTER);
JButton jb = new JButton("Close");
jb.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand().equals("Close"))
jd.dispose();
}
});
jd.getContentPane().add(jb, BorderLayout.SOUTH);
jd.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
jd.pack();
return jd;
}
}
Not exactly sure what's happening, but one solution is to use a SwingUtilities.invokeLater():
#Override
public void focusGained(FocusEvent e)
{
noFocus.requestFocusInWindow();
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createDialog().setVisible(true);
}
});
}
This will allow the text field to get focus properly before the dialog is made visible.
This is my first question and I'm realy sorry for my English. I don't want to navigation in JComboBox's dropdown list show the selected item in the "JComboBox's main field" (sorry, don't know how to call it, see the images).
This is what happen when I navigate in list:
But I want something like this:
and when I press Enter or clicked on item, it appear in the main field.
Here is my code:
import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.*;
public class ComboTest {
JFrame frame;
JPanel panel;
String[] choices = new String[]{
"Java",
"Python",
"C++",
"PHP",
"Perl"
};
JComboBox<String> comboBox = new JComboBox<>(choices);
JTextComponent textComponent;
public static void main(String[] args){
new ComboTest();
}
public ComboTest() {
frame = new JFrame();
panel = new JPanel();
textComponent = (JTextComponent) comboBox.getEditor().getEditorComponent();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 150);
frame.setResizable(false);
panel.setLayout(new FlowLayout());
comboBox.setEditable(true);
comboBox.setSelectedItem(null);
panel.add(comboBox);
frame.add(panel);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Try this code block
comboBox.addPopupMenuListener(new PopupMenuListener() {
#Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
//when Popupmenu is visible, remove the combobox editor text
comboBox.getEditor().setItem(null);
}
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
}
#Override
public void popupMenuCanceled(PopupMenuEvent e) {
}
});
Thanks to zilk. Your answer helped me to solve this. The listener addPopupMenuListener doesn't work for me. But when I changed the addPopupMenuListener to addItemListener, everything worked fine.
comboBox.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(final ItemEvent itemEvent) {
comboBox.getEditor().setItem(null);
comboBox.getEditor().getEditorComponent().addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
if(e.getKeyCode() == KeyEvent.VK_ENTER)
{
comboBox.getEditor().setItem(itemEvent.getItem());
}
}
});
}
});
Well what i'm trying to do is change the text of the JRadioButton's when they're selected, i got them to change the color. I know I can do it by putting the code to change the text inside the dedicated event handling method specific to each button, but how do I do it so that I use A DIFFERENT event handling method that just changes the buttons? I already created one but it doesn't work, here's the code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class LessonTwenty extends JFrame implements ActionListener{
JRadioButton b1,b2;
JTextArea t1;
JScrollPane s1;
JPanel jp = new JPanel();
public LessonTwenty()
{
b1= new JRadioButton("green");
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
jp.setBackground(Color.GREEN);
}
});
b2= new JRadioButton("red");
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
jp.setBackground(Color.RED);
}
});
//Method to change the text of the JRadion Buttons, what i'm trying to make work
new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(b1.isSelected()){
b1.setText("Welcome");
}
else if(b2.isSelected()){
b2.setText("Hello");
}
}
};
jp.add(b1);
jp.add(b2);
this.add(jp);
setTitle("Card");
setSize(700,500);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String [ ] args){
new LessonTwenty();
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
if i understand you right, you want do do something like this:
//Method to change the text of the JRadion Buttons, what i'm trying to make work
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(b1.isSelected()){
b1.setText("Welcome");
}
else if(b2.isSelected()){
b2.setText("Hello");
}
}
};
b1= new JRadioButton("green");
b1.addActionListener(al);
b2= new JRadioButton("red");
b2.addActionListener(al);
ie. you define one ActionListener which you use in all your objects.
The anonymous object you define in your original code does absolutely nothing, it just creates an ActionListener which nobody can ever access, since it is not assigned to any Button.
Maybe this could help
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(e.getSource() == b1){
b1.setText("Welcome");
} else if(e.getSource() == b2){
b2.setText("Hello");
}
}
};
I want to create a Toolbar in my application. If you click a button on that toolbar, it will pop up a menu, just like in Eclipse's toolbar. I don't know how to do this in Swing. Can someone help me please? I've tried Google but found nothing.
This is way harder in Swing than it needs to be. So instead of pointing you to tutorials I've created a fully working example.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class ToolbarDemo {
public static void main(String[] args) {
final JFrame frame = new JFrame();
frame.setPreferredSize(new Dimension(600, 400));
final JToolBar toolBar = new JToolBar();
//Create the popup menu.
final JPopupMenu popup = new JPopupMenu();
popup.add(new JMenuItem(new AbstractAction("Option 1") {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(frame, "Option 1 selected");
}
}));
popup.add(new JMenuItem(new AbstractAction("Option 2") {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(frame, "Option 2 selected");
}
}));
final JButton button = new JButton("Options");
button.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
popup.show(e.getComponent(), e.getX(), e.getY());
}
});
toolBar.add(button);
frame.getContentPane().add(toolBar, BorderLayout.NORTH);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
I don't see why this is harder than it needs to be or why you should use a MouseListener. The solution by Steve McLeod works, but where the menu appears depends on where the mouse was clicked. Why not just use an ActionListener as normally used for a JButton. It seems neither harder nor less hard.
final JPopupMenu menu = new JPopupMenu();
menu.add(...whatever...);
final JButton button = new JButton();
button.setText("My Menu");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
menu.show(button, button.getBounds().x, button.getBounds().y
+ button.getBounds().height);
}
});
This positions the menu about the same as a menu in a JMenuBar for me, and the position is consistent. You could place it differently by modifying the x and y in menu.show().
Here is a simple and nice class
import javax.swing.JPopupMenu;
import javax.swing.JToggleButton;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class MenuButton extends JToggleButton {
JPopupMenu popup;
public MenuButton(String name, JPopupMenu menu) {
super(name);
this.popup = menu;
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ev) {
JToggleButton b = MenuButton.this;
if (b.isSelected()) {
popup.show(b, 0, b.getBounds().height);
} else {
popup.setVisible(false);
}
}
});
popup.addPopupMenuListener(new PopupMenuListener() {
#Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
MenuButton.this.setSelected(false);
}
#Override
public void popupMenuCanceled(PopupMenuEvent e) {}
});
}
}
I think it's the same as in AWT.
You should put an ActionCommand on that button and when it's executed show the pop-up menu according to the mouse coordinates.
See the section Bringing Up a Popup Menu, in How to Use Menus.
I'm not sure I understand you correctly but if you want to know how to make toolbars in Swing check this
Java Tutorials: How to Use Tool Bars and this
Java Tutorials: How to Use Actions
Above, Adam Goode asked,
Does your solution have the behavior where if you click the button again with the menu up, it pops up the menu again, instead of dismissing it?
This turned out to be a testing task. I finally solved it with an invokeLater to re-vanish the popup in that particular case. My solution also allows the client to tailor the button and the popup menu.
/**
* A button that will popup a menu.
* The button itself is a JLabel and can be adjusted with all
* label attributes. The popup menu is returned by getPopup;
* menu items must be added to it.
* <p>
* Clicks outside the menu will dismiss it.
*/
public class MenuButton extends JLabel
implements MouseListener, PopupMenuListener {
JPopupMenu popMenu;
#SuppressWarnings("")
public MenuButton() {
super();
popMenu = new JPopupMenu();
addMouseListener(this);
popMenu.addPopupMenuListener(this);
}
public JPopupMenu getPopup() { return popMenu; }
#Override
public void mousePressed(MouseEvent e) {
if ( ! popMenu.isShowing()) {
popMenu.show(this, 0, getBounds().height);
}
}
#Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
SwingUtilities.invokeLater(()->{
if (popMenu.isShowing()) {
// if shpwing, it was hidden and reshown
// by a mouse down in the 'this' button
popMenu.setVisible(false);
}
});
}
#Override public void mouseClicked(MouseEvent e) { }
#Override public void mouseReleased(MouseEvent e) { }
#Override public void mouseEntered(MouseEvent e) { }
#Override public void mouseExited(MouseEvent e) { }
#Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) { }
#Override public void popupMenuCanceled(PopupMenuEvent e) { }
} // end MenuButton
Sample invocation
MenuButton button = new MenuButton();
JPopupMenu menu = button.getPopup();
menu.add("Browse Sample");
menu.add("Save As ...");
Icon hamburger = IOUtils.loadIconResource(
IndexGofer.class, "images/hamburgerMenu.png");
(IOUtils is on page http://physpics.com/Java/tools/
You should use your own tool to load an icon.)
button.setIcon(hamburger);
button.setOpaque(false);