Null pointer on run of class - java

When I run this project, I get a NullPointer.
"Exception in thread "main" java.lang.NullPointerException
at movieinfo.Swinggui.gui(Swinggui.java:71)
at movieinfo.Swinggui.main(Swinggui.java:38)
"
It doesn't seem on those two lines, I am accessing that hadn't already been declared.
I attempted setting breakpoints and debugging to fix it myself, to no avail.
Thanks for helping me, I really am not asking to be spoonfed.
package movieinfo;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.List;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import org.apache.commons.io.FileUtils;
import com.json.parsers.JSONParser;
import com.json.parsers.JsonParserFactory;
public class Swinggui {
private static JButton enter;
private static JTextField movietext;
private static JTextArea movieinfo;
private static JList listofmovies;//converts moviestowatch into gui element.
private static File textfilemovie; //file which movies marked for watching are saved
private static java.util.List<String> moviestowatch; //arraylist which is populated by textfilemovie than printed to GUI element.
public static void main(String[] args) throws IOException
{
yourMovies();
gui();
json();
}
public static void gui()
{
JFrame maingui = new JFrame("Gui");
maingui.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.VERTICAL;
enter = new JButton("Enter");
c.gridx = 2;
c.gridy = 1;
maingui.add(enter, c);
movieinfo = new JTextArea(5,20);
movieinfo.setBorder(BorderFactory.createMatteBorder(2,2,2,2,Color.red));
movietext = new JTextField(18);
c.gridx = 1;
c.gridy = 1;
maingui.add(movietext, c);
final JScrollPane scrolll = new JScrollPane(movieinfo);
c.gridx = 1;
c.gridy = 3;
c.gridwidth = 2;
maingui.add(scrolll, c);
final JLabel titlee = new JLabel("Enter movie name below!");
c.gridx = 1;
c.gridy = 0;
maingui.add(titlee, c);
maingui.setResizable(false);
maingui.setVisible(true);
listofmovies = new JList(moviestowatch.toArray());
c.gridx = 4;
c.gridy = 3;
maingui.add(new JScrollPane(listofmovies), c);
movieinfo.setLineWrap(true);
movieinfo.setWrapStyleWord(true);
movieinfo.setEditable(false);
scrolll.getPreferredSize();
//pangui.setPreferredSize(new Dimension(300, 150));
//pangui.add(scrolll, BorderLayout.CENTER);
//movieinfo.add(scrolll);
maingui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
maingui.pack();
}
public static void json()
{
enter.addActionListener(new ActionListener(){
private JsonParserFactory factory;
private JSONParser parser;
#SuppressWarnings("rawtypes")
private Map jsonData;
public void actionPerformed(ActionEvent e)
{
System.out.println(apicall.getMovieInfo(movietext.getText()));
factory = JsonParserFactory.getInstance();
parser = factory.newJsonParser();
jsonData = parser.parseJson(apicall.getMovieInfo(movietext.getText()));
String Title = (String)jsonData.get("Title");
String Year = (String)jsonData.get("Year");
String Plot = (String)jsonData.get("Plot");
movieinfo.setText("Title: "+Title+"\nYear: "+ Year +"\nPlot: "+Plot);
}
});
}
public static void yourMovies() throws IOException
{
textfilemovie = new File(org.apache.commons.io.FileUtils.getUserDirectory() + "/yourmovies.txt");
textfilemovie.createNewFile();
moviestowatch = FileUtils.readLines(textfilemovie);
while (listofmovies.getSelectedValue().toString()!= null)
{
movietext.setText(listofmovies.getSelectedValue().toString());
enter.doClick();
}
}
}

You're calling gui() before calling yourMovies() so do not initialize the ArrayList before using it.
But that is not what is important here. No, what is important is that you recognize the process of how to debug a NPE on your own:
Check the line that throws the NPE
Find the variable on that line that is null
Then search back into the code to see why it is null when you think that it shouldn't be.
Usually these errors are easy to fix once you know how.
Your other problems include:
You are over-using static. Your code has no "state", no true OOPs classes, and this will limit your ability to extend and improve your code. The only static method should be the main method, and this should only contain code to set up your classes and start them, and that's it.
Your json code should be in a class of its own, separate from the GUI class. This will allow you to debug and enhance it in isolation from completely unrelated code. Look up cohesion and coupling. You want your class cohesion to be high and coupling to be low: keep related stuff together and unrelated stuff apart.
Your while loop, while (listofmovies.getSelectedValue().toString()!= null)... makes no sense in its current location. You shouldn't be calling doClick() on a GUI's buttons while it's in the process of being created, of being built, and before it is rendered.
Your code is thrown together without planning. Much better would be to write out the structure of your program on paper first before committing any code.

It doesn't seem on those two lines, I am accessing that hadn't already
been declared.
Believe the JVM. If it says there's a NPE at that line, then it's true. Your "seem" is a bad assumption.
I attempted setting breakpoints and debugging to fix it myself, to no
avail.
Sounds like you need to learn how to set breakpoints in your IDE. That will sort it out quickly if you do it properly. Which one are you using?
Thanks for helping me, I really am not asking to be spoonfed.
Unfortunately, you are asking to be spoonfed.

Your moviestowatch is not initialised.
You are calling yourMovies() to initialise moviestowatch.
But you are trying to access moviestowatch in gui().

you have declared moviestowatch at line 35
private static java.util.List<String> moviestowatch; //arraylist which is populated by textfilemovie than printed to GUI element.
and used it at line 71 in function gui()
listofmovies = new JList(moviestowatch.toArray());
initialize it before using it.
the sequence of calling function is
gui();
json();
yourMovies();
your list is initializing in yourMovies() method.and you are using it in gui() method. so call yourMovies() method before calling gui() method which actually using it.
EDIT:
your next error is getting a nullpointer # line 115 in the following while loop.
To solve above error what you have done is changed the sequence and called yourMovies() before gui(). but Here you have initialized listofmovies list in gui and used in yourMovies() method :).
It is general programming practice that for all list/object you have to manually check that everytime before you use. it should be initialized before using it. otherwise it will throw NPE.

If you get NullPointerException it always mean that one of your classes fields was not initialized. There is no way you will get NPE with local reference variable because compiler will warn you. I myself try to initialize everything that does not require additional input on the line where I am declaring it and this practice saved me a lot of NPE. And this is usuful especially with containers.

Related

Java Assigning Value to ComboBox

public static JComboBox[] ComboBox = new JComboBox[100];
String Array[] = { "Item1", "Item2", "Item3", "Item4" };
final DefaultComboBoxModel model = new DefaultComboBoxModel(Array); // this should assign the array and it does
ComboBox[1] = new JComboBox(model); // added this as the above also didn't help
ComboBox[1].setModel(model); // added this in because the above line didn't help
The issue I'm having with this code is its returning as part of the values, "[L]java,labg.String.....". I think this relates to the fact the array has been called (as a string not a true array).
I've tried every possible method i can think of to get rid of that random entry, I've tried true arrays, lists, nothing works. If I delete out Array..
ComboBox[1] = new JComboBox();
and just call the ComboBox naturally, its still there and I can't figure out why.
Updated 18/09/17 # 7.17am
Sorry I didn't really ask the question too well, it was really late and I'm actually experienced in VBA not so much in Java (which i'm still learning forgive me).
Yes I would like to improve my syntax approach, so please feel free to review my code.
Okay to start with, here is the design of the program. The purpose of the application is assist with capturing data in different aspects of their job, as they have templates they must fill out each time they preform an action (like changes address, leaves the country etc).
They select the questionset (example change of address), and then the template they need to fill out populates onto the userform.
The issue I was having was that when adding a dynamic combobox as an array, the combobox was displaying a strange item ([L]java,labg.String.....), even when all elements of the combobox are empty (or forced to be empty).
All I want is to be able to generate a dynamic combobox in an array format, and be able to retrieve the value the user has selected.
In writing the test code for you guys that you can compile....it just works fine...so I'm thinking I need to re-evaluate how the rest of my program is designed.
Here is the code for your reference, if you could help me figure out how to pass non static method's I'd appreciate that too!
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.event.*;
import java.awt.BorderLayout;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JSplitPane;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTextField;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
public class ExampleApplication {
public static JComboBox[] my_dynamic_combobox = new JComboBox[100]; // Declare my dyanmic combobox so its visible throughout the instance of this class (see my explanation as to why I use static objects)
public static JFrame userform1 = new JFrame("My UserForm"); // Creates new instance of JFrame with title 'My UserForm'
public static class my_functions { // This is what I use to hold my functions to avoid repitition in code
public static void add_dynamic_combobox(int my_combobox_array, String[] my_combobox_items) { // This is a function, it adds a new dynamic combobox based on the value passed form a loop, and assigns the relevant list to it.
my_dynamic_combobox[my_combobox_array] = new JComboBox(my_combobox_items); // This should populate the newly created combobox, with its relevant items ONLY
my_dynamic_combobox[my_combobox_array].setBounds(10, 10, 100, 20); // I'm only displaying one combobox at the moment, so positioning doesn't matter here.
userform1.add(my_dynamic_combobox[my_combobox_array]);
}
// End of my_functions class
}
public static void main(String[] args) {
// The static void won't let me pass in/out any arguments or run any class/methods that aren't static. I don't know how to get around this. Doesn't like non-static context
String the_list[] = { "Item1", "Item2", "Item3"};
userform1.setSize(900, 225); // Set 400 width and 500 height
userform1.setLayout(null); // Using no layout managers
userform1.setDefaultCloseOperation(userform1.EXIT_ON_CLOSE); // define exit behaviour
for (int i=0; i<10; i++){
my_functions.add_dynamic_combobox(i, the_list);
}
// Loop has finished display the form.
userform1.setVisible(true);
}
}
edit 2: 18/09/17 # 9.39pm - Still no luck is isolating the code that is causing the issue. It definitely seems to be an issue when referring between static and non-static methods though.
You can use some thing like this
public static JComboBox[] comboBox = new JComboBox[100];
String[] array = { "Item1", "Item2", "Item3", "Item4" };
comboBox[1] = new JComboBox(array);
to add single items use this
comboBox[1].addItem("Item goes here");
No need to declare a DefaultComboBoxModel, as JComboBox does this for you. So try something like this:
public static JComboBox<String>[] comboBox = new JComboBox[100];
String[] array = { "Item1", "Item2", "Item3", "Item4" };
comboBox[1] = new JComboBox<>(array);

Getting info from an array that is in another JPanel

I am storing some info in an ArrayList that is in a JPanel. I want to access this info from a JFrame so that I can print the contents of the ArrayList.
How do I do this?
This is what i have tried so far:
package projektarbete;
import java.awt.*;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
public class Spelet extends javax.swing.JPanel {
ArrayList<String> Resultat = new ArrayList<>();
.....
if(gameOver == true || vinst == true){
btnTillbakaTillMeny.setVisible(true);
int klick = antalKlick;
String namn = txfNamn.getText();
//Integer.toString(klick);
String klickString = klick+"";
String score = namn+"\t"+klickString;
Resultat.add(score);
That was the JPanel and the info is stored in the ArrayList called Restultat.
This is how I am trying to retrieve the info from the JFrame:
package projektarbete;
import javax.swing.JFrame;
public class Instruktioner extends javax.swing.JFrame {
//private final Meny Meny = new projektarbete.Meny();
private static void close() {
// throw new UnsupportedOperationException("Not supported yet.");
}
public Instruktioner() {
initComponents();
Spelet Resultat = new Spelet();
jTextArea1.setText(Resultat);
}
The thing is that NetBeans is underlining Resultat in jTextArea1.setText(Resultat);
Any ideas?
You cannot put a Resultat object as a parameter to setText(), because that method does not Accept a parameter of that type. If you look at the javadoc for the method, you will see what type(s) it takes (there may be more than one 'signature' for the method, each signature taking a different combination of types).
I think what you want to do is have a class and then an object that holds the data for your program. It will have the necessary methods for setting and obtaining data, and for calculating things that need calculation. Then, any object that is going to present information to the user (panel, frame, whatever) will need to have a reference to the class holding the data, and can call methods to get what it needs.
This is the very fundamental idea behind "model-view-controller" -- a *separation of concerns", where the logic for handling data is separated from the logic for displaying that data. It helps in the common cases where you need to change the presentation but the data handling itself is ok.
setText() is waiting for a string, but you gave it an ArrayList

Don't know how to fix my PropertyChangeListener on a JFormattedTextField

EDIT at end of post
Test Code and Output
import java.awt.EventQueue;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.NumberFormat;
import javax.swing.JFormattedTextField;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.text.NumberFormatter;
public class Test{
private JFormattedTextField input, input2;
private NumberFormatter formatter;
private PropertyChangeListener listener;
public Test(){
formatter = new NumberFormatter(NumberFormat.getNumberInstance());
input = new JFormattedTextField(formatter);
input2 = new JFormattedTextField(formatter);
listener = new PropertyChangeListener(){
#Override
public void propertyChange(PropertyChangeEvent evt) {
convert(evt);
}
};
input.setColumns(4);
input2.setColumns(4);
input.addPropertyChangeListener("value", listener);
input2.addPropertyChangeListener("value", listener);
input.setValue(0.0);
JPanel panel = new JPanel();
panel.add(input);
panel.add(input2);
JOptionPane.showMessageDialog(null, panel);
}
private void convert(PropertyChangeEvent evt){
if (evt.getSource()== input){
if (evt.getSource()!= null){
double temp;
temp = converter((Double)evt.getNewValue());
input2.setValue(temp);
}
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable(){
public void run(){
new Test();
}
});
}
private double converter(double value){
value = value*2;
return value;
}
}
The stack trace:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Double
at test.Test.convert(Test.java:46)
My thoughts
Because I have a method that passes in a double (it's convert()) , and seemingly evt.getNewValue() returns the direct value, which at the time of input is technically a long, it's throwing that error.
But every attempt at parsing my evt.getNewValue() to a double hasn't worked. Perhaps a little knowledge of what I'm trying to do with this program would help.
What The Program is for
So I've got a JPanel (in a tabbedPane) that has two JFormattedTextField inputs. It's a conversion application. My conversion class method passes in a double and returns a double. I'd like the fields to be linked together, or in other words, as soon as one field's input is changed the other changes with it (as in it's the output of the conversion).
I was considering scrapping the PropertyChangListener and going for a DocumentListener instead, but opted to try the former first as the latter has 3 overrideable methods I have to take care of, one of which might cause some unexpected results (highlighting and deleting the field would trigger two events for example).
TL;DR:
Is there a better way of getting a dynamically updating, dual input field application? Input one number into one field and the other field's number automatically updates.
Still a novice at Java.
Edit1
I've found a temporary solution: Have a DecimalFormat as the format in the JFormattedTextField. But if it could work without having a decimal as well I'd love it.
Edit2
Question answered, didn't realize evt.getNewValue() was returning a Number instance.
All you know for sure is that the object returned by evt.getNewValue() is a Number object. What if you use that information to your advantage and try something along these lines:
temp = ((Number)evt.getNewValue()).doubleValue();

variable can not be resolved

I'm working through the book Beginning BlackBerry 7 Development and really putting my little or non existent oop/java skills to the test- eclipse is throwing up an error from the code in the book stating that loginhandler hasn't been declared- and yes its correct- it hasn't been declared but it also hasn't been declared in the book.
What has been done is an inner class called logincommandhandler (at the bottom of my code) which can be seen in an excerpt here- http://my.safaribooksonline.com/book/-/9781430230151/chapter-4-user-interface-basics/67 - this is what its meant to be calling (i assume) but my limited oop skills i do not know what loginHandler should be- should it be defined somewhere with a type?
(there is no erata for the book)
package com.beginningblackberry.uifun;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.EditField;
import net.rim.device.api.ui.component.PasswordEditField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.CheckboxField;
import net.rim.device.api.ui.component.ObjectChoiceField;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.util.StringProvider;
import net.rim.device.api.command.Command;
import net.rim.device.api.command.CommandHandler;
import net.rim.device.api.command.ReadOnlyCommandMetadata;
public class UiFunMainScreen extends MainScreen implements FieldChangeListener {
BitmapField img;
EditField usernameField;
PasswordEditField passwordField;
ObjectChoiceField domainField;
CheckboxField rememberCheckBox;
ButtonField clearButton, loginButton;
public UiFunMainScreen(){
Bitmap logoBitmap = Bitmap.getBitmapResource("img/upd8rLOGO.png");
img = new BitmapField(logoBitmap, Field.FIELD_HCENTER);
add(img);
add(new SeparatorField());
add(new LabelField("Please Enter Your Credentials:"));
usernameField = new EditField("Username:","");
passwordField = new PasswordEditField("Password:","");
domainField = new ObjectChoiceField("Domain",new String[] {"Home","Work"});
rememberCheckBox = new CheckboxField("Remember password",false);
add(usernameField);add(passwordField);
add(domainField);
add(rememberCheckBox);
add(new SeparatorField());
clearButton = new ButtonField("Clear",ButtonField.CONSUME_CLICK);
loginButton = new ButtonField("Login",ButtonField.CONSUME_CLICK);
HorizontalFieldManager buttonManager = new HorizontalFieldManager(Field.FIELD_RIGHT);
buttonManager.add(clearButton);
buttonManager.add(loginButton);
add(buttonManager);
clearButton.setChangeListener(this);
//loginButton.setChangeListener(this);
loginButton.setCommand(new Command(LoginHandler));
}
//routing
public void fieldChanged(Field field, int context){
if(field == clearButton){
clearTextFields();
}else if(field == loginButton){
login();
}
}
private void login(){
if(usernameField.getTextLength()== 0 || passwordField.getTextLength() == 0){
Dialog.alert("You must enter a username and password");
}
else
{
String username = usernameField.getText();
String selectedDomain = (String) domainField.getChoice(domainField.getSelectedIndex());
LoginSuccessScreen loginSuccessScreen = new LoginSuccessScreen(username, selectedDomain);
UiApplication.getUiApplication().pushScreen(loginSuccessScreen);
}
}
public void clearTextFields ()
{
usernameField.setText("");
passwordField.setText("");
}
protected void makeMenu(Menu menu, int instance){
super.makeMenu(menu, instance);
/*
menu.add(new MenuItem(new StringProvider("Login"),20,10){
public void run(){
login();
}
});
*/
//login menu item
MenuItem loginMenu = new MenuItem(new StringProvider("Login"),20,10);
loginMenu.setCommand(new Command(LoginHandler));
menu.add(loginMenu);
//clear text menu item
menu.add(new MenuItem(new StringProvider("Clear"),20,10){
public void run(){
clearTextFields();
}
});
}
class LoginCommandHandler extends CommandHandler
{
public void execute(ReadOnlyCommandMetadata metadata, Object context){
login();
}
}
}
and the error-
LoginHandler cannot be resolved to a variable UiFunMainScreen.java /UiFun/src/com/beginningblackberry/uifun line 69 Java Problem
any blackberry/java wizards shed some light on where i am going wrong?
Update
No one really answered the question bang on- to call the new inner class i called this instead
MenuItem loginMenu = new MenuItem(new StringProvider("Login"),20,10);
loginMenu.setCommand(new Command(new LoginCommandHandler()));
menu.add(loginMenu);
update 2 second answer
Declaring loginHandler as a class variable also works -
LoginCommandHandler loginHandler = new LoginCommandHandler();
My guess would be that it should be an instance of LoginCommandHandler (the class declared at the end). It's a guess, but an educated one: Command's constructor expects a CommandHandler instance, and LoginCommandHandler extends CommandHandler, so...
The easy change is to change all the places that look like this:
loginButton.setCommand(new Command(LoginHandler));
to:
loginButton.setCommand(new Command(new LoginCommandHandler()));
E.g., we're calling the LoginCommandHandler constructor and passing the resulting object into new Command().
Or if for some reason (I haven't really read the code) you need a reference to the handler, declare and instantiate it:
LoginCommandHandler loginHandler = new LoginCommandHandler();
...and then use it
loginButton.setCommand(new Command(loginHandler));
(Note that there are multiple places where they've made this mistake in the that quoted code.)
Your code is missing this line
LoginCommandHandler loginHandler = new LoginCommandHandler();
Moreover you can get code for the book here.
The problem is in this line
loginButton.setCommand(new Command(LoginHandler));
You proabably need a instance of LoginHandler (new LoginHandler()) to pass to new Command method.
As the error indicates, the error is in line 69, which I assume is this:
loginButton.setCommand(new Command(LoginHandler));
Assuming LoginHandler is the name of a class or interface, this line is invalid.
It should be something like new Command(LoginHandler.class), new Command(new LoginHandler()) or maybe new Command("LoginHandler"), since the parameter requires you to pass an object (the type object for a class would be <classname>.class).
If it should be a variable, then it simply doesn't exist (btw. Java convention is that variable names start with a lower case letter) and you have to create it.
... it hasn't been declared but it also hasn't been declared in the book. ... (there is no erata for the book)
This doesn't mean the code in the book is 100% correct and compilable.

Java For Loop Inside Constructor is Infinitely Repeating

So, for some reason when I try to use a for loop to initialize panels in chess board, it actually loops the loop itself. In other words, it doesn't go on forever, but it starts and completes again and again.
package chessgame;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ChessGame extends JFrame implements ActionListener{
public static final int WIDTH=800;
public static final int HEIGHT=800;
public static void main(String[] args) {
ChessGame gui = new ChessGame();
gui.setVisible(true);
}
public ChessGame(){
super("Chess Game Demo");
setSize(WIDTH, HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(8,8));
JPanel[] chessSquares = new JPanel[64];
for (int a=0;a<64;a++){
System.out.println(a);
}
}
}
I have included all potentially relevant code because I plan to use indices of chessSquares to color squares black and white. When I do this I also get a NullPointerException. I can understand why I'm getting that given the following error, but I cannot at all understand why a would be printed 0, 1....62, 63 over and over again. I am relatively new to Swing and have absolutely no idea why it does this. If anyone could explain that would be tremendously helpful. Thanks.
Don't put meaningful initialization in ChessGame's constructor, but instead override frameInit. When you do, also be sure to call super.frameInit(). See the javadoc or this tutorial.

Categories