0

I am using Eclipse Kepler and I have an app which instances two JFrame instnaces, and one of them is not visible at this point, as I will make it visible to the user in another method doing some checks. However, when I run it, nothing happens, but when I debug it, it gives this error when it executes mainWindow.setFrameListOfActivities():

InvocationEvent.dispatch() line: not available 'Source not Found'

Here is my code:

In the mainWindow, my frames are instanced, and then I instance updateActivitiesToRun:

package view;

import java.awt.EventQueue;

public class mainWindow extends JFrame {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private JPanel contentPane;
    private JFormattedTextField ftfAlertTime;
    private JFormattedTextField ftfScheduledTime;
    private JTextArea txtGsdDescription;
    private JFormattedTextField ftfGsdNumber;
    private static JFrame frameListOfActivities;


    public static JFrame getFrameListOfActivities() {
        return frameListOfActivities;
    }

    public static void setFrameListOfActivities() {
        frameListOfActivities.setVisible(true);
    }

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    mainWindow frame = new mainWindow();
                    frame.setVisible(true);
                    frame.setLocationRelativeTo(null);
                    frame.setResizable(false);

                    //My Second JFrame
                    listActivities frameListOfActivities = new listActivities();
                    frameListOfActivities.setVisible(false);


                    //Starts the scheduler, which checks if there are any activities 
                    ScheduledExecutorService updateActivitiesToRun = Executors.newScheduledThreadPool(1);
                    updateActivitiesToRun.scheduleAtFixedRate(scheduledTask.updateActivitiesToRun, 0, 2, TimeUnit.SECONDS);

                    //Update activities to cancel the notification after their scheduled time
                    //ScheduledExecutorService updatePastScheduledTimeActivities = Executors.newScheduledThreadPool(1);
                    //updatePastScheduledTimeActivities.scheduleAtFixedRate(scheduledTask.updatePastScheduledTimeActivities, 0, 10, TimeUnit.SECONDS);

                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }
            }
        });
    }

    /**
     * Create the frame.
     * @throws Exception 
     */
    public mainWindow() throws Exception {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setResizable(false);
        setBounds(100, 100, 450, 300);

        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        JLabel lblGsdNumber = new JLabel("GSD Number:");
        lblGsdNumber.setBounds(10, 11, 89, 14);
        contentPane.add(lblGsdNumber);

        JLabel lblDescription = new JLabel("Description:");
        lblDescription.setBounds(10, 36, 89, 14);
        contentPane.add(lblDescription);

        JLabel lblAlertTime = new JLabel("Alert time:");
        lblAlertTime.setBounds(10, 188, 71, 14);
        contentPane.add(lblAlertTime);

        JLabel lblScheduledTime = new JLabel("Scheduled Time:");
        lblScheduledTime.setBounds(220, 188, 115, 14);
        contentPane.add(lblScheduledTime);

        JButton btnCreateActivity = new JButton("Create Activity");
        btnCreateActivity.addActionListener(new ActionListener() {

            //Create Activity button event
            public void actionPerformed(ActionEvent e) {

                if (ftfGsdNumber.getText().equals("")) {
                    JOptionPane.showMessageDialog(null,"Please provide the number of the activity.");
                    ftfGsdNumber.requestFocus();                    

                } else {
                    int validation = Integer.parseInt(ftfScheduledTime.getText().replace(":", ""));

                    if (validation > 2359) {
                        JOptionPane.showMessageDialog(null,"Please provide a valid time schedule for the activity, between 00:00 and 23:59.");
                        ftfScheduledTime.requestFocus();

                    } else {

                        //Confirmation message
                        int result = JOptionPane.showConfirmDialog(null, 
                                   "Confirm details of the new activity?",null, JOptionPane.YES_NO_OPTION);

                        if (result == JOptionPane.YES_OPTION){

                            try{

                                DatabaseQueries.writeActivity(DatabaseQueries.databaseConnect(), ftfGsdNumber.getText(),
                                        txtGsdDescription.getText(), ftfAlertTime.getText(), ftfScheduledTime.getText());

                                //Success Message
                                JOptionPane.showMessageDialog(null,"Activity has been saved successfully");

                                //Clear the txt and formated boxes
                                cleanTextBoxes();

                            }
                            catch(Exception ex) {
                                JOptionPane.showMessageDialog(null, "Unable to insert new activity in database. Error: " + ex);
                            }
                        }
                    }
                }       
            }
        });
        btnCreateActivity.setBounds(148, 228, 133, 23);
        contentPane.add(btnCreateActivity);

        txtGsdDescription = new JTextArea();
        txtGsdDescription.setBounds(10, 61, 414, 116);
        txtGsdDescription.setLineWrap(true);
        contentPane.add(txtGsdDescription);

        ftfAlertTime = new JFormattedTextField();
        ftfAlertTime.setColumns(5);
        ftfAlertTime.setBounds(78, 185, 83, 20);
        contentPane.add(ftfAlertTime);
        createMask(ftfAlertTime);

        ftfScheduledTime = new JFormattedTextField();
        ftfScheduledTime.setColumns(5);
        ftfScheduledTime.setBounds(341, 185, 83, 20);
        contentPane.add(ftfScheduledTime);
        createMask(ftfScheduledTime);   

        ftfGsdNumber = new JFormattedTextField();
        ftfGsdNumber.setBounds(109, 8, 115, 20);
        contentPane.add(ftfGsdNumber);
        createMaskGsd(ftfGsdNumber);

    }

    //Creates the mask of the Scheduled Time and Alert Time
    public void createMask(JFormattedTextField fieldToBeFormated) throws Exception{
        MaskFormatter mask = new MaskFormatter("##:##");
        mask.install(fieldToBeFormated);
    }

    public void createMaskGsd(JFormattedTextField fieldToBeFormated) throws Exception{
        MaskFormatter mask = new MaskFormatter("IN##########");
        mask.install(fieldToBeFormated);
    }

    public void cleanTextBoxes(){
        txtGsdDescription.setText("");
        ftfAlertTime.setText("");
        ftfGsdNumber.setText("");
        ftfScheduledTime.setText("");
    }
}

Here is the code of listActivities JFrame:

package view;

import java.awt.event.ActionEvent;

public class listActivities extends JFrame {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private JPanel contentPane;
    private JTable table;

    /**
     * Launch the application.

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    listActivities frame = new listActivities();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    */

    /**
     * Create the frame.
     */
    public listActivities() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 318);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        JButton btnAcknowledge = new JButton("Acknowledge");
        btnAcknowledge.addActionListener(new ActionListener() {

            //Acknowledge button event
            public void actionPerformed(ActionEvent arg0) {



            }
        });
        btnAcknowledge.setBounds(154, 246, 131, 23);
        contentPane.add(btnAcknowledge);

        table = new JTable();
        table.setModel(new DefaultTableModel(
            new Object[][] {
            },
            new String[] {
                "GSD Number", "Scheduled Time"
            }
        ) {
            /**
             * 
             */
            private static final long serialVersionUID = 1L;
            boolean[] columnEditables = new boolean[] {
                false, true
            };
            public boolean isCellEditable(int row, int column) {
                return columnEditables[column];
            }
        });
        table.getColumnModel().getColumn(0).setPreferredWidth(114);
        table.getColumnModel().getColumn(1).setPreferredWidth(139);
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        table.setBounds(10, 11, 414, 96);
        contentPane.add(table);

        JLabel lblDescription = new JLabel("Description:");
        lblDescription.setBounds(10, 118, 86, 14);
        contentPane.add(lblDescription);

        JTextArea textArea = new JTextArea();
        textArea.setBounds(10, 143, 414, 92);
        textArea.setLineWrap(true);

        contentPane.add(textArea);
    }
}

And this is the code of scheduledTask class, which errors when trying to set the Frame to visible:

package rules;

import java.sql.ResultSet;
import java.sql.SQLException;

import persistence.DatabaseQueries;
import view.mainWindow;

public class scheduledTask {

    private static ResultSet resultSetVar;


    public static Runnable updateActivitiesToRun = new Runnable() {
        public void run() {         

            System.out.println("first message");
            mainWindow.setFrameListOfActivities();

            DatabaseQueries.updateActivitiesToStartNotification(DatabaseQueries.databaseConnect());
        }
    };  
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 1) See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/q/9554636/418556) 2) Please use code formatting for code and code snippets, structured documents like HTML/XML or input/output. To do that, select the text and click the `{}` button at the top of the message posting/editing form. – Andrew Thompson Oct 09 '14 at 00:49
  • `contentPane.setLayout(null);` Java GUIs have to work on different OS', screen size, screen resolution etc. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). – Andrew Thompson Oct 09 '14 at 00:53
  • Try cleaning and rebuilding the program – MadProgrammer Oct 09 '14 at 00:58
  • You might like to have a read through [Code Conventions for the Java TM Programming Language](http://www.oracle.com/technetwork/java/codeconvtoc-136057.html), it will make it easier for people to read your code and for you to read others – MadProgrammer Oct 09 '14 at 00:58
  • `static` is not your friend, you will end up with reference issues if your are not very, very careful... – MadProgrammer Oct 09 '14 at 01:00

1 Answers1

2

frameListOfActivities in the setFrameListOfActivities method is null when it is called...

This occurs because you've redeclared it within the main method...

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                //...
                //My Second JFrame
                listActivities frameListOfActivities = new listActivities();
                // ^--- Redeclared as a local variable...
                frameListOfActivities.setVisible(false);

Beware of over reliance of static, this is pretty good indicator that your design is wrong and needs work. The instance of frameListOfActivities should be passed to the the instance of Runnable which is scheduled with the ScheduledExecutorService. I'd also be concerned about making this window visible EVERY 2 SECONDS...seems like you don't like your users...

In fact, I'm wondering if a SwingWorker would be a better solution...remember, Swing is not thread safe, you should never create or modify the state of the UI from outside the Event Dispatching Thread

Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify. See Why is it frowned upon to use a null layout in SWING? for more details

Also beware of the use of multiple frames, which can make it difficult for the user to manage (I have enough open windows) and which can also confuse the user. Have a look at The Use of Multiple JFrames, Good/Bad Practice? for more details

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366