Forgive me if I'm asking too big of a question, I trying to learn to code and I think I'm missing a big detail about KeyListiner. I am trying to make a simple program that "rolls a dice" and displays a picture of a number 1 to 6 when the users presses a key. My program doesn't seem to respond to any user input.
What am I doing wrong?
Thank you for any help, I'm just trying to learn so any advice is appreciated.
public class Dice {
public static void main (String arg[]) {
new DD();
}
}
class DD extends JPanel {
DD(){
JFrame frame = new JFrame();
ImageIcon icon = new ImageIcon("dice.jpg");
JLabel label = new JLabel(icon);
frame.add(label);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
addKeyListener(new Roll());
}
}
class Roll extends JFrame implements KeyListener {
public void keyPressed(KeyEvent event){}
public void keyReleased(KeyEvent event){}
public void keyTyped(KeyEvent event){
int d = event.getKeyCode();
if(d == KeyEvent.VK_UP){
int roll = (int) (Math.random()*6) + 1;
System.out.println(roll);
}
}
}
Let's take a closer look at your DD class...
class DD extends JPanel {
DD() {
JFrame frame = new JFrame();
ImageIcon icon = new ImageIcon("dice.jpg");
JLabel label = new JLabel(icon);
frame.add(label);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
addKeyListener(new Roll());
}
}
You create an instance of JFrame, from within the constructor of the JPanel, which is a questionable act...
You create a JLabel and add it to the JFrame
You show the JFrame
You add a KeyListener to the DD JPanel
But wait a minute, DD is never attached to any visible component, how could it ever possible be capable of receiving key events?!
KeyListener will only work when the component that it's registered to is focusable AND has focus, but if it's never displayed on the screen, it could never have focus!
To start with, I'd avoid using KeyListener, it has focus related issues, and instead use the Key Bindings API
For example...
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Dice {
public static void main(String[] args) {
new Dice();
}
public Dice() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DD());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
class DD extends JPanel {
DD() {
setLayout(new GridBagLayout());
JLabel label = new JLabel(" - ");
add(label);
addKeyBindingFor(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "Action.roll", new DiceRollAction(label));
}
protected void addKeyBindingFor(KeyStroke keyStroke, String name, Action action) {
InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = getActionMap();
inputMap.put(keyStroke, name);
actionMap.put(name, action);
}
public class DiceRollAction extends AbstractAction {
private JLabel label;
public DiceRollAction(JLabel label) {
this.label = label;
}
#Override
public void actionPerformed(ActionEvent e) {
int roll = (int) (Math.random() * 6) + 1;
label.setText(Integer.toString(roll));
}
}
}
}
Related
I am adding multiple Jlabel using for loop. What I want is on mouse click, the color of the selected JLabel should change and set to the default color on click of anotherJLabel.
Since you changed the state of the label, you need someway to change it back. The simplest solution is to maintain a reference to the last label that was changed and when the new label is clicked, reset it's state
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
HighlightMouseListener hml = new HighlightMouseListener();
for (int index = 0; index < 10; index++) {
JLabel label = new JLabel("Hello " + index);
label.addMouseListener(hml);
add(label, gbc);
}
}
}
public class HighlightMouseListener extends MouseAdapter {
private JLabel previous;
#Override
public void mouseClicked(MouseEvent e) {
Component source = e.getComponent();
if (!(source instanceof JLabel)) {
return;
}
JLabel label = (JLabel) source;
if (previous != null) {
previous.setBackground(null);
previous.setForeground(null);
previous.setOpaque(false);
}
previous = label;
label.setForeground(Color.WHITE);
label.setBackground(Color.BLUE);
label.setOpaque(true);
}
}
}
I still wonder if a JList would be a better and simpler solution, but since I don't know what you're doing, it's all I can do
The idea is to have one "global" JFrame which I can then add/remove JPanels as needed to make a smooth flowing application. Currently, when I try changing from the first JPanel to the second, the second won't display. My code is below:
Handler (class to run the app):
package com.example.Startup;
import com.example.Global.Global_Frame;
public class Handler
{
public Handler()
{
gf = new Global_Frame();
gf.getAccNum();
gf.setVisible(true);
}
public static void main(String[] args)
{
new Handler();
}
Global_Frame gf = null;
}
public static void main(String[] args)
{
new Handler();
}
Global_Vars gv = null;
Global_Frame gf = null;
}
Global Frame:
package com.example.Global;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import com.example.FirstRun.AccDetails;
import com.example.FirstRun.FirstTimeRun;
public class Global_Frame extends JFrame
{
private static final long serialVersionUID = 1L;
ActionListener val = new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
getUserDetails();
}
};
public Global_Frame()
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); // get look and feel based on OS
}
catch (ClassNotFoundException ex) // catch all errors that may occur
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
catch (InstantiationException ex)
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IllegalAccessException ex)
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
catch (UnsupportedLookAndFeelException ex)
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
EventQueue.invokeLater(new Runnable()
{
public void run() //run the class's constructor, therefore starting the UI being built
{
initComponents();
}
});
}
public void initComponents()
{
setPreferredSize(new Dimension(600, 400)); // setting measurements of jframe
revalidate(); // revalidate the elements that will be displayed
repaint(); // repainting what is displayed if going coming from a different form
pack(); // packaging everything up to use
setLocationRelativeTo(null); // setting form position central
}
public void getAccNum()
{
setPreferredSize(new Dimension(600, 400)); // setting measurements of jframe
FirstTimeRun panel1 = new FirstTimeRun(val);
add(panel1);
revalidate();
repaint();
pack();
}
public void getUserDetails()
{
getContentPane().removeAll();
resizing(750, 500);
AccDetails panel2 = new AccDetails();
add(panel2);
revalidate();
repaint();
pack();
}
private void resizing(int width, int height)
{
timer = new Timer (10, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0)
{
getContentPane().removeAll();
setPreferredSize(new Dimension(sizeW, sizeH));
revalidate();
repaint();
pack();
if (!wToggle)
sizeW += 2;
if (!hToggle)
sizeH += 2;
if (toggle)
{
setLocationRelativeTo(null);
toggle = false;
}
else
toggle = true;
if (sizeW == width)
wToggle = true;
if (sizeH == height)
hToggle = true;
if (hToggle && wToggle)
timer.stop();
}
});
timer.start();
}
//variables used for window resizing
private Timer timer;
private int sizeW = 600;
private int sizeH = 400;
private boolean toggle = false;
private boolean wToggle = false;
private boolean hToggle = false;
public int accNum = 0;
}
First Panel:
package com.example.FirstRun;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
public class FirstTimeRun extends JPanel
{
private static final long serialVersionUID = 1L;
public FirstTimeRun()
{
}
public FirstTimeRun(ActionListener val)
{
initComponents(val);
}
private void initComponents(ActionListener val) // method to build initial view for user for installation
{
pnlStart = new JPanel[1];
btnNext = new JButton();
pnlStart[0] = new JPanel();
btnNext.setText("Next"); // adding text to button for starting
btnNext.setPreferredSize(new Dimension(80, 35)); //positioning start button
btnNext.addActionListener(val);
pnlStart[0].add(btnNext); // adding button to JFrame
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(pnlStart[0]);
}
// objects used in UI
private JPanel[] pnlStart;
private JButton btnNext;
}
Second Panel:
package com.example.FirstRun;
import java.awt.BorderLayout;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class AccDetails extends JPanel
{
private static final long serialVersionUID = 1L;
public AccDetails()
{
accAssets();
}
private void accAssets()
{
// instantiating elements of the GUI
pnlAccDetails = new JPanel[2];
lblWelcome = new JLabel();
lblMain = new JLabel();
for (int i = 0; i < 2; i++)
pnlAccDetails[i] = new JPanel();
lblWelcome.setText("Welcome to Example_App"); // label welcoming user
pnlAccDetails[0].setLayout(new BoxLayout(pnlAccDetails[0], BoxLayout.LINE_AXIS));
pnlAccDetails[0].add(lblWelcome); // adding label to form
lblMain.setText("<html>The following information that is collected will be used as part of the Example_App process to ensure that each user has unique Example_App paths. Please fill in all areas of the following tabs:</html>"); // main label that explains what happens, html used for formatting
pnlAccDetails[1].setLayout(new BorderLayout());
pnlAccDetails[1].add(Box.createHorizontalStrut(20), BorderLayout.LINE_START);
pnlAccDetails[1].add(lblMain, BorderLayout.CENTER); //adding label to JFrame
pnlAccDetails[1].add(Box.createHorizontalStrut(20), BorderLayout.LINE_END);
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(pnlAccDetails[0]);
add(pnlAccDetails[1]);
}
private JLabel lblWelcome;
private JLabel lblMain;
private JPanel[] pnlAccDetails;
}
I have tried using both a CardLayout and the "revalidate();" "repaint();" and "pack();" options and I'm stumped as to why it's not showing. Thanks in advance for any help that can be offered.
EDIT:
While cutting down my code, if the "resizing" method is removed, the objects are shown when the panels change. I would like to avoid having to remove this completely as it's a smooth transition for changing the JFrame size.
#John smith it is basic example of switch from one panel to other panel I hope this will help you to sort out your problem
Code:
package stack;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class RemoveAndAddPanel implements ActionListener{
JFrame frame;
JPanel firstPanel;
JPanel secondPanel;
JPanel controlPanel;
JButton nextButton;
public RemoveAndAddPanel() {
JFrame.setDefaultLookAndFeelDecorated(true);
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
firstPanel = new JPanel();
firstPanel.add(new JLabel("FirstPanel"));
firstPanel.setPreferredSize(new Dimension(100,100));
secondPanel = new JPanel();
secondPanel.add(new JLabel("Second panel"));
secondPanel.setPreferredSize(new Dimension(100,100));
nextButton = new JButton("Next panel");
controlPanel = new JPanel();
nextButton.addActionListener(this);
controlPanel.add(nextButton);
frame.setLayout(new BorderLayout());
frame.add(firstPanel,BorderLayout.CENTER);
frame.add(controlPanel, BorderLayout.SOUTH);
frame.setVisible(true);
frame.setSize(300,100);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == nextButton) {
frame.remove(firstPanel);
frame.add(secondPanel);
nextButton.setEnabled(false);
}
frame.validate();
}
public static void main(String args[]) {
new RemoveAndAddPanel();
}
}
As mentioned in the edit, the problem lay within the resizing method. When the timer stopped, it wouldn't go anywhere, causing the UI to not load. The fix to the code is clearing the screen and adding the call to resizing to the actionlistener. Then adding a call to the next method after:
timer.stop();
Thanks for getting me to remove the mess around it and find the source of the problem #matt & #Hovercraft Full of Eels upvotes for both of you.
The main thing to consider while changing panel in a jframe is the layout, for a body(main) panel to change to any other panel the parent panel must be of type CardLayout body.setLayout(new java.awt.CardLayout());
After that you can now easily switch between panels wiht the sample code below
private void updateViewLayout(final HomeUI UI, final JPanel paneeelee){
final JPanel body = UI.getBody(); //this is the JFrame body panel and must be of type cardLayout
System.out.println("Page Loader Changing View");
new SwingWorker<Object, Object>() {
#Override
protected Object doInBackground() throws Exception {
body.removeAll();//remove all visible panel before
body.add(paneeelee);
body.revalidate();
body.repaint();
return null;
}
#Override
protected void done() {
UI.getLoader().setVisible(false);
}
}.execute();
}
Lets say i have 2 GUI panels A and B
In Panel A, I have a jTextArea that you can input a String ,
and a jbutton that if it is pressed, it appends the String inside a jTextArrea on a jTextField that is inside Panel B
What i want to do is make the String append on Panel B after waiting 2 seconds
without having the Thread Going on to Sleep
It has to be able to input another string into jTextArea during the wait period
How do i do this without using Thread.sleep()?
Start by taking a look at Concurrency in Swing, How to use Swing Timers and Worker Threads and SwingWorker to understand the issues and the possible solutions.
If you really don't want to use Thread#sleep (which you could use with a SwingWorker), a Swing Timer is probably the best solution. It allows you to setup a callback after a given delay (you can also repeat the callback, but in this case, we only need it once).
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTextField field;
private JTextArea ta1;
private JTextArea ta2;
private JButton btn;
private Timer timer;
public TestPane() {
JPanel panelA = new JPanel(new BorderLayout());
JPanel panelB = new JPanel(new BorderLayout());
setLayout(new GridLayout(1, 2));
add(panelA);
add(panelB);
field = new JTextField(10);
ta1 = new JTextArea(10, 20);
ta1.setEditable(false);
btn = new JButton("Add");
panelA.add(field, BorderLayout.NORTH);
panelA.add(new JScrollPane(ta1));
panelA.add(btn, BorderLayout.SOUTH);
ta2 = new JTextArea(10, 20);
ta2.setEditable(false);
panelB.add(new JScrollPane(ta2));
ActionListener startListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
ta1.append(field.getText() + "\n");
if (!timer.isRunning()) {
field.setEnabled(false);
btn.setEnabled(false);
timer.start();
}
}
};
field.addActionListener(startListener);
btn.addActionListener(startListener);
timer = new Timer(2000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
ta2.append(field.getText() + "\n");
field.setEnabled(true);
btn.setEnabled(true);
field.setText(null);
field.requestFocusInWindow();
}
});
timer.setRepeats(false);
}
}
}
I created a JPopupmenu and i added a JTextField. When I am using metal or nimbus everything is alright. The problem is when I switch LookAndFeel to Windows. I can not press right ALT, because if I press this key, JPopupmenu will hide.
Can I use right ALT to write national signs in Windows LookAndFeel?
import javax.swing.*;
import java.awt.event.*;
public class Popup extends JFrame {
JPopupMenu popup;
JPanel panel;
JTextField field;
public Popup(){
setSize(500,400);
try {
//UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException e1) {
e1.printStackTrace();
}
SwingUtilities.updateComponentTreeUI(this);
popup = new JPopupMenu();
field = new JTextField(10);
popup.add(field);
JButton button = new JButton("Options");
button.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
popup.show(e.getComponent(), e.getX(), e.getY());
}
});
panel = new JPanel();
panel.add(button);
add(panel);
}
public static void main(String[] args){
Popup pop = new Popup();
pop.setVisible(true);
}
}
JPopupMenu has a very specific set of operation requirements, and yes, they do change between look and feels, that's kind of the point.
What you could do is create you own popup using an undecorated JFrame. The trick here is to mimic as much of the popup as need, for example, auto closer when another component gains focus, the ability to dismiss the popup with the escape key...etc...
This is just a quick example to provide a proof of concept, I'd personally also add a key binding for the escape key, some kind of listener interface to allow the search pane to request that the popup be dismissed and the ability to auto focus some component when the window was made visible, but that's just me...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestPopup {
public static void main(String[] args) {
new TestPopup();
}
public TestPopup() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JButton show;
public TestPane() {
setLayout(new GridBagLayout());
show = new JButton("...");
show.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
PopupWindow window = new PopupWindow();
window.show(show, 0, show.getHeight());
}
});
add(show);
}
}
public class SearchPane extends JPanel {
private JList list;
private JTextField search;
public SearchPane() {
setLayout(new BorderLayout());
list = new JList();
list.setPrototypeCellValue("This is just a test");
list.setVisibleRowCount(20);
search = new JTextField(10);
add(new JScrollPane(list));
add(search, BorderLayout.SOUTH);
}
}
public class PopupWindow extends JFrame {
private SearchPane searchPane;
public PopupWindow() {
setUndecorated(true);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
addWindowFocusListener(new WindowFocusListener() {
#Override
public void windowGainedFocus(WindowEvent e) {
}
#Override
public void windowLostFocus(WindowEvent e) {
dispose();
}
});
searchPane = new SearchPane();
add(searchPane);
pack();
}
public void show(JComponent parent, int x, int y) {
Point point = new Point(x, y);
SwingUtilities.convertPointToScreen(point, parent);
setLocation(point);
setVisible(true);
}
}
}
Take it easy on me, I'm pretty new to Java programming in general, especially swing, and I'm trying to learn the basics of GUI programming.
I want to be able to prompt the user to enter a certain key into a text box and then click a button to display a string of text based on what key they enter. This is what I have so far:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class LeeSinAbilities extends JFrame
{
private JLabel leeSin;
private JTextField ability;
private JButton c;
private JLabel aName;
private static final long serialVersionUID = 1L;
public LeeSinAbilities()
{
super("Lee Sin's Abilities");
setLayout(new FlowLayout());
setResizable(true);
setSize(500, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel leeSin = new JLabel("Enter an ability key to see Lee Sin's ability names! (q, w, e, r)");
add(leeSin);
JTextField ability = new JTextField("Enter abilities here: ", 1);
add(ability);
JButton go = new JButton("Get Ability Name");
add(go);
JLabel aName = new JLabel("");
add(aName);
event e = new event();
go.addActionListener(e);
}
public static void main(String [] args){
new LeeSinAbilities().setVisible(true);
}
public class event implements ActionListener{
public void actionPerformed(ActionEvent e){
String abilityName = ability.getText();
if(abilityName.equalsIgnoreCase("q")){
aName.setText("Sonic Wave / Resonating Strike");
}
else if(abilityName.equalsIgnoreCase("w")){
aName.setText("Safeguard / Iron Will");
}
else if(abilityName.equalsIgnoreCase("e")){
aName.setText("Tempest / Cripple");
}
else if(abilityName.equalsIgnoreCase("r")){
aName.setText("Dragon's Rage");
}
else
aName.setText("Brutha please -_-...q, w, e, or r!");
}
}
}
I realise ActionListener is not the correct event to use, I'm just not sure what to put there yet (I'm guessing KeyListener.) All comments / suggestions are highly appreciated.
The first issue (which I assume is NullPointerException) is due to the fact that you are shadowing your variables...
public class LeeSinAbilities extends JFrame
{
//...
// This is a instance variable named ability
private JTextField ability;
//...
public LeeSinAbilities()
{
//...
// This is a local variable named ability , which
// is now shadowing the instance variable...
JTextField ability = new JTextField("Enter abilities here: ", 1);
//...
}
public class event implements ActionListener{
public void actionPerformed(ActionEvent e){
// This will be `null` as it's referencing the
// instance variable...
String abilityName = ability.getText();
//...
}
}
}
So instead of using...
JTextField ability = new JTextField("Enter abilities here: ", 1);
You should be using...
ability = new JTextField("Enter abilities here: ", 1);
This will prevent the NullPointerException from occurring in you actionPerformed method
Updated
Now, if you want to respond to key events, the best approach is to use the Key Bindings API, for example
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class KeyPrompt {
public static void main(String[] args) {
new KeyPrompt();
}
public KeyPrompt() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.setSize(400, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel aName;
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel("Enter an ability key to see Lee Sin's ability names! (q, w, e, r)"), gbc);
aName = new JLabel("");
add(aName, gbc);
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0), "QAbility");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "WAbility");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_E, 0), "EAbility");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_R, 0), "RAbility");
am.put("QAbility", new MessageAction(aName, "Sonic Wave / Resonating Strike"));
am.put("WAbility", new MessageAction(aName, "Safeguard / Iron Will"));
am.put("EAbility", new MessageAction(aName, "Tempest / Cripple"));
am.put("RAbility", new MessageAction(aName, "Dragon's Rage"));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.dispose();
}
public class MessageAction extends AbstractAction {
private final String msg;
private final JLabel msgLabel;
public MessageAction(JLabel msgLabel, String msg) {
this.msgLabel = msgLabel;
this.msg = msg;
}
#Override
public void actionPerformed(ActionEvent e) {
msgLabel.setText(msg);
}
}
}
}
It has better control over the focus requirements depending on your needs...