I don't know a whole lot about programming so excuse my messy code, but I'm working on a little choice-based game and my action listeners are throwing a nasty NullPointerException. Let me know what the issue might be.
the error is
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
with a continued list of (Unknown Source) based lines
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class finalproj extends JFrame implements ActionListener
{
private static final int WIDTH = 800, HEIGHT = 800;
private static final Font STANDARD_FONT = new Font("Arial", Font.BOLD, 32);
private JButton startgame, next, endgame;
private JLabel startmenu, question;
private int chanceofdeath = 0;
private JRadioButton q1A, q1B, q1C, q2A, q2B, q2C, q3A, q3B, q3C, q4A, q4B, q4C,
q5A, q5B, q5C, q6A, q6B, q6C, q7A, q7B, q8C, q9A, q9B, q9C, q10A, q10B, q10C, q11A,
q11B, q11C, q12A, q12B, q12C, q13A, q13B, q13C, q14A, q14B, q14C, q15A, q15B, q15C;
public static void main(String[] args)
{
new finalproj();
}
public finalproj()
{
setLayout(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(WIDTH, HEIGHT);
setTitle("The Wild, Wild West");
getContentPane().setBackground(Color.BLACK);
setLocationRelativeTo(null);
setResizable(false);
JLabel startmenu = new JLabel("");
startmenu.setSize(800, 100);
startmenu.setLocation(35, 100);
startmenu.setFont(STANDARD_FONT);
startmenu.setText("Howdy Pardner! Ready to enter the Wild West?!");
startmenu.setOpaque(true);
startmenu.setBackground(Color.BLACK);
startmenu.setForeground(Color.WHITE);
startmenu.setVisible(true);
JButton startgame = new JButton("press me");
startgame.setFont(new Font("Arial", Font.BOLD, 28));
startgame.setForeground(Color.BLACK);
startgame.setSize(600, 100);
startgame.setLocation(100, 300);
startgame.setVisible(true);
JButton next = new JButton("Continue");
next.setFont(new Font("Arial", Font.BOLD, 28));
next.setForeground(Color.BLACK);
next.setSize(600, 100);
next.setLocation(100, 300);
next.setFocusable(false);
next.setVisible(false);
JLabel question = new JLabel();
question.setFont(new Font("Arial", Font.BOLD, 28));
question.setForeground(Color.BLACK);
question.setSize(600, 100);
question.setLocation(100, 300);
question.setFocusable(false);
question.setVisible(false);
question.setText("AAAAA");
startgame.addActionListener(this);
add(startmenu);
add(startgame);
add(question);
add(next);
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().equals("press me"))
{
startmenu.setVisible(false);
}
You are using local variable with the name 'startmenu', while the field 'startmenu' is never assigned.
You should initialize it like this
startmenu = new JLabel("");
instead of
JLabel startmenu = new JLabel("");
The same thing should be done with other fields.
Let me advice you to use IDE highlighting, it will show you what field or variable you are looking at.
First of you declare a variable name with
private JLabel startmenu, question;
in your constructor, you are creating an object using
JLabel startmenu = new JLabel("");
this object scoope only in constructor, not outside the constructor.
so you need to insitalize value of startmenu using above statement.
this.startmenu = new JLabel("");
what to do. replace
JLabel startmenu = new JLabel("");
to
this.startmenu = new JLabel("");
Related
I'm new in Java learning, I was asked to develop a GUI application that simulates four cars racing, You can set the speed for each car. and the following is my code, it can run but can't display the picture. I don't know much about where should I position my picture (In JPanel or JFrame). could someone give me some help to finish the project?
Thanks in advance.
import JavaFX.scene.canvas.GraphicsContext;
import JavaFX.scene.image.ImageView;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Main {
static class program extends JFrame {
//create two JPanel objects.
JPanel topRow = new JPanel();
JPanel lowRow = new JPanel() {
public void paint(Graphics graphics) {
//draw a graph
graphics.drawRect(5, 25, 490, 240);
graphics.drawLine(5, 85, 495, 85);
graphics.drawLine(5, 145, 495, 145);
graphics.drawLine(5, 205, 495, 205);
}
};
private JTextField carped_a = new JTextField();
String s1 = carped_a.getText();//there I want to change this to the //car's speed
private JTextField carped_b = new JTextField();
String s2 = carped_b.getText();
private JTextField carped_c = new JTextField();
String s3 = carped_c.getText();
private JTextField carped_d = new JTextField();
String s4 = carped_d.getText();
program() {
super("program");
setLookAndFeel();
setResizable(false);
setSize(515, 330);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
BorderLayout layout = new BorderLayout();
setLayout(layout);
topRow.setBounds(5, 5, 490, 40);
GridLayout grid = new GridLayout(1, 4, 20, 10);
topRow.setLayout(grid);
JLabel carLabel_a = new JLabel("car 1: ", JLabel.RIGHT);
topRow.add(carLabel_a);
carped_a.setEditable(true);
topRow.add(carped_a);
JLabel carLabel_b = new JLabel("car 2:", JLabel.RIGHT);
topRow.add(carLabel_b);
carped_b.setEditable(true);
topRow.add(carped_b);
JLabel carLabel_c = new JLabel("car 3:", JLabel.RIGHT);
topRow.add(carLabel_c);
carped_c.setEditable(true);
topRow.add(carped_c);
JLabel carLabel_d = new JLabel("car 4:", JLabel.RIGHT);
topRow.add(carLabel_d);
carped_d.setEditable(true);
topRow.add(carped_d);
add(topRow, BorderLayout.NORTH);
add(lowRow, BorderLayout.CENTER);
}
private void setLookAndFeel() {
try {
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception exc) {
// ignore error
}
}
}
static class Car extends JPanel{
JLabel carLabel =new JLabel();
Car(int a, int b) {
carLabel.setBounds(a,b,50,40);
this.add(carLabel);
ImageIcon img=new ImageIcon("car.jpg");
carLabel.setIcon(img);
carLabel.setText(null);
}
}
public static void main(String[] args) {
program program1= new program();
Car car1= new Car(5,45);
}
}
I'm using IntelliJ IDEA.
First of all, you create a Car panel but you never add it to the frame:
public static void main(String[] args) {
program program1 = new program();
Car car1 = new Car(5, 45);
program1.add(car1);
}
Secondly, the image won't shown because it is not in the correct path. When you say new JLabel("myimage.png");, it is expected to have the image into project's main directory. However, this way your application will not be portable (actually it will but you will have to take the whole project with it). In order to make it independent and portable read this question.
I am currently designing a login screen, but I ran into a strange issue. I already designed my GUI with the help of swing, and it was time to make functional buttons. I wanted to test my login button and if it would take me to the frame I want, but it is unable to. I can set a JOptionPane.showMessageDialog for example, which works just fine, but I am unable to open another frame from the button. I tried with New JFrameName().setVisible(true), and also JFrameName test = new JFrameName(); test.setVisible(true);, but the methods show up in red. Here is my code.
package com.edu4java.swing.tutrial3;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class LoginView {
public static void main(String[] args) {
JFrame frame = new JFrame("Bus Tour Booking System");
frame.setSize(300, 200);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.add(panel);
placeComponents(panel);
frame.setVisible(true);
}
private static void placeComponents(JPanel panel) {
panel.setLayout(null);
JLabel titleLabel = new JLabel("Bus Tour Booking System");
titleLabel.setBounds(70,15,150,25);
panel.add(titleLabel);
JLabel userLabel = new JLabel("Username: ");
userLabel.setBounds(30, 50, 80, 25);
panel.add(userLabel);
JTextField userText = new JTextField(20);
userText.setBounds(120, 50, 130, 25);
panel.add(userText);
JLabel passwordLabel = new JLabel("Password: ");
passwordLabel.setBounds(30, 80, 80, 25);
panel.add(passwordLabel);
JPasswordField passwordText = new JPasswordField(20);
passwordText.setBounds(120, 80, 130, 25);
panel.add(passwordText);
JButton loginButton = new JButton("login");
loginButton.setBounds(100, 125, 80, 25);
panel.add(loginButton);
ActionListener myButtonListener = new MyButtonListener();
loginButton.addActionListener(myButtonListener);
}
private static class MyButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
//can't access a new frame from here :(
}
}
}
I would be very grateful if someone could help me out, I read a lot on Stackoverflow and Reddit, but just can't find the solution. I am also new to Java, so that doesn't help a lot either :D. Thanks in advance!
P.S. As far as the actual functionality for the login screen, I am going to do that in a later stage.
This is your login class. I put the JFrame frame in the global scope, so you can manipulate it from the ButtonListener method. I also created a SomeFrame class, just to demonstrate the new JFrame that would be created when you click the button. When an action is performed(the button is clicked) a new object of SomeFrame is created. Since SomeFrame extends JFrame we can use the method setVisible() to a SomeFrame object. The SomeFrame frame appears and the LoginView is no longer visible.
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class LoginView {
public static JFrame frame = new JFrame("Bus Tour Booking System");
public static void main(String[] args) {
frame.setSize(300, 200);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.add(panel);
placeComponents(panel);
frame.setVisible(true);
}
private static void placeComponents(JPanel panel) {
panel.setLayout(null);
JLabel titleLabel = new JLabel("Bus Tour Booking System");
titleLabel.setBounds(70,15,150,25);
panel.add(titleLabel);
JLabel userLabel = new JLabel("Username: ");
userLabel.setBounds(30, 50, 80, 25);
panel.add(userLabel);
JTextField userText = new JTextField(20);
userText.setBounds(120, 50, 130, 25);
panel.add(userText);
JLabel passwordLabel = new JLabel("Password: ");
passwordLabel.setBounds(30, 80, 80, 25);
panel.add(passwordLabel);
JPasswordField passwordText = new JPasswordField(20);
passwordText.setBounds(120, 80, 130, 25);
panel.add(passwordText);
JButton loginButton = new JButton("login");
loginButton.setBounds(100, 125, 80, 25);
panel.add(loginButton);
ActionListener myButtonListener = new MyButtonListener();
loginButton.addActionListener(myButtonListener);
}
private static class MyButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
SomeFrame newFrame = new SomeFrame();
newFrame.setVisible(true);
frame.setVisible(false);
}
}
}
This is the SomeFrame class.
import javax.swing.JFrame;
import javax.swing.JPanel;
public class SomeFrame extends JFrame {
public SomeFrame(){
super("something");
this.setSize(300, 200);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
this.add(panel);
this.setVisible(true);
}
}
So this problem is really giving me a headache because for some reason last night when i was working on it, my code ran perfectly and my textfields would show up without a problem...
Go to bed, wake up, time to work on it again aaaaaand bam. Now my JtextFields only show up when i highlight them or click them or something...I was wondering what could be wrong?
My code is really just messy and crappy at this point while i figure out a better way to design my program...
I thought it was just eclipse but netbeans is giving me the same issue.
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.awt.*;
import javax.swing.border.*;
public class DiffuserCalc {
//create the class data fields
private double Qts;
private double Qes;
private double Vas;
JFrame ProgramBounds = new JFrame();
JLabel label1= new JLabel("Qts");
JLabel label2= new JLabel("Qes");
JLabel label3= new JLabel("Fs");
JLabel label4= new JLabel("BL");
JLabel label5= new JLabel("Xmax");
JLabel label6= new JLabel("Fs");
JLabel label7= new JLabel("Vas");
JLabel label8= new JLabel("Diameter");
JLabel label9= new JLabel("Pmax (RMS)");
JTextField QtsParam = new JTextField("Value");
JTextField QesParam = new JTextField("Value");
JTextField FsParam = new JTextField(" ");
JTextField BLParam = new JTextField(" ");
JTextField XmaxParam = new JTextField(" ");
Font myFont = new Font("Tahoma", Font.BOLD, 20);
DiffuserCalc()
{
ProgramBounds.setTitle("Box Designer");
JPanel ParameterMenu = new JPanel();
JPanel FieldInputs = new JPanel();
ParameterMenu.setBounds(30, 0, 1180, 120);
FieldInputs.setBounds(0,0, 1280, 720);
ProgramBounds.add(ParameterMenu);
ProgramBounds.add(FieldInputs);
ProgramBounds.setSize(1280,720);
// LAYOUT
ParameterMenu.setLayout(new FlowLayout(FlowLayout.CENTER, 60, 10));
FieldInputs.setLayout(null);
Border lineBdr = BorderFactory.createLineBorder(Color.BLACK);
Border BlackBorder = BorderFactory.createTitledBorder(lineBdr, " T/S Parameters ", TitledBorder.CENTER, TitledBorder.TOP, myFont, Color.black);
//FIELD PROPERTIES
label1.setFont(myFont);
label2.setFont(myFont);
label3.setFont(myFont);
label4.setFont(myFont);
label5.setFont(myFont);
label6.setFont(myFont);
label7.setFont(myFont);
label8.setFont(myFont);
label9.setFont(myFont);
// PARAMETER BOUNDS
int XLoc = 150;
int YLoc = 70;
QtsParam.setBounds(XLoc, YLoc, 40, 20);
QesParam.setBounds(XLoc+95, YLoc, 40, 20);
FsParam.setBounds(XLoc+190, YLoc, 40, 20);
// ADD FIELDS
ParameterMenu.add(label1);
ParameterMenu.add(label2);
ParameterMenu.add(label3);
ParameterMenu.add(label4);
ParameterMenu.add(label5);
ParameterMenu.add(label6);
ParameterMenu.add(label7);
ParameterMenu.add(label8);
ParameterMenu.add(label9);
ParameterMenu.setBorder(BlackBorder);
FieldInputs.add(QtsParam);
FieldInputs.add(QesParam);
FieldInputs.add(FsParam);
FieldInputs.add(BLParam);
FieldInputs.add(XmaxParam);
// set everything proper
QtsParam.requestFocus();
ParameterMenu.setVisible(true);
FieldInputs.setVisible(true);
ProgramBounds.setVisible(true);
}
public double BoxDimension(int x, int y)
{
return x;
}
public static void main(String[] args) {
DiffuserCalc MainProgram = new DiffuserCalc();
}
}
Your code only sets the bounds for 3 text fields but you add 5 text fields to the panel.
Don't use a null layout!!!
Use a proper layout manager and then you don't have to worry about making mistakes like this.
Also, follow Java naming conventions. Variable names do NOT start with an upper case character.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.FlowLayout;
import java.awt.Font;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
public class DiffuserCalc {
//create the class data fields
private double qts;
private double qes;
private double vas;
private JFrame programBounds = new JFrame();
private JLabel label1= new JLabel("Qts");
private JLabel label2= new JLabel("Qes");
private JLabel label3= new JLabel("Fs");
private JLabel label4= new JLabel("BL");
private JLabel label5= new JLabel("Xmax");
private JLabel label6= new JLabel("Fs");
private JLabel label7= new JLabel("Vas");
private JLabel label8= new JLabel("Diameter");
private JLabel label9= new JLabel("Pmax (RMS)");
private JTextField qtsParam = new JTextField("Value");
private JTextField qesParam = new JTextField("Value");
private JTextField fsParam = new JTextField("");
private JTextField bLParam = new JTextField("");
private JTextField xmaxParam = new JTextField("");
private Font myFont = new Font("Tahoma", Font.BOLD, 20);
DiffuserCalc()
{
programBounds.setTitle("Box Designer");
JPanel parameterMenu = new JPanel();
JPanel labelPanel = new JPanel();
JPanel fieldInputs = new JPanel();
// LAYOUT
programBounds.setLayout(new BorderLayout());
parameterMenu.setLayout(new BorderLayout());
fieldInputs.setLayout(new FlowLayout(FlowLayout.LEFT));
fieldInputs.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
labelPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
labelPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
programBounds.add(parameterMenu, BorderLayout.NORTH);
parameterMenu.add(labelPanel, BorderLayout.NORTH);
parameterMenu.add(fieldInputs, BorderLayout.SOUTH);
// programBounds.add(fieldInputs);
programBounds.setSize(1280,720);
Border lineBdr = BorderFactory.createLineBorder(Color.BLACK);
Border BlackBorder = BorderFactory.createTitledBorder(lineBdr, " T/S Parameters ", TitledBorder.CENTER, TitledBorder.TOP, myFont, Color.black);
//FIELD PROPERTIES
label1.setFont(myFont);
label2.setFont(myFont);
label3.setFont(myFont);
label4.setFont(myFont);
label5.setFont(myFont);
label6.setFont(myFont);
label7.setFont(myFont);
label8.setFont(myFont);
label9.setFont(myFont);
// ADD FIELDS
labelPanel.add(label1);
labelPanel.add(label2);
labelPanel.add(label3);
labelPanel.add(label4);
labelPanel.add(label5);
labelPanel.add(label6);
labelPanel.add(label7);
labelPanel.add(label8);
labelPanel.add(label9);
parameterMenu.setBorder(BlackBorder);
qtsParam.setColumns(3);
fieldInputs.add(qtsParam);
qesParam.setColumns(3);
fieldInputs.add(qesParam);
fsParam.setColumns(2);
fieldInputs.add(fsParam);
bLParam.setColumns(2);
fieldInputs.add(bLParam);
xmaxParam.setColumns(2);
fieldInputs.add(xmaxParam);
// set everything proper
qtsParam.requestFocus();
programBounds.pack();
programBounds.setVisible(true);
}
public double BoxDimension(int x, int y)
{
return x;
}
public static void main(String[] args) {
DiffuserCalc MainProgram = new DiffuserCalc();
}
}
So I rewrote the class for you to be more according to the Java style standard. Next not using a Layout manager is asking for trouble. And even though your requirements are like you say it's still better to put the effort to use a Layout manager as you'll keep running into problems like these. Read more about layout managers here. Furthermore don't call setVisible on JPanels that you added to a frame. When you call setVisible on the JFrame it will call setVisible on all of it child components.
Next call the method setColumns on the JTextField instead of initializing it with spaces for more consistent and predictable behaviour.
I want to make a "simple" program. it consists of three buttons and when you click on one of them i want a picture to show up, but i don't know how to add the image properly.
If anyone has played pokemon i want to make the start where you select your starter pokemon.
Here is my code.
public LayoutLek(){
super("Starter");
panel=new JPanel();
panel.setLayout(new GridLayout(2,1));
top_p=new JPanel();
label1=new JLabel("Make a choice");
label1.setFont(new Font("Arial", Font.BOLD, 30));
label1.setForeground(Color.black);
ImageIcon green = new ImageIcon("Bilder/bulbasaur.jpg"); //Dont know if it is correct but...
JLabel label2 = new JLabel(green);
top_p.setBackground(Color.yellow);
top_p.add(label1);
bottom_p=new JPanel();
bottom_p.setLayout(new GridLayout(1,3));
panel.add(top_p);
panel.add(bottom_p);
button1=new JButton("Button 1");
button1.setBackground(Color.green);
button1.setForeground(Color.black);
button1.setFont(new Font("Arial", Font.BOLD, 24));
button2=new JButton("Button 2");
button2.setBackground(Color.red);
button2.setForeground(Color.black);
button2.setFont(new Font("Arial", Font.BOLD, 24));
button3=new JButton("Button 3");
button3.setBackground(Color.blue);
button3.setForeground(Color.black);
button3.setFont(new Font("Arial", Font.BOLD, 24));
bottom_p.add(button1);
bottom_p.add(button2);
bottom_p.add(button3);
button1.addActionListener(this);
button2.addActionListener(this);
button3.addActionListener(this);
this.add(panel);
//this.setSize(350, 300);
this.pack();
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setAlwaysOnTop(true);
}
public static void main(String[] args) {
new LayoutLek();
}
public void actionPerformed(ActionEvent e) {
System.out.println("Clicked"); //Just to test
Object src = e.getSource();
if(src==button1){
//Here should the image show up
}
else if(src==button2){
}
else if(src==button3){
}
}
If anyone can help i would be thankful!
Images that are embedded into your program should be loaded from the class path, not the file system. When you pass a String to the ImageIcon your telling the program to look in the file system. To load from the class path, use
new ImageIcon(getClass().getResource("/Bilder/bulbasaur.jpg");
where Bilder need to be in the src
Your JLabel label2 is locally scoped within the constructor, so you can't access it from outside the constructor, i.e. the actionPerformed. You need to declare it outside the constructor, as class members, as you seem to have done with your other objects.
Have all three ImageIcons already initialized As class members also.
Just use label2.setIcon(oneOfTheImageIcons); in the actionPerformed to change the icon of the JLabel
Swing apps should be run from the Event Dispatch Thread. You can do so by wrapping your new LayoutLek(); in a SwingUtilities.invokeLater... See Initial Threads for complete details.
You never add your label2 to a visible conainter.
After fixing all the above mentioned points, here is a runnable refactor. You just need to change your file paths accordingly.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class LayoutLek extends JFrame implements ActionListener {
JPanel panel;
JPanel top_p;
JLabel label1;
JPanel bottom_p;
JButton button1;
JButton button2;
JButton button3;
ImageIcon green;
ImageIcon blue;
ImageIcon red;
JLabel label2;
public LayoutLek() {
super("Starter");
green = new ImageIcon(getClass().getResource("/path/to/imgage"));
blue = new ImageIcon(getClass().getResource("/path/to/imgage"));
red = new ImageIcon(getClass().getResource("/path/to/imgage"));
label2 = new JLabel(green);
panel = new JPanel();
panel.setLayout(new GridLayout(2, 1));
top_p = new JPanel();
label1 = new JLabel("Make a choice");
label1.setFont(new Font("Arial", Font.BOLD, 30));
label1.setForeground(Color.black);
top_p.setBackground(Color.yellow);
top_p.add(label1);
bottom_p = new JPanel();
bottom_p.setLayout(new GridLayout(1, 3));
panel.add(top_p);
panel.add(bottom_p);
button1 = new JButton("Button 1");
button1.setBackground(Color.green);
button1.setForeground(Color.black);
button1.setFont(new Font("Arial", Font.BOLD, 24));
button2 = new JButton("Button 2");
button2.setBackground(Color.red);
button2.setForeground(Color.black);
button2.setFont(new Font("Arial", Font.BOLD, 24));
button3 = new JButton("Button 3");
button3.setBackground(Color.blue);
button3.setForeground(Color.black);
button3.setFont(new Font("Arial", Font.BOLD, 24));
bottom_p.add(button1);
bottom_p.add(button2);
bottom_p.add(button3);
button1.addActionListener(this);
button2.addActionListener(this);
button3.addActionListener(this);
this.add(panel);
this.add(label2, BorderLayout.PAGE_START);
//this.setSize(350, 300);
this.pack();
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setAlwaysOnTop(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new LayoutLek();
}
});
}
public void actionPerformed(ActionEvent e) {
System.out.println("Clicked"); //Just to test
Object src = e.getSource();
if (src == button1) {
label2.setIcon(green);
} else if (src == button2) {
label2.setIcon(blue);
} else if (src == button3) {
label2.setIcon(red);
}
}
}
Firstly, src.equals(button1). It's better practise to use the object-based equals method, == is better applied to primitive comparison (i.e. int, long, boolean, etc).
Secondly, you can do a couple of things.
Add the image to a container, then remove it and add another each time a button is clicked.
Add all three images to a container, set them all to invisible (setVisible(false)) and then in src.equals(button1/2/3) you set the appropriate image to visible. Container may need to be repainted.
Hope this helps!
I've got a simple Swing GUI and I want to add a new line of text to a JTextArea after a button is pressed, simple right?
The Button and it's ActionListener function correctly (printing stuff to the console works fine), but when I use .append()or .setText() to add text to the textarea, I get a nullpointer exception.
As always, code it below. Any input would be greatly appreciated, thanks!!!
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.LineBorder;
public class GUI extends JFrame implements ActionListener {
private JFrame frame;
private JLabel paneHeader;
public JTextArea ipArea, portArea, outputLog, orderLog, cookLog;
private JButton newServer;
public String ipAddress, portNumber, cashierName, cookName;
public GUI() {
initGUI();
}
public void initGUI() {
frame = new JFrame("Restaurant Overview");
Container contentPane = frame.getContentPane();
JLabel paneHeader = new JLabel("Restaurant Monitoring System");
paneHeader.setBounds(200, 0, 200, 25);
paneHeader.setFont(new Font("Calibri", Font.BOLD, 14));
JLabel ipLabel = new JLabel("IP Address: ");
ipLabel.setBounds(25, 30, 75, 20);
ipLabel.setFont(new Font("Calibri", Font.PLAIN, 12));
final JTextArea ipArea = new JTextArea();
ipArea.setBorder(new LineBorder(Color.GRAY));
ipArea.setBounds(105, 30, 100, 20);
JLabel portLabel = new JLabel("Port Number: ");
portLabel.setBounds(25, 55, 75, 20);
portLabel.setFont(new Font("Calibri", Font.PLAIN, 12));
final JTextArea portArea = new JTextArea();
portArea.setBorder(new LineBorder(Color.GRAY));
portArea.setBounds(105, 55, 100, 20);
JButton newServer = new JButton("Create new Server");
newServer.setBorder(new LineBorder(Color.GRAY));
newServer.setBounds(250, 30, 150, 40);
newServer.setActionCommand("createserver");
newServer.addActionListener(this);
JTextArea outputLog = new JTextArea(" ");
outputLog.setBorder(new LineBorder(Color.GRAY));
outputLog.setBounds(25, 90, 150, 150);
//outputLog.setEditable(false);
JTextArea cashierLog = new JTextArea();
cashierLog.setBorder(new LineBorder(Color.GRAY));
cashierLog.setBounds(185, 90, 150, 150);
//cashierLog.setEditable(false);
JTextArea cookLog = new JTextArea();
cookLog.setBorder(new LineBorder(Color.GRAY));
cookLog.setBounds(345, 90, 150, 150);
//cookLog.setEditable(false);
contentPane.add(paneHeader);
contentPane.add(ipLabel);
contentPane.add(ipArea);
contentPane.add(portLabel);
contentPane.add(portArea);
contentPane.add(outputLog);
contentPane.add(cashierLog);
contentPane.add(cookLog);
contentPane.add(newServer);
frame.setLayout(null);
frame.pack();
frame.setSize(600,400);
frame.setVisible(true);
}
public void test() {
//ipAddress = ipArea.getText() + "\n";
//portNumber = portArea.getText() + "\n";
String text = "lemons";
//System.out.println(text);
outputLog.append(text);
//outputLog.append(portNumber);
}
public void actionPerformed(ActionEvent e) {
if ("createserver".equals(e.getActionCommand())) {
//test();
outputLog.append("lemons");
} else {
//Do Nothing
}
}
}
You are likely shadowing a variable -- declaring it more than once, but initializing a local variable not the class field, and so the class field remains null.
Edit:
Yep, sure enough you do. In your constructor you have
JTextArea outputLog = new JTextArea(" ");
This re-declares the outputLog variable, and so you are initializing only the variable local to the constructor. The solution is not to redeclare the variable but instead initialize the class field. So change the above to
outputLog = new JTextArea(" ");
You will need to do this for every variable that needs to be accessed in the class scope. For those that are OK to declare locally, do so, but in the sake of safety, get rid of their corresponding class declaration so as not to risk causing the same error in the future.
Your error is that the instance variable outputLog is not initialized.
your code not done on EDT, you have to wrap tht into invokeLater()
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
outputLog.setText(outputLog.getText()
+ System.getProperty("line.separator") + text);
}
});