I have to run a method manually when pressing the key Alt+H
if("The key pressed==(Alt+H)"){
callMethod();
}
public void callMethod(){
//Some codes here
}
How I can actually do this in Java. Please give me a simple way to do this.
It's worth reading here about Oracle Tutorial - Enabling Keyboard Operation where it is explained in details along with sample.
Read more about on Oracle Tutorial - How to Use Key Bindings
Some example directly from the above tutorial:
//Setting the mnemonic when constructing a menu item:
menuItem = new JMenuItem("A text-only menu item",
KeyEvent.VK_H);
//Setting the mnemonic after creation time:
menuItem.setMnemonic(KeyEvent.VK_H);
//Setting the accelerator:
menuItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_H, ActionEvent.ALT_MASK));
Read more here Oracle Tutorial - How to Use Buttons, Check Boxes, and Radio Buttons
Sample code: (Alt-H would click the Middle button)
JButton b2 = new JButton("Middle button", middleButtonIcon);
b2.setMnemonic(KeyEvent.VK_H);
If using menus then you can use setMnemonic(), see How to Use Menus for examples. Another option is to use Key Bindings. For example:
import java.awt.event.*;
import javax.swing.*;
public class TestKeys {
private static void createAndShowGUI() {
final JFrame frame = new JFrame("Keys");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
KeyStroke escapeKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_H, InputEvent.ALT_MASK);
Action testAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(frame, "Alt-H pressed");
}
};
frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escapeKeyStroke, "TestAction");
frame.getRootPane().getActionMap().put("TestAction", testAction);
JLabel label = new JLabel("Hit Alt-H");
label.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
frame.add(label);
frame.setLocationByPlatform(true);
frame.pack();
frame.setVisible(true);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Best method is to use setMnemonic() because its the the simplest.
check this article for more http://www.herongyang.com/Swing/JMenuBar-Set-Keyboard-Mnemonics-on-Menu-Items.html
private JMenu getColorMenu() {
JMenu myMenu = new JMenu("Color");
ButtonGroup myGroup = new ButtonGroup();
JRadioButtonMenuItem myItem = new JRadioButtonMenuItem("Red");
myItem.setSelected(true);
myItem.setMnemonic(KeyEvent.VK_R);
myItem.addActionListener(this);
myItem.addMenuKeyListener(this);
myGroup.add(myItem);
myMenu.add(myItem);
myItem = new JRadioButtonMenuItem("Green");
myItem.setMnemonic(KeyEvent.VK_G);
myItem.addActionListener(this);
myItem.addMenuKeyListener(this);
myGroup.add(myItem);
myMenu.add(myItem);
myItem = new JRadioButtonMenuItem("Blue");
myItem.setMnemonic(KeyEvent.VK_B);
myItem.addActionListener(this);
myItem.addMenuKeyListener(this);
myGroup.add(myItem);
myMenu.add(myItem);
return myMenu;
Related
I'm having difficulty using anonymous inner classes with actionListener. Can someone explain to me what is wrong with my code and how to use anonymous inner classes with actionListener. I'm trying to make a menu bar in one class and the action listener in the other. I ran into some difficulty when I tried using anonymous inner classes. The java website wasn't clear. Can you please explain it to me and help me fix my code.
public class Listener implements ActionListener {
HangmanView hangmanView = new HangmanView();
JFrame dialogFrame = new JFrame();
ImageIcon logo = new ImageIcon("logo.png");
public void listener1() {
hangmanView.getMenuItem().addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {// right click key
JOptionPane.showMessageDialog(dialogFrame, "Developer: Joe"
, "Developer",
JOptionPane.INFORMATION_MESSAGE, logo);
}// end actionPerformed method
});
}
}
another class:
public class HangmanView {
public JMenuItem getMenuItem() {
JMenuItem menuItem = new JMenuItem("Developer", KeyEvent.VK_T);
menuItem.addActionListener(new Listener());
return menuItem;
}
public JMenuBar menuBar() {
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
menuBar.add(menu);
menu.add(getMenuItem());// return here
return menuBar;
}
If you're trying to implement the listener for different JMenuItems, what I would do instead is create a custom Action class that you can use for multiple JMenuItems, as JMenuItems are a good example of when to use an Action.
private class MyAction extends AbstractAction {
String name;
public MyAction(String name, Icon icon) {
super(name, icon);
this.name = name;
}
public MyAction(String name, Icon icon, String desc,
Integer mnemonic, KeyStroke accelorator) {
super(name, icon);
putValue(Action.SHORT_DESCRIPTION, desc);
putValue(Action.MNEMONIC_KEY, mnemonic);
putValue(Action.ACCELERATOR_KEY, accelorator);
this.name = name;
}
#Override
public void actionPerformed(ActionEvent e) {
switch (name) {
case "menu1Action":
// do something for menuItem1
break;
case "menu2Action":
// do something for menuItem2
break;
case "menu3Action":
// do something for menuItem3
break;
}
}
}
Have this class as an inner class of HangmanView. You can then create an instance of this custom Action class for each JMenuItem. Here's a example
Action menu1Action = new MyAction(
/* arg 1 */ "menu1Action",
/* arg 2 */ someIcon,
/* arg 3 */ "Some Short description of the action",
/* arg 4 */ new Integer(KeyEvent.VK_T),
/* arg 5 */ KeyStroke.getKeyStroke(KeyEvent.VK_T, ActionEvent.CTRL_MASK));
The first argument is the name of the action. This name will be the name that you will see in the menu
The second argument is the icon that you will see in the menu next to the name.
The third argument is the Description of the menu item action
The fourth argument is the Mnemonic (i.e. Alt + T).
The fifth argument is the Accelerator (i.e. Ctrl + T).
When you add an Action to a JMenu, the title of that Action will automatically get placed as what you see in the JMenu. So all you need to do is add this custom Action to your JMenu. You don't ever have to actually create a JMenuItem at all. The Action will serve as the replacement for the JMenuItem. Just add all your MyAction objects to the JMenu.
menu.add(menu1Action);
What I have left out, is the implementation for each separate switch case in the actionPerformed. The case will be what you name the action in the constructor. Because I named the Action "menu1Action", I should have the corresponding name in the the switch case. In that case, you can do your JOptionPane or what ever else you wish to perform when that JMenuItem is clicked or accessed by keyboard.
Another great benefit of using an Action is that it can serve multiple purposes. With the same MyAction menu1Action you created, you can use the same Action for a JToolBar. Without any alteration to the above menu1Action, you could just do this:
JTooBar toolbar = new JToolBar();
toolbar.add(menu1Action);
Now in your tool bar and in your menu item, you have the same action. The tool bar will only show the icon and not the name.
Here is an example. What I do is create three different MyAction objects. One for left-alignment, one for center-alignment, and one for right-alignment. Each of these actions is used three separate times for three separate components, a menu item, a toll bar and a button
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ActionInterfaceDemo extends JFrame {
static JPanel buttonPanel = new JPanel();
static FlowLayout flowLayout = new FlowLayout();
public ActionInterfaceDemo(){
ImageIcon centerIcon = new ImageIcon(
ActionInterfaceDemo.class.getResource("image/centeralignment.png"));
ImageIcon rightIcon = new ImageIcon(
ActionInterfaceDemo.class.getResource("image/rightalignment.png"));
ImageIcon leftIcon = new ImageIcon(
ActionInterfaceDemo.class.getResource("image/leftalignment.png"));
Action leftAction = new MyAction("Left", leftIcon,
"Left alignment for the buttons in the panel",
new Integer(KeyEvent.VK_L),
KeyStroke.getKeyStroke(KeyEvent.VK_L, ActionEvent.CTRL_MASK));
Action rightAction = new MyAction("Right", rightIcon,
"Right alignment for the buttons in the panel",
new Integer(KeyEvent.VK_R),
KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.CTRL_MASK));
Action centerAction = new MyAction("Center", centerIcon,
"Center alignment for the buttons in the panel",
new Integer(KeyEvent.VK_C),
KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK));
JMenuBar menuBar = new JMenuBar();
JMenu menuAlignment = new JMenu("Alignment");
setJMenuBar(menuBar);
menuBar.add(menuAlignment);
menuAlignment.add(leftAction);
menuAlignment.add(centerAction);
menuAlignment.add(rightAction);
JToolBar toolBar = new JToolBar("Alignment");
toolBar.setBorder(BorderFactory.createLineBorder(Color.BLUE));
toolBar.add(leftAction);
toolBar.add(centerAction);
toolBar.add(rightAction);
buttonPanel.setLayout(flowLayout);
JButton jbtLeft = new JButton(leftAction);
JButton jbtCenter = new JButton(centerAction);
JButton jbtRight = new JButton(rightAction);
buttonPanel.add(jbtLeft);
buttonPanel.add(jbtCenter);
buttonPanel.add(jbtRight);
add(toolBar, BorderLayout.EAST);
add(buttonPanel, BorderLayout.CENTER);
pack();
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run(){
new ActionInterfaceDemo();
}
});
}
private class MyAction extends AbstractAction {
String name;
public MyAction(String name, Icon icon, String desc,
Integer mnemonic, KeyStroke accelorator) {
super(name, icon);
putValue(Action.SHORT_DESCRIPTION, desc);
putValue(Action.MNEMONIC_KEY, mnemonic);
putValue(Action.ACCELERATOR_KEY, accelorator);
this.name = name;
}
#Override
public void actionPerformed(ActionEvent e) {
switch (name) {
case "Left":
flowLayout.setAlignment(FlowLayout.LEFT);
break;
case "Right":
flowLayout.setAlignment(FlowLayout.RIGHT);
break;
case "Center":
flowLayout.setAlignment(FlowLayout.CENTER);
break;
}
buttonPanel.revalidate();
}
}
}
You can press the "Left" in either the menu, the toolbar, or the button and they will produce the same result, as they are derived from the same Action.
Here are the images I used if you want to test it out
Note You don't have to use either of these exact constructors. You can create your own with different arguments. This is just a custom one I like to use.
Aslo See How to use Action tutorial
Listener, being an ActionListener through its inheritance hierarchy,
public class Listener implements ActionListener {
needs to implement an actionPerfomed(ActionEvent) method
#Override
public void actionPerformed(ActionEvent e) {
// implement it
}
However, since you seem to be adding an anonymous ActionListener, just don't have your Listener class implement ActionListener. Remove that bit.
Your object-oriented programming is all over the place. Your code in the OP looks like it's supposed to be some kind of GUI with different classes somehow working together but it's just creating new objects all over the place. There are too many reasons it doesn't work. I'd suggest you stick to something simple until you have a better grasp on how all this works.
You also got a very good suggestion in your other question that's a lot like this one but you haven't really followed it. Your code does something completely different.
Here is a very basic GUI. You have one object that has everything as fields. Everything is in one place. The containing object is the listener and decides what to do based on the event source. You should stick with a design like this until you are more comfortable with OOP.
public class HangmanView
implements ActionListener {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new HangmanView().setFrameVisible(true);
}
});
}
private JFrame theFrame = new JFrame("Main Window");
private JPanel theContent = new JPanel();
private JMenuBar theBar = new JMenuBar();
private JMenu fileMenu = new JMenu("File");
private JMenuItem exitMenuItem = new JMenuItem("Exit");
private JMenuItem devMenuItem = new JMenuItem("Developer");
public HangmanView() {
assert SwingUtilities.isEventDispatchThread();
exitMenuItem.addActionListener(this);
devMenuItem.addActionListener(this);
fileMenu.add(exitMenuItem);
theBar.add(fileMenu);
theBar.add(devMenuItem);
theContent.setPreferredSize(new Dimension(500, 500));
theFrame.setJMenuBar(theBar);
theFrame.setContentPane(theContent);
theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
theFrame.pack();
theFrame.setLocationRelativeTo(null);
}
public void setFrameVisible(boolean vis) {
theFrame.setVisible(vis);
}
#Override
public void actionPerformed(ActionEvent ae) {
if(ae.getSource() == devMenuItem) {
showDevDiag();
} else if(ae.getSource() == exitMenuItem) {
systemExit();
}
}
private void showDevDiag() {
JOptionPane.showMessageDialog(
theFrame,
"Developer: Joe",
"Developer",
JOptionPane.INFORMATION_MESSAGE,
null
);
}
private void systemExit() {
System.exit(0);
}
}
if I should use anonymous class, that's what should be done:
public static void main(String args[]){
/*bla bla bla...*/
JButton button1=new JButton("button1");
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae){
/*bla bla bla...*/
}
};
}
On the other hand, I always do this:
public class Class implements Runnable,ActionListener
{
private static Map<Thread,ActionEvent> THREAD_ATTRIB
=new HashMap<Thread,ActionEvent> (0);
JButton button1=new JButton("button1");
JButton button2=new JButton("button2");
//constructor
public Class(){
this.button1.addActionListener(this);
this.button2.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent ae){
Thread thread=new Thread(this);
THREAD_ATTRIB.put(thread,ae);
thread.start();
}
#Override
public void run(){
ActionEvent ae=THREAD_ATTRIB.get(Thread.currentThread());
if(ae!=null){
Object source=ae.getSource();
if(source.equals(this.button1){
/*bla bla bla...*/
} else if(source.equals(this.button2){
/*bla bla bla...*/
}
} else{
/*bla bla bla...*/
}
}
}
I have created a frame in Java which has some textfields and buttons in it. Assuming that user wants more textfields (for example to add more data), I want to put a button and when a user clicks the button, then a new textfield should appear. then user can fill data in it and again by clicking that button another textfield should appear.
How can I do this ? What code I need to write for the button to show more and more text fields by clicking button?
Thank you !
It would be wise that instead of adding components to your JFrame directly, you add them to a JPanel. Though related to your problem, have a look at this small example, hopefully might be able to give you some hint, else ask me what is out of bounds.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JFrameExample
{
private JFrame frame;
private JButton button;
private JTextField tfield;
private String nameTField;
private int count;
public JFrameExample()
{
nameTField = "tField";
count = 0;
}
private void displayGUI()
{
frame = new JFrame("JFrame Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(0, 1, 2, 2));
button = new JButton("Add JTextField");
button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
tfield = new JTextField();
tfield.setName(nameTField + count);
count++;
frame.add(tfield);
frame.revalidate(); // For JDK 1.7 or above.
//frame.getContentPane().revalidate(); // For JDK 1.6 or below.
frame.repaint();
}
});
frame.add(button);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new JFrameExample().displayGUI();
}
});
}
}
Supposing that you have a main container called panel and a button variable button which is already added to panel, you can do:
// handle the button action event
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// create the new text field
JTextField newTextField = new JTextField();
// add it to the container
panel.add(newTextField);
panel.validate();
panel.repaint();
}
});
When adding the new text field, you may need to mention some layout related characteristics, depending on the layout manager you are using (for instance if you use GridBagLayout, you will need to specify the constraints).
I need some help with my ActionListener on my JMenuBar.
There's no error; however every time I click on a JMenuItem, it triggers all the action associated with the JMenuItem. My question is: am I doing it right in my ActionListener code? I'm not too sure about my ActionListener class. I'm trying to separate my ActionListener from my Button logic.
If anyone has any ideas on what I may be doing wrong, please point it out.
Here is my code:
package MenuBar;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class SimpleMenuBar{
private static final LayoutManager grid = new GridLayout(0, 1);
public JMenuBar MenuBar;
public JMenu MenuFile, MenuEdit, MenuOption;
public JMenuItem ItemNew, ItemOpen, ItemSave, ItemExit, ItemCopy, ItemCut, ItemPaste;
ButtonGroup direction;
JRadioButtonMenuItem forwardradio, backwardradio;
JCheckBoxMenuItem CheckCase;
String input = null;
public void Design()
{
JFrame frame = new JFrame("Simple Menubar");
frame.setSize(320, 320);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
MenuBar = new JMenuBar();
frame.setJMenuBar(MenuBar);
MenuBar.setLayout(grid);
//Menus
MenuFile = new JMenu("File");
MenuFile.setMnemonic(KeyEvent.VK_F);
MenuBar.add(MenuFile);
//sub Menus
ItemNew = new JMenuItem("New", KeyEvent.VK_N);
MenuFile.add(ItemNew);
ItemNew.setActionCommand("New");
ItemNew.addActionListener(new MenuBarMethod());
ItemOpen = new JMenuItem("Open", KeyEvent.VK_O);
MenuFile.add(ItemOpen);
ItemOpen.setActionCommand("Open");
ItemNew.addActionListener(new MenuBarMethod());
MenuFile.addSeparator();
ItemSave = new JMenuItem("Save", KeyEvent.VK_S);
MenuFile.add(ItemSave);
MenuFile.addSeparator();
ItemExit = new JMenuItem("Exit", KeyEvent.VK_X);
MenuFile.add(ItemExit);
MenuEdit = new JMenu("Edit");
MenuFile.setMnemonic(KeyEvent.VK_E);
MenuBar.add(MenuEdit);
ItemCopy = new JMenuItem("Copy", KeyEvent.VK_C);
KeyStroke ctrlCKeyStroke = KeyStroke.getKeyStroke("control C");
ItemCopy.setAccelerator(ctrlCKeyStroke);
MenuEdit.add(ItemCopy);
ItemCut = new JMenuItem("Cut", KeyEvent.VK_V);
KeyStroke ctrlVKeyStroke = KeyStroke.getKeyStroke("control V");
ItemCut.setAccelerator(ctrlVKeyStroke);
MenuEdit.add(ItemCut);
ItemPaste = new JMenuItem("Paste", KeyEvent.VK_Y);
KeyStroke ctrlYKeyStroke = KeyStroke.getKeyStroke("control Y");
ItemPaste.setAccelerator(ctrlYKeyStroke);
ItemPaste.setEnabled(false);
MenuEdit.add(ItemPaste);
MenuEdit.addSeparator();
MenuOption = new JMenu("Option");
Icon atIcon = new ImageIcon("option.png");
MenuOption.setIcon(atIcon);
MenuOption.setMnemonic(KeyEvent.VK_O);
direction = new ButtonGroup();
forwardradio = new JRadioButtonMenuItem("Forward Me", true);
forwardradio.setMnemonic(KeyEvent.VK_F);
MenuOption.add(forwardradio);
direction.add(forwardradio);
MenuEdit.add(MenuOption);
backwardradio = new JRadioButtonMenuItem("Backward Me");
backwardradio.setMnemonic(KeyEvent.VK_B);
MenuOption.add(backwardradio);
direction.add(backwardradio);
MenuOption.addSeparator();
CheckCase = new JCheckBoxMenuItem("Case Sensitive");
MenuOption.add(CheckCase);
direction.add(CheckCase);
MenuEdit.add(MenuOption);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable(){
public void run()
{
SimpleMenuBar MyMenu = new SimpleMenuBar();
MyMenu.Design();
}
});
}
}
It's an awful lot of code for just a menu bar. I haven't fully implemented the ActionListener. For testing purposes, I've only implemented it for two items: ItemNew and ItemOpen. Unfortunately, every time I click on the ItemNew menu item, it triggers the actions of both ItemNew and ItemOpen.
Here are is code for my action listener:
package MenuBar;
import java.awt.event.*;
import javax.swing.JOptionPane;
public class MenuBarMethod implements ActionListener{
public void actionPerformed(ActionEvent e)
{
if("New".equals(e.getActionCommand())){
JOptionPane.showMessageDialog(null, "Selected Item: " + e.getActionCommand());
}
if("Open".equals(e.getActionCommand())){
JOptionPane.showMessageDialog(null, "Selected Item: " + e.getActionCommand());
}
}
}
As a matter of personal preference, I prefer to use the Action API
The main reasons are
It centralise logic associated with a particular action, including name, key stroke, short cuts, icons etc
It's reusable. It's much easier to create an Action Object then it's to have recreate the menu item & the tool bar item & the popup menu item
It's well supported by other Swing components. Most Swing components that support the ActionListener API generally provide the means to supply an Action as well (JMenu.add(Action), JMenu(Action) etc)
It makes your code easier to read, much easier to read a single ActionPerformed method of an Action class then try and skim through multiple if statements
Take a look at How to Use Actions
IMHO
I would use the getSource method of ActionEvent instead of getActionCommand.
public class MenuBarMethod implements ActionListener{
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == ItemNew){
JOptionPane.showMessageDialog(null, "Selected Item: " + e.getActionCommand());
}
if(e.getSource() == ItemOpen){
JOptionPane.showMessageDialog(null, "Selected Item: " + e.getActionCommand());
}
}
}
I just joined, and am glad to be here~ So, this morning (at like 2am, but thats besides the point :P ) I was doing a little bit of Java tests with JFrame and other GUI stuff. This is my first time working with GUIs. I was trying to make a little java app that would act as a dream journaller. However, my progress was frozen when I encountered a problem i could not solve. My code is as follows.
import java.awt.*;
import javax.swing.*;
import java.applet.*;
public class Display extends Canvas
{
static final int WIDTH = 600;
static final int HEIGHT = 400;
public static String defaultEntry = "Dreams...";
public static final String TITLE = "Dream Journal Testing";
Button erase;
public static void main(String[] args)
{
Display d = new Display();
d.create();
}
public void create()
{
JFrame frame = new JFrame();
System.out.println("Running");
Panel cardOne = new Panel();
Panel p1 = new Panel();
Panel p2 = new Panel();
Panel p3 = new Panel();
Panel grid = new Panel();
cardOne.setLayout(new BorderLayout());
p1.setLayout(new GridLayout(2,1,3,6));
TextArea textArea1 = new TextArea(defaultEntry);
/*Font f1 = new Font("Courier", Font.PLAIN, 16);
setFont(f1);*/
Label l1 = new Label("Welcome to the Dream Journal! :)");
Label l2 = new Label("Type your dream below:");
p1.add(l1);
p1.add(l2);
p2.add(textArea1);
p3.setLayout(new FlowLayout(FlowLayout.CENTER));
Button ok = new Button("Save");
erase = new Button("Erase");
p3.add(erase);
p3.add(ok);
cardOne.add("North",p1);
cardOne.add("Center",p2);
cardOne.add("South",p3);
frame.add(cardOne);
//frame.add(cardOne);
//frame.setLocationRelativeTo(null);
frame.pack();
frame.setTitle(TITLE);
frame.setSize(WIDTH, HEIGHT);
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
System.out.println(textArea1.getText());
}
/*public boolean handleEvent(Event evt)
{
if(evt.target == erase)
{
System.out.println("it works");
return true;
}
else return super.handleEvent(evt);
}
*/
public boolean action(Event evt, Object arg)
{
if("Erase".equals(arg))
{
System.out.println("hello");
//textArea1.setText("");
}
return true;
}
}
The problem i have is I am not able to figure out how to make it so if the "Erase" AWT button is pushed, the system will print a line (as a test). I have tried
public boolean action(Event evt, Object arg)
And
public boolean handleEvent, but neither worked. Anyone have any suggestions for the Java noob that is me? Thanks!! :)
One way is to add an action listener to the button (e.g. for Save). Another way is to create an Action (e.g. for Erase).
Don't mix Swing with AWT components unless it is necessary. It is not worth even learning how to use AWT components at this point in time, use Swing only for best results and best help.
Here is a version of the app. using all Swing components.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Display
{
static final int WIDTH = 600;
static final int HEIGHT = 400;
public static String defaultEntry = "Dreams...";
public static final String TITLE = "Dream Journal Testing";
JButton erase;
public static void main(String[] args)
{
Display d = new Display();
d.create();
}
public void create()
{
JFrame frame = new JFrame();
System.out.println("Running");
JPanel cardOne = new JPanel();
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
JPanel p3 = new JPanel();
cardOne.setLayout(new BorderLayout());
p1.setLayout(new GridLayout(2,1,3,6));
JTextArea textArea1 = new JTextArea(defaultEntry);
JLabel l1 = new JLabel("Welcome to the Dream Journal! :)");
JLabel l2 = new JLabel("Type your dream below:");
p1.add(l1);
p1.add(l2);
p2.add(textArea1);
p3.setLayout(new FlowLayout(FlowLayout.CENTER));
JButton ok = new JButton("Save");
ok.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
System.out.println("Do " + ae.getActionCommand());
}
});
erase = new JButton(new EraseAction());
p3.add(erase);
p3.add(ok);
// Use the constants
cardOne.add(BorderLayout.PAGE_START,p1);
cardOne.add(BorderLayout.CENTER,p2);
cardOne.add(BorderLayout.PAGE_END,p3);
frame.add(cardOne);
frame.pack();
frame.setTitle(TITLE);
frame.setSize(WIDTH, HEIGHT);
frame.setResizable(false);
frame.setLocationByPlatform(true);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
System.out.println(textArea1.getText());
}
}
class EraseAction extends AbstractAction {
EraseAction() {
super("Erase");
}
#Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("Do " + arg0.getActionCommand());
}
}
First let me explain you the Funda of Event Handler....
- First of all there are Event Source, when any action take place on the Event Source, an Event Object is thrown to the call back method.
- Call Back method is the method inside the Listener (Interface) which is needed to be implemented by the Class that implements this Listener.
- The statements inside this call back method will dictate whats needed to be done, when the action is done on the Event Source.
Eg:
Assume
Event Source - Button
When Clicked - Event object is thrown at the call back method
Call back method - actionPerformed(ActionEvent e) inside ActionListener.
Now your case :
Now this can be done in 2 ways.....
1. Let you Display class implements the ActionListener, then Register the button with
the ActionListener, and finally implement the abstract method actionPerformed() of ActionListener.
Eg:
public class Display extends Canvas implements ActionListener{
public Display(){
// Your code....
setComponent(); // Initializing the state of Components
}
public void setComponent(){
// Your code.........
Button b = new Button("Click");
b.addActionListener(this); // Registering the button.
// Your code..........
}
public void actionPerformed(ActionEvent event) {
// Do here whatever you want on the Button Click
}
}
2. Use Anonymous class.
- Anonymous class are declared and initialized simultaneously.
- Anonymous class must implement or extend to only one interface or class resp.
Your Display class will NOT implement ActionListener here....
public class Display extends Canvas {
public Display(){
// Your code....
setComponent(); // Initializing the state of Components
}
public void setComponent(){
// Your code.........
Button b = new Button("Click");
// Registering the button and Implementing it
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event) {
// Do here whatever you want on the Button Click
}
});
// Your code..........
}
}
You need to implement ActionListner :
public class Display extends Canvas implements ActionListener
and add yourself to your button as such:
erase.addActionListener(this);
and then implement the required method:
public void actionPerformed(ActionEvent event) {
//do stuff
}
For more info, check out this tutorial on creating ActionListeners.
You'll find that this observable pattern is widely used the in Java GUI.
A couple high level critiques:
You are using many older AWT components (ie Button) when there are similar, but newer (read: more flexible) Swing components available (ie JButton). Take a look at this for a quick explanation on the difference.
The event model that you have implemented was revamped in 1997 to the observable pattern that I suggested above. If you would like to learn more, you can read this.
I need to create a combo box with multi-selection, how to achieve that?
I know, that the question is rather old, but for those, who still looks for solution of this problem, try the following code:
public class ComboSelections {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, UnsupportedLookAndFeelException {
UIManager.setLookAndFeel((LookAndFeel) Class.forName("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel").newInstance());
final JPopupMenu menu = new JPopupMenu();
JMenuItem one = new JCheckBoxMenuItem("One");
JMenuItem two = new JCheckBoxMenuItem("Two");
JMenuItem three = new JCheckBoxMenuItem("Three");
JMenuItem four = new JCheckBoxMenuItem("Four");
menu.add(one);
menu.add(two);
menu.add(three);
menu.add(four);
final JButton button = new JButton("Click me");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (!menu.isVisible()) {
Point p = button.getLocationOnScreen();
menu.setInvoker(button);
menu.setLocation((int) p.getX(),
(int) p.getY() + button.getHeight());
menu.setVisible(true);
} else {
menu.setVisible(false);
}
}
});
one.addActionListener(new OpenAction(menu, button));
two.addActionListener(new OpenAction(menu, button));
three.addActionListener(new OpenAction(menu, button));
four.addActionListener(new OpenAction(menu, button));
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.add(button);
frame.getContentPane().add(panel);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static class OpenAction implements ActionListener {
private JPopupMenu menu;
private JButton button;
private OpenAction(JPopupMenu menu, JButton button) {
this.menu = menu;
this.button = button;
}
#Override
public void actionPerformed(ActionEvent e) {
menu.show(button, 0, button.getHeight());
}
}
}
There are a few basic problems with creating custom combobox popup content (like a list with multiselection):
1. Default UI suggests JList usage as the content so to change that behavior you will have to change the whole ComboBoxUI
2. You cannot simply change the default combobox list into multiselection one due to the fact that only one value gets "selected" at the end and list has default rollover selection mouse listener, that will make you unable to choose more than one element
So i'd reccomend you to use simple JList instead of combobox or look into using some extended components libraries like JideSoft - they have this component and lots more which you won't be able to quickly create using Swing features.