2

I keep getting the following error message java.lang.IllegalStateException: Buffers have not been created. This is the first time ever I came across this and don't know how to get rid of it safely. I researched this error message and the only solution I came accross was to use the following:

createBufferStrategy(2);

From my understaning, Java is double buffering by default and I should not need the line above. (By the way, I did not mess with the buffers at all prior to the error). Some say that this message may be shown if you are rendering something outside of the EDT.

The following is just a sample code I wrote to demonstrate what my application does. First of all, the application is written on the NetBeans Platform (RCP). BarcodeInput class receives the data that comes in via a Barcode Scanner connected to a serial port, than a worker BarcodeProcessWorker processes that data further. The way the code is shown below works great without giving me error messages, but if I use the SwingUtilities.invokeLater I get the error message. It does not make any sense to me as I thought that I sould be using the SwingUtilities.invokeLater from a background thread to updated the GUI as all updates should be performed on the EDT.

    public final class MainTopComponent extends TopComponent {//NetBeans TopComponent

        public MainTopComponent() {        
            initComponents();//The MainJPanel is created here
            ...
        }

    }

    public class MainJPanel extends javax.swing.JPanel{

        private SerialPortConnection spc;

        public MainJPanel() {
            initComponents();//Paints GUI components
            initSerialPortConnection();//Initialize the Serial Port (SerialPortConnection spc) for the Barcode Scanner
            initBarcode();
        }

        private void initBarcode(){
            BarcodeInput bsi = new BarcodeInput(bspc);
        }

    }

    public class BarcodeInput implements BarcodeSerialPortListener{

        private BarcodeSerialPortConnection bspc;
        private BarcodeJDialog barcodeJDialog;

        public BarcodeInput(BarcodeSerialPortConnection bspc) {
            this.bspc = bspc;
            barcodeJDialog = new barcodeJDialog();//This is just a regular JDialog with some labels displayed and among them is a label called labelBarcode
        }

        public void addToBarcodeSerialPortListenerList() {
            bspc.addToBarcodeSerialPortListenerList(this);
        }

        public boolean isBarcodeJDialogVisible(){
            return barcodeJDialog.isVisible();
        }

        public void showBarcodeJDialog(){
            barcodeJDialog.setVisible(true);
        }

        public void hideBarcodeJDialog(){
            barcodeJDialog.setVisible(false);
        }

        public void setTextOfLabelBarcode(String s){
            barcodeJDialog.setTextOfLabelBarcode(s);
        }

        @Override
        public void stringReveivedFromSerialPort(String serialPortString) {//Overrides the method in the interface BarcodeSerialPortListener
            BarcodeProcessWorker bpWorker = new BarcodeProcessWorker(this, serialPortString);
            bpWorker.execute();//This swing worker class processes the received serial port string
        }

    }


public class BarcodeProcessWorker extends SwingWorker<Void,Void>{

    private BarcodeInput bi;
    private String serialPortString;

    public BarcodeProcessWorker(BarcodeInput bi, String serialPortString){
        this.bi = bi;
        this.serialPortString = serialPortString;
    }

    @Override
    protected Void doInBackground() throws Exception{

        if("SHOW".contains(serialPortString)){

        //First I remove the SHOW from the serialPortString and whatever is left is the data:
        //For example if the barcode had SHOW12345, I end up with 12345 as data. SHOW is just a command
        //that tells my application to display the BarcodeJDialog, where HIDE tells it to hide the BarcodeJDialog.

            ShowBarcode sb = new ShowBarcode(bi, barcodeData);
            sb.show();

        }else if("HIDE".equals(serialPortString){

            bi.hideBarcodeJDialog();//WORKS LIKE THIS, DOES NOT WORK AS SHOWN BELOW

            //If I use the following here, I get that error message
            //  SwingUtilities.invokeLater(new Runnable(){
            //      @Override
            //      public void run(){
            //          bi.hideBarcodeJDialog();
            //      }
            //  });

        }

        return null;
    }

}

public class ShowBarcode {

    private BarcodeInput bi;
    private String barcodeData;

    public ShowBarcode(BarcodeInput bi, String barcodeData){
        this.bi = bi;
        this.barcodeData = barcodeData;
    }

    public void show(){

        bi.setTextOfLabelBarcode(barcodeData);//Set text as 12345
        bi.showBarcodeJDialog();//WORKS LIKE THIS, DOES NOT WORK AS SHOWN BELOW

        //If I use the following here, I get that error message
        //  SwingUtilities.invokeLater(new Runnable(){
        //      @Override
        //      public void run(){
        //      bi.setTextOfLabelBarcode(barcodeData);//Set text as 12345
        //      bi.showBarcodeJDialog();
        //      }
        //  });

    }

}
4

1 回答 1

2

我认为我应该使用SwingUtilities.invokeLater()后台线程来更新 GUI,因为所有更新都应该在 EDT 上执行。

不,doInBackground()通常会调用以下两种方法中的一种或两种,如下所示:

  • publish():发布的值应由process()在 EDT 上运行的 处理。

  • setProgress():新值在 EDT 上传达给任何已注册的PropertyChangeListener.

如果没有令人信服的理由来改变,我只会使用默认的JComponent缓冲策略。

于 2012-09-12T17:20:05.580 回答