This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I have a problem with ActionListener. If I use an anonymous class everything works good, if the MainFrame class implements ActionListener everything works good. But if I create an extern class and implement ActionListener I get NullPointerException.
How can I fix this problem using an extern class that implement ActionListener interface?
Thanks in advance!
This is the code:
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class App {
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new MainFrame("Hello world Swing");
frame.setSize(500, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
MainFrame code:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
public class MainFrame extends JFrame {
JTextArea textArea;
public MainFrame(String title) {
super(title);
Container c = getContentPane();
c.setLayout(new BorderLayout());
textArea = new JTextArea();
JButton button = new JButton("Click me!");
c.add(textArea, BorderLayout.CENTER);
c.add(button, BorderLayout.SOUTH);
button.addActionListener(new ListenApp());
}
}
ListenApp code:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
public class ListenApp implements ActionListener {
MainFrame frame;
#Override
public void actionPerformed(ActionEvent e) {
frame.textArea.append("Hello\n");
}
}
It's because in ListenApp the frame (field) you have isn't declared as the frame you created in your main method.
They way to make it work is to pass the frame into the listener as an argument in the listener's constructor. Take a look:
MainFrame class:
package test;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class MainFrame extends JFrame {
private JTextArea textArea; // private fields are always recommended.
public MainFrame(String title) {
super(title);
Container c = getContentPane();
c.setLayout(new BorderLayout());
textArea = new JTextArea();
JButton button = new JButton("Click me!");
c.add(textArea, BorderLayout.CENTER);
c.add(button, BorderLayout.SOUTH);
button.addActionListener(new ListenApp(this)); //pass the frame to the listener
}
public JTextArea getTextArea() // Must have access to the textArea aswell
{
return textArea;
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new MainFrame("Hello world Swing");
frame.setSize(500, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
ListenApp class:
package test;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ListenApp implements ActionListener {
private MainFrame frame;
public ListenApp(MainFrame frame) {
this.frame = frame;
}
#Override
public void actionPerformed(ActionEvent arg0) {
frame.getTextArea().append("i append something");
}
}
Related
as you see I have made a very simple program where I input text on a textfield, then press the button to print it on the console:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
class Main {
private static class Window extends JFrame {
private static class TextField extends JTextField {
private TextField() {
setVisible(true);
setBounds(5, 0, 190,20);
}
}
public class Button extends JButton implements ActionListener {
private Button() {
setText("print");
addActionListener(this);
setVisible(true);
setBounds(5, 35, 190,20);
}
public void actionPerformed(ActionEvent e) {
TextField textField = new TextField();
String input = textField.getText();
System.out.println(input);
}
}
However, while I click the button, it adds blank lines to the console, without the text I have written in it.
Your actionPerformed method creates a new TextField instance and prints the text from that new instance.
A very simple example that works as intended:
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class TextAndButtonExample {
public static void main( String[] args ) {
EventQueue.invokeLater(() -> new TextAndButtonExample().start());
}
void start() {
JTextField textField = new JTextField();
JButton button = new JButton(new AbstractAction("Print") {
public void actionPerformed( ActionEvent e ) {
System.out.println(textField.getText());
}
});
JPanel controlPane = new JPanel(new GridLayout(2, 1));
controlPane.add(textField);
controlPane.add(button);
JPanel contentPane = new JPanel();
contentPane.add(controlPane);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(contentPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Note that I did not extend any Swing components and that I did use a layout manager instead of explicitly setting bounds for components.
So when I run the program it doesn't print out the variable kod. I should addKeyListener(); But I don't know where and how ?
Can someone please tell me how am I supposed to add the keyListener to my main class or where ever I am supposed to add it ???
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.event.KeyEvent;
import java.awt.event.KeyAdapter;
public class YuGiOh {
public static void main(String[] args){
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JLabel l1 = new JLabel("LABEL");
frame.setSize(200,200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.addKeyListener(new tipkovnica());
panel.setLayout(null);
frame.add(panel);
l1.setBounds(80,100,100,20);
panel.add(l1);
}
}
class tipkovnica extends KeyAdapter{
public void keyBinder(KeyEvent e){
int kod = e.getKeyCode();
System.out.println(kod);
}
public void keyReleased(KeyEvent e){
}
}
KeyListener() requires the component to have focus. Try adding:
frame.requestFocus();
I have 2 panel (2 class, extends from JPanel), 1 frame (1 class, extends from JFrame)
My first panel - WelcomePanel:
package caro;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class WelcomePanel extends JPanel {
public WelcomePanel() {
ImageIcon logoImage = new ImageIcon("/home/khanhpq/logo.png");
JButton playButton = new JButton("Play");
JButton exitButton = new JButton("Exit");
JLabel imageLabel = new JLabel(logoImage);
add(imageLabel);
add(playButton);
add(exitButton);
playButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
}
});
exitButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int option = JOptionPane.showConfirmDialog(null, "Are you sure ?", "Warning", JOptionPane.YES_NO_OPTION);
if(option == JOptionPane.YES_OPTION) {
System.exit(0);
}
}
});
}
}
My second panel - BoardPanel:
package caro;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
public class BoardPanel extends JPanel {
public BoardPanel() {
JPanel boardPanel = new JPanel();
Board board = new Board();
CellButton cellButton[] = new CellButton[144];
GridLayout gridLayout = new GridLayout(12, 12);
boardPanel.setLayout(gridLayout);
for (int i = 0; i < 144; i++) {
cellButton[i] = new CellButton();
boardPanel.add(cellButton[i]);
}
}
}
My main frame - MainFrame
package caro;
import javax.swing.JFrame;
public class MainFrame extends JFrame {
public MainFrame() {
add(new WelcomePanel());
setSize(360, 380);
setVisible(true);
}
public static void main(String[] args) {
MainFrame startFrame = new MainFrame();
}
}
My question: Help me write code, addActionListener on buttons of panels (material example). When i press play button (of WelcomePanel), WelcomePanel is hidden and BoardPanel is show. And, when i exit BoardPanel (close button is pressed, or click x button), WelcomePanel is showed.
My friend recommend use Message and Handle, but I don't know. Please help me. Thanks.
Its better to declare dependencies (Component like buttons, panels, etc...) as fields. In this way they are visible for a third class that is the Controller of them. In next examaple I make MainFrame controlling itself, just an example. Read about Presentation patterns for better pratices.
WelcomePanel.java
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class WelcomePanel extends JPanel {
/* Declare your dependecies as fields,
* so you can hold a reference.
*/
ImageIcon logoImage;
JButton playButton;
JButton exitButton;
JLabel imageLabel;
public WelcomePanel() {
logoImage = new ImageIcon("/home/khanhpq/logo.png");
playButton = new JButton("Play");
exitButton = new JButton("Exit");
imageLabel = new JLabel(logoImage);
add(imageLabel);
add(playButton);
add(exitButton);
}
}
BoardPanel.java
import javax.swing.JButton;
import javax.swing.JPanel;
public class BoardPanel extends JPanel {
/* Declare your dependecies as fields,
* so you can hold a reference.
*/
JButton closeButton;
public BoardPanel() {
closeButton = new JButton();
add(closeButton);
}
}
MainFrame.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class MainFrame extends JFrame implements ActionListener {
/* Declare your dependecies as fields,
* so you can hold a reference.
*/
WelcomePanel welcomePanel;
BoardPanel boardPanel;
public MainFrame() {
welcomePanel = new WelcomePanel();
boardPanel = new BoardPanel();
add(welcomePanel);
add(boardPanel);
boardPanel.setVisible(false);
boardPanel.closeButton.addActionListener(this);
welcomePanel.playButton.addActionListener(this);
setSize(360, 380);
}
/**
* This class is the controller.
*/
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(boardPanel.closeButton)) {
welcomePanel.setVisible(false);
boardPanel.setVisible(true);
} else if (e.getSource().equals(welcomePanel.playButton)) {
welcomePanel.setVisible(true);
boardPanel.setVisible(false);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MainFrame startFrame = new MainFrame();
startFrame.setVisible(true);
}
});
}
}
Folks, I intend to implement a simple button ActionListener but it appears to not work.
The java codes are attached as following.....
The program intends to respond the click action from user and change the context of the JLabel
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 Frame extends JFrame implements ActionListener {
public JButton btn = new JButton("Click");
public JLabel display = new JLabel("null");
public JPanel mainPanel = new JPanel();
public Frame() {
mainPanel.add(btn);
mainPanel.add(display);
add(mainPanel);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btn) {
display.setText("it works");
System.out.println("it works");
}
}
public static void main(String[] args) {
Frame testFrame = new Frame();
testFrame.pack();
testFrame.setVisible(true);
}
}
Your actionlistener (the JFrame itself) is not added with addActionListener.
You should add ActionListner to the button
public Frame(){
mainPanel.add(btn);
mainPanel.add(display);
btn.addActionListener(this);
add(mainPanel);
}
I have a button that inserts an unordered list item into a JTextPane. However, when I click on the button to insert a list item, two bullets are inserted instead of one. One bullet is inserted only during the first time insertion.
I cut out the functionality from my application and pasted the code into a small SSCCE (below) and the problem remains. Does anyone have any idea as to what might be happening here?
[The problem has been solved, below is the complete solved code. There are two ways to do this, refer to the functionality in the show and the bullets button]
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;
import javax.swing.text.ElementIterator;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
public class Main {
private static Button2 show = new Button2 ("Show");
private static LIButton bullets = new LIButton("Bullets", HTML.Tag.UL);
private static JEditorPane pane = new JEditorPane();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
create();
}
});
}
private static void create() throws HeadlessException {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pane.setPreferredSize(new Dimension(300, 300));
pane.setContentType("text/html");
frame.add(pane, BorderLayout.CENTER);
JPanel panel = new JPanel();
panel.add(bullets);
panel.add(show);
frame.add(panel, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
static class LIButton extends JButton {
static final String LI_HTML = "<HTML><BODY><UL><LI></LI></UL></BODY></HTML>";
public LIButton(String name, HTML.Tag parent) {
super(new HTMLEditorKit.InsertHTMLTextAction(
name, LI_HTML, HTML.Tag.UL, HTML.Tag.LI, HTML.Tag.BODY, HTML.Tag.UL));
}
}
static class Button2 extends JButton implements ActionListener {
static final String LI_HTML = "<HTML><BODY><UL><LI></LI></UL></BODY></HTML>";
public Button2(String name) {
super(name);
this.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent ae) {
HTMLDocument doc = (HTMLDocument) pane.getDocument();
HTMLEditorKit kit = (HTMLEditorKit) pane.getEditorKit();
try {
kit.insertHTML(doc, doc.getLength() - 1, LI_HTML, 0, 1, null);
} catch (BadLocationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The example below seems to work.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.HeadlessException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
public class Main {
private static LIButton bullets = new LIButton("Bullets", HTML.Tag.UL);
private static JTextPane pane = new JTextPane();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
create();
}
});
}
private static void create() throws HeadlessException {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pane.setPreferredSize(new Dimension(300, 300));
pane.setContentType("text/html");
pane.setText("<HTML><BODY><UL></UL></BODY></HTML>");
frame.add(pane, BorderLayout.CENTER);
JPanel panel = new JPanel();
panel.add(bullets);
frame.add(panel, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
static class LIButton extends JButton {
static final String LI_HTML = "<LI>item</LI>";
public LIButton(String name, HTML.Tag parent) {
super(new HTMLEditorKit.InsertHTMLTextAction(
name, LI_HTML, parent, HTML.Tag.LI));
}
}
}