0

I am trying to add a value and display it on a progress bar i have created on a jframe through my main (because i have methods left and right and i want that value to be from 1 of theses) but when i run it it gives me

Exception in thread "main" java.lang.NullPointerException 

i understand that i have to initialize the "var" so I wont be getting that error but i dont really know how. (i am kind of new to java)

This is my code (there are probably unnecessary stuff here but they were created automatically through the design)

import java.io.IOException;

public class UI extends javax.swing.JFrame {

/**
 * Creates new form UI
 */
public UI() {
    initComponents();
}


/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    p1hp = new javax.swing.JProgressBar();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(p1hp, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(768, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
            .addContainerGap(469, Short.MAX_VALUE)
            .addComponent(p1hp, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(100, 100, 100))
    );

    pack();
}// </editor-fold>                        

/**
 * @param args the command line arguments
 * @throws java.io.IOException
 */
public static void main(String[] args) throws IOException {


    java.awt.EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            new UI().setVisible(true);
        }
    });
// THIS IS WHAT I AM TRYING TO DO
  p1hp.setStringPainted(true);
  p1hp.setValue(12);
  }

// Variables declaration - do not modify                     
public static javax.swing.JProgressBar p1hp;
// End of variables declaration   
}

aside that though, i tried creating a button, which i added thoses 2 lines and it worked fine
(the code for the button isnt here)

Note1: I manually maked the progressbar static bacause if not, I would get the error

non-static variable p1hp cannot be referenced from a static context

Note2: I have read this answer: What is a NullPointerException, and how do I fix it?
Still not sure how to fix it

Note3: I am using Netbeans 8.2

3 Answers3

2

Do not put the JProgressBar static, instead, add a getter that would allow you to get it in your main. You will face other issue because of your design tho.

public JProgressBar getProgressBar()
{
    return p1hp;
}

And then in your main :

UI ui = new UI();
final JProgressBar progressBar = ui.getProgressBar();

To set values in your main use :

public static void main(String[] args) throws IOException {

    java.awt.EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            UI ui = new UI();
            ui.setVisible(true);
            ui.getProgressBar().setStringPainted(true);
            ui.getProgressBar().setValue(12);
        }
    });
Demogorii
  • 656
  • 5
  • 16
  • nope, doesnt display anything by using my 2 lines progressBar.setStringPainted(true); progressBar.setValue(12); – Xaralabos Nikolaidhs Jun 01 '17 at 18:12
  • Because you are not in the UI thread. You can fix this by using `SwingUtilities.invokeLater(...)` and create a new anonymous `Runnable` inside. I will update to reflect this. – Demogorii Jun 01 '17 at 18:25
  • ok, tnx, this works too. A other guy above game me a different answer which worked too, i will ask my teacher which1 is better :P – Xaralabos Nikolaidhs Jun 01 '17 at 18:35
  • Mine is, using static references for UI components is very bad practice. ;) – Demogorii Jun 01 '17 at 18:40
  • Note: it works even if i remove thoses 2 lines UI ui = new UI(); final JProgressBar progressBar = ui.getProgressBar(); Before i set my values – Xaralabos Nikolaidhs Jun 01 '17 at 18:40
  • i am still using my progressbar as static, if i remove it, i get the "non-static variable p1hp cannot be referenced from a static context" error, but the problem is solved anyway, which was the nullexception – Xaralabos Nikolaidhs Jun 01 '17 at 18:43
0

I manually maked the progressbar static bacause if not, I would get the error

You can create your class object and then access using that object. This will prevent you from

non-static variable p1hp cannot be referenced from a static context

But it is not good for here because when you create new object from UI new JFrame will create.

Wrap using try-catch block. This will handle your exception.

try{
    //where null values occur
}catch(NullPointerException e){
  System.out.println("errr");//you dont want add this but it is good to display something.
}

UPDATE:

From looking at your code I think you are creating GUI's in netbeans. If it is you have to do as following,

Right click on JProgressBar in navigator or in JFrame. Next, goto custom code and then tick the static and change Access: to `public. And then you can do any changes.

Or:

In that window add your code for JProgressBar in initialization code

enter image description here

Now you donot even need to make it static.

Blasanka
  • 21,001
  • 12
  • 102
  • 104
  • it prints the "errr" fine but i still want to add value to it :/ – Xaralabos Nikolaidhs Jun 01 '17 at 17:57
  • Are you use netbeans – Blasanka Jun 01 '17 at 18:01
  • i already have it public on the code i posted – Xaralabos Nikolaidhs Jun 01 '17 at 18:14
  • @XaralabosNikolaidhs Im sorry not the `public`, `static`. then you can add in main as above your code – Blasanka Jun 01 '17 at 18:15
  • i lost u, if u mean removing the static and leaving it just public then i already said what happens, it give me a "non-static variable p1hp cannot be referenced from a static context" error... also i cant modify anything inside the "private void initComponents()", probably a netbeans thing, i dont know – Xaralabos Nikolaidhs Jun 01 '17 at 18:18
  • @XaralabosNikolaidhs You can make it `public` and `static` and edit in souece code but their is a simpler way I added it as a image. try that out – Blasanka Jun 01 '17 at 18:23
  • as i said, i want to modify it through my main. I have some other classes which i use some methods from them to get some numbers, which i want to use on this progressbar. I am not sure if i can use thoses methods on the area u are talking about – Xaralabos Nikolaidhs Jun 01 '17 at 18:25
  • You can create object from that classes inside in it and do whatever you want – Blasanka Jun 01 '17 at 18:26
0

You are initializing Progress bar p1hp variable in the UI constructor but UI constructor is being run inside invokeLater that does not guarantee that it will be executed right before the next line that calls p1hp.setStringPainted(true);

As a quick fix initialize p1hp right in the declaration like this:

public static javax.swing.JProgressBar p1hp = new javax.swing.JProgressBar();

UPDATE:

Here is a sample code that starts/stops progress. The code is not intended to be a complete solution but is a good start to get going with Swing and progress handling. I have not commented the code much but anyone is free to ask questions in form of comments right in the code:

Screen:

enter image description here

Progress Handler:

public interface ProgressHandler {

public void startProgress();

public void updateProgress(String message, int progress);

public void stopProgress();

}

Main View:

public class MainView {
private JComponent view = null;

private ProgressView progressView = null;
private LoadDataView loadDataView = null;

public MainView(){
    progressView = new ProgressView();
    loadDataView = new LoadDataView();
}

public JComponent getView(){
    if (view == null) view = createView();
    return view;
}

private JComponent createView(){
    JPanel result = new JPanel( new BorderLayout() );

    result.add( progressView.getView(), BorderLayout.NORTH );
    result.add( loadDataView.getView(), BorderLayout.CENTER );

    return result;
}

public static void main(String[] args) throws IOException {
    MainView mainView = new MainView();

    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    frame.getContentPane().add( mainView.getView() );

    frame.setSize(400, 200);
    frame.setVisible(true);
}

}

Progress View

public class ProgressView {

private static ProgressHandlerImpl progressHandler = new ProgressHandlerImpl(); 

private JComponent view = null;

public static ProgressHandler getProgressHandler(){
    return progressHandler;
}

public JComponent getView(){
    if (view == null) view = createView();
    return view;
}

private JComponent createView(){
    JPanel result = new JPanel( new BorderLayout() );        
    result.add( progressHandler.getMessageLabel(), BorderLayout.NORTH );
    result.add( progressHandler.getProgressBar(), BorderLayout.CENTER );
    return result;
}

private static class ProgressHandlerImpl implements ProgressHandler{
    public JProgressBar progressBar = null;
    public JLabel messageLabel = null;

    public ProgressHandlerImpl(){
        progressBar = new JProgressBar();
        progressBar.setVisible(false);
        progressBar.setStringPainted(true);

        messageLabel = new JLabel();
        messageLabel.setVisible(false);
    }

    public JProgressBar getProgressBar(){
        return progressBar;
    }

    public JLabel getMessageLabel(){
        return messageLabel;
    }

    @Override
    public void startProgress(){
        java.awt.EventQueue.invokeLater( new Runnable(){ public void run(){
        progressBar.setValue(0);
        progressBar.setVisible(true); } } );            
    }

    @Override
    public void updateProgress(String message, int progress) {
        java.awt.EventQueue.invokeLater( new Runnable(){  public void run(){
        progressBar.setValue(progress); 

        if (message == null) return;

        if ( !messageLabel.isVisible() ) messageLabel.setVisible(true);

        messageLabel.setText(message);
        } } );  
    }

    @Override
    public void stopProgress(){
        java.awt.EventQueue.invokeLater( new Runnable(){  public void run(){
        progressBar.setValue(0);
        progressBar.setVisible(false); 
        messageLabel.setVisible(false);} } );  
    }       
}

}

Load View

public class LoadDataView {
private JComponent view = null;
private Thread thread = null;

public JComponent getView(){
    if (view == null) view = createView();
    return view;
}

private JComponent createView(){
    JPanel result = new JPanel();

    JButton startProgressButton = new JButton("start");
    startProgressButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { startProgress(); } } );        
    result.add(startProgressButton);

    JButton stopProgressButton = new JButton("stop");
    stopProgressButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { stopProgress(); } } );        
    result.add(stopProgressButton);

    return result;
}

private void startProgress(){
    if (thread != null) throw new IllegalStateException();

    thread = new Thread( new Runnable(){ public void run(){
        ProgressView.getProgressHandler().startProgress();

        for (int i = 0; i < 100; i++){
            ProgressView.getProgressHandler().updateProgress("Loading...", i);

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {                   
                ProgressView.getProgressHandler().updateProgress("Loading stopped!", i);
                //do some other logging
                break;
            }
        }

    } } );

    thread.start();
}

private void stopProgress(){
    if (thread == null) return;

    thread.interrupt(); 

    thread = null;
}

}

tsolakp
  • 5,858
  • 1
  • 22
  • 28
  • it wasnt exacly like that i used " public static final javax.swing.JProgressBar p1hp = new javax.swing.JProgressBar(); " instead (because i cant manually modify it, it was ether final or not static) – Xaralabos Nikolaidhs Jun 01 '17 at 18:29
  • So you're recommending that he toss out object-oriented programming principles, that he fix things *backwards* by making them static, that he use static to allow sharing of fields between classes? This is not a good recommendation. **Much** better to show him how to fix the code so statics aren't needed. – Hovercraft Full Of Eels Jun 01 '17 at 19:06
  • @XaralabosNikolaidhs: for the good of future visitors to this site, please accept either of the other two answers, the ones that don't give recommendations that may mislead newbie future visitors to this site. – Hovercraft Full Of Eels Jun 01 '17 at 19:07
  • First, having static Progress bar is totally fine, this is in order to be able to start/stop it from anywhere in your code. There is always better way to design it, but is out of this question scope. Second, I said 'as a quick' fix to get going. The answer is exactly what question was asking. The issue was a tricky one and less obvious than the standard 'dont use static' answer. At least give some credit where it is due. Third, it is not always clear cut what is best practice for a given application, and giving an advice that seems like a common sense can actually lead to a wrong direction – tsolakp Jun 01 '17 at 20:06
  • Thanks, I saw that you did. My comment was addressed to @Hovercraft Full Of Eels. – tsolakp Jun 01 '17 at 21:33
  • i understand that "static" and whatsoever is a 'bad' way to fix things but i could not figure a other way with my current knowledge of things. Can any of you like, create it from the beginning with your own ways? i am curious and wanna see the right way – Xaralabos Nikolaidhs Jun 01 '17 at 21:33
  • I will try to add code to the answer sometimes soon. – tsolakp Jun 01 '17 at 21:52