I am having trouble hiding a new frame when I am trying to open a new one. At the end of this code there is a call to start() method of another class and I would like this classes frame to be hidden but I cannot seem to access the from from its current location.
package InventoryApp;
//Import
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
/**
*
* #author Curtis
*/
public class JSplash extends JFrame implements ActionListener
{
//declaration of variable objects
Font myFont = new Font("Arial", Font.BOLD, 20);
JButton myButton = new JButton("Click Me!");
Color bgColor = new Color(0,0,255);
Color firstColor = new Color(255,255,255);
String first = "Welcome to DaemoDynamics!";
String last = "Click the Button";
String middle = "";
String middle2 = "";
int count = 1;
//Constructor
public JSplash()
{
super("Item Inventory Application");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout (new BorderLayout());
add(myButton, BorderLayout.SOUTH);
setDefaultLookAndFeelDecorated(true);
getContentPane().setBackground(bgColor);
//adds action listener
myButton.addActionListener(this);
}
//Paint method
#Override
public void paint(Graphics e)
{
super.paint(e);
e.setFont(myFont);
e.setColor(firstColor);
e.drawString(first, 14, 80);
e.drawString(last, 70, 240);
e.drawString(middle, 75, 150);
e.drawString(middle2, 60, 175);
}
public static void begin()
{
final int TALL = 316;
final int WIDE = 304;
JSplash frame = new JSplash();
frame.setSize(WIDE, TALL);
frame.setVisible(true);
}
//Listener Method
#Override
public void actionPerformed(ActionEvent e)
{
//First Time button hit
if(count == 1)
{
middle = "Brighter Business";
middle2 = "for A Brighter Future";
last = "Click Again to Begin";
repaint();
//increases button count
count ++;
}
else//if button count is not 1
{
frame.setVisible(false);
FinalProject.start();
}
}
}
The frame is declare as a local variable, and therefore is out of scope in the actionPerformed() method.
Related
I started programming Java. This is my first window application. I did a simple tic-tac-toe game and I want the "o" button font color to be a different color. But it doesn't work. I can change the background color, but not the fonts, why?
package moje;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.print.PrinterJob;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JTextField;
public class Kolko_i_krzyzyk extends JFrame implements ActionListener {
static JTextField tekst;
static JLayeredPane ekran = new JLayeredPane();
static JButton button = new JButton();
static int licznik=0;
public Kolko_i_krzyzyk () {
super("Kółko i krzyżyk");
ekran = new JLayeredPane();
setVisible(true);
setSize(800, 800);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
//Siatka podzielona 3 na 3
setLayout(new GridLayout(3,3));
//Tworzenie 9 przycisków
for(int i = 1; i<=9; i++) {
JButton button = new JButton();
add(button);
button.addActionListener(this);
}
}
public static void main(String[] args) {
JFrame okno = new Kolko_i_krzyzyk();
}
#Override
public void actionPerformed(ActionEvent e) {
JButton button = (JButton) e.getSource();
if(licznik%2==0 ) {
button.setText("x");
button.setFont(new Font ("Arial", Font.BOLD, 90));
}
else {
button.setText("O");
button.setForeground(Color.RED);
button.setFont(new Font ("Arial", Font.BOLD, 90));
}
button.setEnabled(false);
licznik++;
}
}
The issue here is the default behavior when disabling the JButton via setEnabled(false).
This will grey out the button and ignore any color formatting you did to the text (foreground).
There are several workarounds to modify this behavior (as seen in this similar question).
Here is a short demonstration (without the final game logic of course) , which changes the UI of the JButton via setUI().
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.plaf.metal.MetalButtonUI;
public class Test {
private int counter = 0;
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Test().buildGui());
}
private void buildGui() {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.add(panel);
panel.setLayout(new GridLayout(3, 3));
for (int i = 1; i <= 9; i++) {
JButton button = new JButton() {
#Override
public Dimension getPreferredSize() {
return new Dimension(150, 150);
}
};
button.setFont(new Font("Arial", Font.BOLD, 90));
panel.add(button);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (counter % 2 == 0) {
button.setText("X");
button.setUI(new MetalButtonUI() {
// override the disabled text color for the button UI
protected Color getDisabledTextColor() {
return Color.BLUE;
}
});
} else {
button.setText("O");
button.setUI(new MetalButtonUI() {
protected Color getDisabledTextColor() {
return Color.RED;
}
});
}
button.setEnabled(false);
counter++;
}
});
}
frame.pack();
frame.setVisible(true);
}
}
Result:
Another (simpler) way to do it would be to build some ImageIcons for "X" and "O", then set these on the buttons via setIcon()/setDisabledIcon(). This would save you the trouble from modifying the button UI.
I need to divide java swing window into many fields, something similar to the table or chess board. Color of each cell should be dependent on the object which this cell represents (each object has coordinates, which are changing during the game, so the color of each cell is not constant).
Additionally, if the user clicks on the empty field (white color), then a new random object is created and this object is assigned to these field (and field color is changing).
Which of java swing controls will be the best for these functionalities?
If I were you I would make 2 panel classes(white and black), the white one with a MouseAdapter, so that when one of the panels is clicked you can pull a random JLabel from an array. Here's an example that might help (roughly 120 lines):
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
public class ScratchPaper extends JFrame {
private static final long serialVersionUID = 1L;
private static final int GRIDSIZE = 8;
private JPanel[][] whitePanel = new WhitePanel[GRIDSIZE][GRIDSIZE];
private JPanel[][] blackPanel = new BlackPanel[GRIDSIZE][GRIDSIZE];
private Random rand = new Random();
JButton b1 = new JButton("Btn1");
JButton b2 = new JButton("Btn2");
JButton b3 = new JButton("Btn3");
JLabel l1 = new JLabel("Lbl1");
JLabel l2 = new JLabel("Lbl2");
JLabel l3 = new JLabel("Lbl3");
JPanel panel = new JPanel();
private JComponent[][] randObjects = {{b1, b2, b3}, {l1, l2, l3}, {panel, panel, panel}};
private Color[] randColors = {Color.RED, Color.ORANGE, Color.YELLOW, Color.GREEN, Color.BLUE, Color.MAGENTA};
public ScratchPaper() {
initGUI();
setTitle("EXAMPLE");
pack();
setLocationRelativeTo(null);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
private void initGUI() {
JPanel centerPanel = new JPanel();
centerPanel.setLayout(new GridLayout(GRIDSIZE, GRIDSIZE)); // makes 8*8 grid
add(centerPanel, BorderLayout.CENTER);
MouseAdapter ma = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
Component clickedComp = findComponentAt(e.getPoint());
JPanel target = (JPanel) clickedComp;
panel.setBackground(randColors[rand.nextInt(randColors.length)]);
if (target instanceof WhitePanel){
target.add(randObjects[rand.nextInt(randObjects.length)][rand.nextInt(randObjects[0].length)]);
target.updateUI();
}
}
};
addMouseListener(ma);
for (int row=0; row<GRIDSIZE; row++) {
for (int col=0; col<GRIDSIZE; col++) {
whitePanel[row][col] = new WhitePanel(row, col);
blackPanel[row][col] = new BlackPanel(row, col);
if ((row%2 == 0 && col%2 == 0) || ((row+1)%2 == 0 && (col+1)%2 == 0)) {
centerPanel.add(whitePanel[row][col]);
}
else {
centerPanel.add(blackPanel[row][col]);
}
}
}
}
public static void main(String args[]) {
try {
String className = UIManager.getCrossPlatformLookAndFeelClassName();
UIManager.setLookAndFeel(className);
} catch (Exception ex) {
System.out.println(ex);
}
EventQueue.invokeLater(new Runnable(){
#Override
public void run(){
new ScratchPaper();
}
});
}
class WhitePanel extends JPanel {
private static final int SIZE = 50;
public WhitePanel(int row, int col) {
Dimension size = new Dimension(SIZE, SIZE);
setPreferredSize(size);
setBackground(Color.WHITE);
}
}
class BlackPanel extends JPanel {
private static final int SIZE = 50;
public BlackPanel(int row, int col) {
Dimension size = new Dimension(SIZE, SIZE);
setPreferredSize(size);
setBackground(Color.BLACK);
}
}
}
Try running it! It's actually pretty fun!
I'm trying to make a traffic light program, changing the foreground colour of JLabel from red to yellow to green, everytime I press JButton (i.e once i press JButton, JLabel turns red, then when i again press JButton it turns yellow and so on). But somehow the colour changes only once to red & nothing happens on further pressing JButton. Any kind of help would be appreciated. Thanks.
import java.awt.Color;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import java.awt.Font;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTextField;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class traffic {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
traffic window = new traffic();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public traffic() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 798, 512);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JLabel lblTrafficLight = new JLabel("Traffic Light");
lblTrafficLight.setFont(new Font("Tahoma", Font.BOLD, 40));
lblTrafficLight.setHorizontalAlignment(SwingConstants.CENTER);
lblTrafficLight.setBounds(190, 11, 403, 61);
frame.getContentPane().add(lblTrafficLight);
JLabel lblRed = new JLabel("RED");
lblRed.setHorizontalAlignment(SwingConstants.CENTER);
lblRed.setFont(new Font("Tahoma", Font.PLAIN, 40));
lblRed.setBounds(273, 125, 249, 61);
frame.getContentPane().add(lblRed);
JButton btnButton = new JButton("Button");
btnButton.setActionCommand("B");
btnButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
if(btnButton.getActionCommand().equals("B"))
{
lblRed.setForeground(Color.RED);
}
if(btnButton.getActionCommand().equals("B"))
{
lblRed.setForeground(Color.YELLOW);
}
if(btnButton.getActionCommand().equals("B"))
{
lblRed.setForeground(Color.GREEN);
}
if(btnButton.getActionCommand().equals("B"))
{
lblRed.setForeground(Color.YELLOW);
}
if(btnButton.getActionCommand().equals("B"))
{
lblRed.setForeground(Color.RED);
}
}
});
btnButton.setBounds(353, 346, 89, 23);
frame.getContentPane().add(btnButton);
}
}
You're using the same actionCommand, B for each if block, and so all of the blocks will always run, and the last block will be the one seen.
e.g.,
int x = 1;
if (x == 1) {
// do something
}
if (x == 1) {
// do something else
}
all blocks will be done!
Either change the actionCommands used, or don't use actionCommand String but rather an incrementing int index. Also, don't use MouseListeners for JButtons but rather ActionListeners.
For example:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
public class Traffic2 extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = 300;
private static final String[] STRINGS = {"Red", "Blue", "Orange", "Yellow", "Green", "Cyan"};
private Map<String, Color> stringColorMap = new HashMap<>();
private JLabel label = new JLabel("", SwingConstants.CENTER);
private int index = 0;
public Traffic2() {
stringColorMap.put("Red", Color.red);
stringColorMap.put("Blue", Color.blue);
stringColorMap.put("Orange", Color.orange);
stringColorMap.put("Yellow", Color.YELLOW);
stringColorMap.put("Green", Color.GREEN);
stringColorMap.put("Cyan", Color.CYAN);
label.setFont(label.getFont().deriveFont(Font.BOLD, 40f));
String key = STRINGS[index];
label.setText(key);
label.setForeground(stringColorMap.get(key));
JPanel centerPanel = new JPanel(new GridBagLayout());
centerPanel.add(label);
JPanel topPanel = new JPanel();
topPanel.add(new JButton(new AbstractAction("Change Color") {
#Override
public void actionPerformed(ActionEvent e) {
index++;
index %= STRINGS.length;
String key = STRINGS[index];
label.setText(key);
label.setForeground(stringColorMap.get(key));
}
}));
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(centerPanel, BorderLayout.CENTER);
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
Traffic2 mainPanel = new Traffic2();
JFrame frame = new JFrame("Traffic2");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I ll explain my code in a bit:
I have a JComboBox with a list of items
And when the JButton "Select" is pressed, it registers the last index of the last selected item from JComboBox.
Now I need to access this index inside the main.
Here is my code :
public static final JComboBox c = new JComboBox();
private static final JButton btnNewButton = new JButton("Select");
And the JButton ActionListener is:
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
ind = c.getSelectedIndex();
frame.setVisible(false);
}
});
So after the button is pressed, the frame closes
But now when I try to access this ind inside main simply by
public static void main(String[] args) {
System.out.println(ind);}
I get a return value of ind = 0
I understand that this is because it has been initialized to 0 as
static ind = 0
But then how do I access this index outside the JButton ActionListener?
I need to use this index further in my code.
EDIT
Here's my MCVE
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.SpringLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.UIManager;
public class MinimalExProgram
{
private static String[] description = { "One", "Two", "Three"};
static int ind;
public static final JComboBox c = new JComboBox(description);
private static final JButton btnNewButton = new JButton("Select");
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().setForeground(UIManager.getColor("ComboBox.disabledBackground"));
frame.getContentPane().setBackground(UIManager.getColor("EditorPane.disabledBackground"));
SpringLayout springLayout = new SpringLayout();
springLayout.putConstraint(SpringLayout.NORTH, btnNewButton, 5, SpringLayout.NORTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, c, -6, SpringLayout.WEST, btnNewButton);
springLayout.putConstraint(SpringLayout.EAST, btnNewButton, -10, SpringLayout.EAST, frame.getContentPane());
springLayout.putConstraint(SpringLayout.WEST, c, 6, SpringLayout.WEST, frame.getContentPane());
springLayout.putConstraint(SpringLayout.NORTH, c, 6, SpringLayout.NORTH, frame.getContentPane());
frame.getContentPane().setLayout(springLayout);
frame.setSize(500, 150);
frame.setLocation(400, 200);
frame.setResizable(false);
c.setBackground(UIManager.getColor("ComboBox.disabledBackground"));
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
System.out.print("What I want:");
ind = c.getSelectedIndex();
System.out.println(ind);
frame.setVisible(false);
}
});
frame.getContentPane().add(c);
btnNewButton.setForeground(UIManager.getColor("ComboBox.buttonDarkShadow"));
btnNewButton.setBackground(UIManager.getColor("EditorPane.disabledBackground "));
frame.getContentPane().add(btnNewButton);
frame.setVisible(true);
System.out.print("What I get: ");
System.out.println(ind);
}
}
I need to access the ind inside the main as mentioned before
Here when I print out the ind I get zero despite whatever choice I make inside the combobox.
OK, I'm going to guess since you've yet to show us enough information to do more than this, but I assume that:
You're showing a 2nd window as a dialog off of a main window
That this 2nd window is a JFrame and holds your JComboBox and the button
That you're making it invisible on button push,
That you try to get the information from the combobox, but it's always 0
And this may be because you're getting the information before the user has had a chance to interact with the 2nd window.
If so, the solution is to make the 2nd window a modal dialog window such as a modal JDialog and not a JFrame. This way, the calling code will know exactly when the 2nd window is no longer visible since the calling code's code flow will be blocked until the 2nd window is no longer visible.
Edit
Proof of concept: Change your code from:
final JFrame frame = new JFrame();
to:
// rename frame variable to dialog for clarity
final JDialog dialog = new JDialog();
dialog.setModalityType(ModalityType.APPLICATION_MODAL);
and it works.
But again, I'd get rid of unnecessary statics and get rid of doing too much code in the main method. For instance,...
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
#SuppressWarnings("serial")
public class MinimalExProgram3 extends JPanel {
private static void createAndShowGui() {
MainPanel mainPanel = new MainPanel();
JFrame frame = new JFrame("MinimalExProgram3");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class MainPanel extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private JTextField field = new JTextField(8);
private ComboPanel comboPanel = new ComboPanel();
JDialog dialog = null;
public MainPanel() {
field.setFocusable(false);
add(field);
add(new JButton(new ShowComboAction("Show Combo")));
}
#Override // make it bigger
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class ShowComboAction extends AbstractAction {
public ShowComboAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
Window mainWin = SwingUtilities.getWindowAncestor(MainPanel.this);
if (dialog == null) {
dialog = new JDialog(mainWin, "Dialog", ModalityType.APPLICATION_MODAL);
dialog.add(comboPanel);
dialog.pack();
dialog.setLocationRelativeTo(null);
}
dialog.setVisible(true);
// code called here after dialog no longer visible
String text = comboPanel.getText();
field.setText(text);
}
}
}
#SuppressWarnings("serial")
class ComboPanel extends JPanel {
private static final String[] DESCRIPTION = { "One", "Two", "Three" };
private int ind;
private JComboBox<String> combo = new JComboBox<>(DESCRIPTION);
private String text;
private SelectionAction selectionAction = new SelectionAction("Select");
private JButton selectionButton = new JButton(selectionAction);
public ComboPanel() {
add(combo);
add(selectionButton);
combo.setAction(selectionAction);
}
public int getInd() {
return ind;
}
public String getText() {
return text;
}
private class SelectionAction extends AbstractAction {
public SelectionAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
ind = combo.getSelectedIndex();
if (ind >= 0) {
text = combo.getSelectedItem().toString();
}
Window win = SwingUtilities.getWindowAncestor(ComboPanel.this);
win.dispose();
}
}
}
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...