Java Swing - How to call a non-static method from GUI class

tsume

The Pervy Sage
Joined
Apr 19, 2010
Messages
21,130
Reaction score
373
Location
In the vasts of the internet
Hi everyone.
So I'm using Netbeans to code with it's java application to create a GUI, the GUI/application class being PlayerView.
I created a separate thread which sends & recieves messages on a network using UDP sockets. All's working well but when I recieve certain message, and I want to change stuff on the GUI (like make a button visible) I find myself facing problems.

What I've gotten is that all the objects in the PlayerView class are non-static, so I created a method in the PlayerView class:
Code:
public void goGame(){
           ....code....}

Then because the method is non-static, from another class I called like this:
Code:
public void jump(){
        PlayerView a = new PlayerView(); //<-This I'm sure is incorrect
        a.goGame();
    }

Now PlayerView takes in SingleFrameApplication as a variable, which truelly got me lost.
I could just make goGame static but then I will come across the problem of referencing non-static to static objects & I think I'll be stuck again on trying to solve it the same way I did in the jump() method.

Can anyone help?
 
Last edited:
I'm no expert, but...

It seems like you've designed your objects wrong. You shouldn't need to call non-static methods without an instance of an object from a static context.

Probably not the answer you were looking for, but without more substantial code (so that we can see what methods are where), it's difficult to advise.
 
You shouldn't need to call non-static methods without an instance of an object from a static context.
I'm no expert either, telling by how you lost me with that explanation.

I'll try put up as much as I can
PlayerView:
Code:
package player;


import java.awt.Cursor;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JFrame;

import java.io.*;
import java.net.*;
import java.sql.PreparedStatement;
import java.util.*;
import javax.swing.JButton;
import javax.swing.JTable;
import javax.swing.JTextArea;

/**
 * The application's main frame.
 */
public class PlayerView extends FrameView {
    public static Vector<robots> playerList = new Vector<robots>();


    public void setPlayerList(Vector<robots> pList) {
        playerList = pList;
    }

    public Vector<robots> getPlayerList() {
        return playerList;
    }

    int refereePort;
    String refereeIP;
    public static String playerName;
    public static boolean gameStart = false;

    public PlayerView(SingleFrameApplication app) {
        super(app);

        initComponents();

        // status bar initialization - message timeout, idle icon and busy animation, etc
        ResourceMap resourceMap = getResourceMap();
        int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
        messageTimer = new Timer(messageTimeout, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                statusMessageLabel.setText("");
            }
        });
        messageTimer.setRepeats(false);
        int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
        for (int i = 0; i < busyIcons.length; i++) {
            busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
        }
        busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
                statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
            }
        });
        idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
        statusAnimationLabel.setIcon(idleIcon);
        progressBar.setVisible(false);

        // connecting action tasks to status bar via TaskMonitor
        TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
        taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                String propertyName = evt.getPropertyName();
                if ("started".equals(propertyName)) {
                    if (!busyIconTimer.isRunning()) {
                        statusAnimationLabel.setIcon(busyIcons[0]);
                        busyIconIndex = 0;
                        busyIconTimer.start();
                    }
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(true);
                } else if ("done".equals(propertyName)) {
                    busyIconTimer.stop();
                    statusAnimationLabel.setIcon(idleIcon);
                    progressBar.setVisible(false);
                    progressBar.setValue(0);
                } else if ("message".equals(propertyName)) {
                    String text = (String)(evt.getNewValue());
                    statusMessageLabel.setText((text == null) ? "" : text);
                    messageTimer.restart();
                } else if ("progress".equals(propertyName)) {
                    int value = (Integer)(evt.getNewValue());
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(false);
                    progressBar.setValue(value);
                }
            }
        });
    }

    @Action
    public void showAboutBox() {
        if (aboutBox == null) {
            JFrame mainFrame = PlayerApp.getApplication().getMainFrame();
            aboutBox = new PlayerAboutBox(mainFrame);
            aboutBox.setLocationRelativeTo(mainFrame);
        }
        PlayerApp.getApplication().show(aboutBox);
    }

  private void buttonRegisterActionPerformed(java.awt.event.ActionEvent evt) {                                               
        refereeIP = ipField.getText();
        refereePort = Integer.parseInt(portField.getText());
        playerName = nameField.getText();
        textArea.append("Registering" + "\n" );
        textArea.setCaretPosition(textArea.getDocument().getLength());


        Cursor hourglass = new Cursor(Cursor.WAIT_CURSOR);
        mainPanel.setCursor(hourglass);
        buttonRegister.setEnabled(false);
        //Register
        boolean registerDone = true;
        try {
            register.sendRegister(refereeIP, refereePort, playerName);
        } catch (Exception ex) {
            //registerDone = false;
            String error = "Error: Registering failed, check IP address and port are correct";
            textArea.append(error + "\n" );
            textArea.setCaretPosition(textArea.getDocument().getLength());
            buttonRegister.setEnabled(true);
        }

        Cursor normalCursor = new Cursor(Cursor.DEFAULT_CURSOR);
        mainPanel.setCursor(normalCursor);
        

        if (registerDone){
            buttonRegister.setVisible(false);

            //Player Table Test
            //playerTable.setValueAt("In", 1, 0);
            //playerTable.setValueAt("Twice", 0, 0);
            
            //Remove button & labels
            //Start new thread for sending broadcast
            //Start new thread to listen to broadcast

            //Start progress bar
            jProgressBar.setIndeterminate(true);
            BroadcastListen();
            
        }
    }                                              

    private void jProgressBarStateChanged(javax.swing.event.ChangeEvent evt) {
        // TODO add your handling code here:
    }

    public void BroadcastListen(){
        JTextArea jTA = textArea;
        broadcast broadcastStart = new broadcast(jTA);
        Thread bcThread = new Thread(broadcastStart);
        bcThread.start();

        JTable jT = playerTable;
        discover listenStart = new discover(textArea, playerTable);
        Thread lThread = new Thread(listenStart);
        lThread.start();
    }

    public void goGame(){
              System.out.println("It's working");
    }



    // Variables declaration - do not modify
    private javax.swing.JButton buttonRegister;
    private javax.swing.JTextField ipField;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JProgressBar jProgressBar;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JTextField nameField;
    private javax.swing.JTable playerTable;
    private javax.swing.JTextField portField;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JLabel statusAnimationLabel;
    private javax.swing.JLabel statusMessageLabel;
    private javax.swing.JPanel statusPanel;
    private javax.swing.JTextArea textArea;
    // End of variables declaration

    private final Timer messageTimer;
    private final Timer busyIconTimer;
    private final Icon idleIcon;
    private final Icon[] busyIcons = new Icon[15];
    private int busyIconIndex = 0;

    private JDialog aboutBox;
}

I decided to test if I can call the goGame method first before coding and this where I got stuck:

Code:
public class test2 {
    public void jump(){
        PlayerView a = new PlayerView(); // <-Error occurs here
        a.goGame();
    }

}
 
Last edited:
Without analysing too closely, that should work? If not, where is jump() being called from?

On an unrelated note,

1) Please use JUnit for test cases.
2) System.out.println() is just wrong. There are plenty of great free logging packages out there. (log4j, etc)
 
There needs to be a static context which exists in order to create an instance of PlayerView. Netbeans would have created a file similar to
Code:
package desktopapplication2;

import org.jdesktop.application.Application;
import org.jdesktop.application.SingleFrameApplication;

/**
 * The main class of the application.
 */
public class DesktopApplication2 extends SingleFrameApplication {

    /**
     * At startup create and show the main frame of the application.
     */
    @Override protected void startup() {
        show(new DesktopApplication2View(this));
    }

    /**
     * This method is to initialize the specified window by injecting resources.
     * Windows shown in our application come fully initialized from the GUI
     * builder, so this additional configuration is not needed.
     */
    @Override protected void configureWindow(java.awt.Window root) {
    }

    /**
     * A convenient static getter for the application instance.
     * @return the instance of DesktopApplication2
     */
    public static DesktopApplication2 getApplication() {
        return Application.getInstance(DesktopApplication2.class);
    }

    /**
     * Main method launching the application.
     */
    public static void main(String[] args) {
        launch(DesktopApplication2.class, args);
    }
}
in order to run the actual code. You should get your clues from there where you are going wrong
 
The purpose of the jump() method was try and see if I can call goGame() method without getting any errors, since Netbeans does error checks on code as it's type out, I just edited to show where the error is occuring.

I will try sleep over this.
 
My best suggestion to hook Swing GUI's with non GUI classes is to have a look at the SwingWorker class, available since JDK 1.6

http://en.wikipedia.org/wiki/SwingWorker

This remains, in my view, one of the safest ways to update any GUI changes, ensuring that the EDT remains clean.
 
Hey guys, thanks for the input...after sleeping over it & consulting some friends, decided for the next phase of the game I will open up another form and make the current one invisible.
May seem cheap but it's what I have decided to keeping moving forward.

Again thanks.
 
Top
Sign up to the MyBroadband newsletter
X