Как обновить текстовое поле, созданное с помощью графического дизайнера GUI NetBeans в Java - PullRequest
1 голос
/ 08 апреля 2020

Я уже десятилетиями пишу встроенный код C и хочу обновить свой набор навыков, изучив Java.

У меня также есть потребность в графическом инструменте для тестирования проекта (чтение последовательного порта, данных процесса, запись результата в последовательный порт на основе выбора кнопок GUI и т. Д. c)

Я пытаюсь использовать графический дизайнер GUI NetBeans для создания GUI, а затем добавить Java код для реализации логики c, но я все еще изучаю Java, поэтому я не уверен, как получить доступ к текстовому полю в моем GUI из кода Java. В частности, я хочу, чтобы текстовое поле на экране обновлялось каждую секунду в соответствии с текущим временем (это в конечном итоге станет маршрутизацией проверки работоспособности при поиске пропущенных командных таймаутов и т. Д. c).

Проблема, с которой я столкнулся, заключается в том, что как получить доступ к объекту текстового поля timeDisplayField из моей подпрограммы healthCheck (). Процедура healthCheck () вызывается каждую секунду, но когда я раскомментирую любую попытку добраться до объекта timeDisplayField, я получаю либо ошибку компиляции, либо ошибку времени выполнения NullPointer.

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package myPackage;

import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Date;

/**
 *
 * @author SGrunza
 */


public class mainWindow extends javax.swing.JFrame {

    /**
     * Creates new form mainWindow
     */



        public void healthCheck()
{
    Calendar    now = Calendar.getInstance();
    int         hour = now.get( Calendar.HOUR_OF_DAY );
    int         minute = now.get( Calendar.MINUTE );
    int         second = now.get( Calendar.SECOND );

    String      timeString = new String();

    //System.out.printf("%02d:%02d:%02d\r\n", hour, minute, second );

    timeString = timeString.format( "%02d:%02d:%02d\r\n", hour, minute, second );
    timeDisplayField.setText( timeString );
}

    public mainWindow() 
    {
        Timer       healthTimer = new Timer();

        healthTimer.scheduleAtFixedRate( new TimerTask()
                {
                    @Override 
                    public void run()
                {
                    //System.out.println( "healthTask " + new Date() +
                    //        "Thread name: " + Thread.currentThread().getName() );
                    healthCheck();
                }
                },
                0,  // delay until first run
                1000 ); // delay for each subsequent run


        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">//GEN-BEGIN:initComponents
    private void initComponents() {

        interfaceTypeGroup = new javax.swing.ButtonGroup();
        jPanel1 = new javax.swing.JPanel();
        nfcButton = new javax.swing.JRadioButton();
        smipButton = new javax.swing.JRadioButton();
        serialButton = new javax.swing.JRadioButton();
        appStatusField = new javax.swing.JTextField();
        msgField = new javax.swing.JTextField();
        cardReaderStatusField = new javax.swing.JTextField();
        timeDisplayField = new javax.swing.JTextField();
        activateButton = new javax.swing.JButton();
        readButton = new javax.swing.JButton();
        deactivateButton = new javax.swing.JButton();
        checkSleepButton = new javax.swing.JButton();
        getInfoButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        interfaceTypeGroup.add(nfcButton);
        nfcButton.setSelected(true);
        nfcButton.setText("NFC");

        interfaceTypeGroup.add(smipButton);
        smipButton.setForeground(new java.awt.Color(153, 153, 153));
        smipButton.setText("SMIP");

        interfaceTypeGroup.add(serialButton);
        serialButton.setForeground(new java.awt.Color(153, 153, 153));
        serialButton.setText("Serial");

        appStatusField.setText("appStatus");

        msgField.setText("msgWindow");

        cardReaderStatusField.setText("cardReader_status");

        timeDisplayField.setText("timeDisplay");

        activateButton.setLabel("Activate");

        readButton.setText("Read Sensor");

        deactivateButton.setText("Deactivate");

        checkSleepButton.setText("Check Sleep");

        getInfoButton.setText("Get Info");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(msgField)
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                        .addComponent(activateButton, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(deactivateButton, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(readButton, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(getInfoButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addContainerGap())
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(checkSleepButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGap(12, 12, 12))))
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(12, 12, 12)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(nfcButton)
                            .addComponent(smipButton)
                            .addComponent(serialButton))
                        .addGap(18, 18, 18)
                        .addComponent(cardReaderStatusField))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(12, 12, 12)
                        .addComponent(appStatusField, javax.swing.GroupLayout.PREFERRED_SIZE, 203, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 564, Short.MAX_VALUE)
                        .addComponent(timeDisplayField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(12, 12, 12))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(nfcButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(smipButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(serialButton))
                    .addComponent(cardReaderStatusField))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(timeDisplayField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(appStatusField, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(activateButton)
                    .addComponent(getInfoButton))
                .addGap(18, 18, 18)
                .addComponent(readButton)
                .addGap(18, 18, 18)
                .addComponent(deactivateButton)
                .addGap(37, 37, 37)
                .addComponent(checkSleepButton)
                .addGap(18, 18, 18)
                .addComponent(msgField, javax.swing.GroupLayout.DEFAULT_SIZE, 217, Short.MAX_VALUE)
                .addContainerGap())
        );

        timeDisplayField.getAccessibleContext().setAccessibleName("timeDisplayField");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(mainWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(mainWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(mainWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(mainWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new mainWindow().setVisible(true);
            }
        });
    }


    // Variables declaration - do not modify//GEN-BEGIN:variables
    public javax.swing.JButton activateButton;
    public javax.swing.JTextField appStatusField;
    public javax.swing.JTextField cardReaderStatusField;
    public javax.swing.JButton checkSleepButton;
    public javax.swing.JButton deactivateButton;
    public javax.swing.JButton getInfoButton;
    public javax.swing.ButtonGroup interfaceTypeGroup;
    public javax.swing.JPanel jPanel1;
    public javax.swing.JTextField msgField;
    public javax.swing.JRadioButton nfcButton;
    public javax.swing.JButton readButton;
    public javax.swing.JRadioButton serialButton;
    public javax.swing.JRadioButton smipButton;
    public javax.swing.JTextField timeDisplayField;
    // End of variables declaration//GEN-END:variables
}

Я достаточно нов, чтобы Java что я не уверен, где искать помощь. Я подозреваю, что часть проблемы заключается в использовании сборщика NetBeans GUI, но я действительно не хочу собирать все GUI вручную.

Чтобы свести это к простому вопросу: как мне изменить healthCheck (), чтобы он обновлял текстовое поле на экране?

1 Ответ

1 голос
/ 08 апреля 2020

Ответ в Что такое исключение NullPointerException и как мне это исправить. Вы можете увидеть это в трассировке стека (ошибка):

Exception in thread "Timer-0" java.lang.NullPointerException
    at rae.mainWindow.healthCheck(mainWindow.java:24)
    at rae.mainWindow$1.run(mainWindow.java:35)
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)

В строке 24 у вас есть эта строка:

timeDisplayField.setText(timeString);

timeString не является null, что означает timeDisplayField является null. Это потому, что вы сначала запускаете таймер и после того, как вы вызываете метод initComponents, который создает текстовое поле:

public mainWindow() {
    Timer healthTimer = new Timer();

    healthTimer.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            // System.out.println( "healthTask " + new Date() +
            // "Thread name: " + Thread.currentThread().getName() );
            healthCheck();
        }
    }, 0, // delay until first run
            1000); // delay for each subsequent run

    initComponents(); //here
}

Вы можете исправить это, вызвав initComponents до начала времени:

public mainWindow() {
    Timer healthTimer = new Timer();

    initComponents(); //Before timer

    healthTimer.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            // System.out.println( "healthTask " + new Date() +
            // "Thread name: " + Thread.currentThread().getName() );
            healthCheck();
        }
    }, 0, // delay until first run
            1000); // delay for each subsequent run

}

Однако использование java.util.Timer не рекомендуется в среде Swing. Попробуйте заменить его на Swing Timer , который создан для таких случаев. Хороший пример его использования можно найти в этом посте.

...