JFrame,Error无法生成非静态字段的静态引用

时间:2015-04-21 02:35:12

标签: java eclipse swing compiler-errors jframe

我正在尝试从SerialRead方法设置数据变量,但我得到了#34;无法对非静态字段Etiqueta2进行静态引用",Eclipse说我应该使Etiqueta2静态但它不会显示Jlabel中的数据。

public class Final extends JFrame
{

    //Crea Elementos de la interfaz
    JLabel Etiqueta=new JLabel();
    JTextField Texto=new JTextField();
    JButton Boton=new JButton();
    JLabel Etiqueta1=new JLabel();
    JLabel Etiqueta2=new JLabel();
    JButton Boton1=new JButton();




    public Final()
    {
        super();
        // Crea la interfaz

        setVisible(true);
        setLayout(null);
        setTitle("Lectura y escritura de datos");
        setSize(380,200);
        //Propiedades de los elementos del Frame
        // Etiqueta
        Etiqueta.setBounds(20,50, 100, 20);
        Etiqueta.setText("Enviar un digito");
        add(Etiqueta);
        // Caja de texto
        Texto.setBounds(120,50,100, 20);
        add(Texto);
        // Boton
        Boton.setBounds(250,50,100, 20);
        Boton.setText("Enviar");
        add(Boton);
        // Etiqueta 1
        Etiqueta1.setBounds(20,80, 100, 20);
        Etiqueta1.setText("Leer un digito");
        add(Etiqueta1);
        // Etiqueta2
        Etiqueta2.setBounds(120,80,100, 20);
        add(Etiqueta2);
        // Boton 1
        Boton1.setBounds(250,80,100, 20);
        Boton1.setText("Leer");
        add(Boton1);
        // Boton de cierre   
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    }

    void connect ( String portName ) throws Exception
    {
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
        if ( portIdentifier.isCurrentlyOwned() )
        {
            System.out.println("Error: Port is currently in use");
        }
        else
        {
            CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);

            if ( commPort instanceof SerialPort )
            {
                SerialPort serialPort = (SerialPort) commPort;
                serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);

                InputStream in = serialPort.getInputStream();
                OutputStream out = serialPort.getOutputStream();

                new SerialReader(in, Etiqueta2).execute();
                (new Thread(new SerialWriter(out))).start();

            }
            else
            {
                System.out.println("Error: Only serial ports are handled by this example.");
            }
        }     
    }

    /** */
public static class SerialReader extends SwingWorker<Void, String> {   //Final frame = new Final();

    private InputStream in;
    private JLabel label;

    public SerialReader(InputStream in, JLabel label) {
        this.in = in;
        this.label = label;
    }

    @Override
    protected void process(List<String> chunks) {
        String data = chunks.get(chunks.size() - 1);
        label.setText(data);
    }

    @Override
    protected Void doInBackground() throws Exception {
        byte[] buffer = new byte[1024];
        int len = -1;
        while ((len = this.in.read(buffer)) > -1) {
            String data = new String(buffer, 0, len);
            System.out.println(data);
            publish(data);
        }
        return null;
    }
}

    /** */
    public static class SerialWriter implements Runnable 
    {
          **** output code ****
    }

    public static void main ( String[] args )
    {

        try
        {
            (new Final()).connect("COM7");
        }
        catch ( Exception e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

如何在Etiqueta2标签上设置setText以显示数据变量?

由于

EDIT3:我使用swingworker更新了代码,执行并打印了控制台中的数据

2 个答案:

答案 0 :(得分:2)

SerialReaderFinal的静态内部类,因此无法访问Final中的任何非静态字段。由于您显然不在SerialReader之外使用Final,只需将其设为非静态(甚至可以是私有内部类)。同样适用于SerialWriter

答案 1 :(得分:1)

SerialReader被声明为static,因此它无法访问外部Final类的实例字段,因为它可以创建{{1}的实例首先不需要SerialReader的实例。

相反,您应该将要更新的Final的引用传递给JLabel

SerialReader

然后你可以在你的run方法中使用它进行更新。

你可以简单地让这个课程非静态,但这取决于你的需要

你遇到的另一个问题是Swing不是线程安全的,所以从public static class SerialReader implements Runnable { //Final frame = new Final(); InputStream in; private JLabel label; public SerialReader ( InputStream in, JLabel label ) { this.label = label; //... 方法中调用setText实例上的JLabel实际上是不可取的。< / p>

通常情况下,我建议使用run,因为它有一些方法可以让您在后台线程中获得SwingWorker个结果,并在事件的上下文中使用publish个结果调度线程,允许您安全地修改UI的状态,但在这种情况下,您可以使用process

SwingUtilities.invokeLater

但您可能需要 public void run () { //... try { while ( ( len = this.in.read(buffer)) > -1 ) { //... SwingUtiltiies.invokeLater(new Runnable() { public void run() { Etiqueta2.setText(data); } }); } } catch ( IOException e ) { e.printStackTrace(); } } data,这可能会导致更多问题,在这种情况下,我只需使用final

仔细查看Worker Threads and SwingWorker了解更多详情

SwingWorker示例......

SwingWorker

Runnable public static class SerialReader extends SwingWorker<Void, String> { //Final frame = new Final(); private InputStream in; private JLabel label; public SerialReader(InputStream in, JLabel label) { this.in = in; this.label = label; } @Override protected void process(List<String> chunks) { String data = chunks.get(chunks.size() - 1); label.setText(data); } @Override protected Void doInBackground() throws Exception { byte[] buffer = new byte[1024]; int len = -1; while ((len = this.in.read(buffer)) > -1) { String data = new String(buffer, 0, len); publish(data); } return null; } } 示例......

SwingWorker

&#34;伪造的&#34; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.GridBagLayout; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.SwingWorker; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class Test { public static void main(String[] args) { new Test(); } public Test() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private JLabel label; public TestPane() { setLayout(new GridBagLayout()); label = new JLabel("..."); add(label); new ClockWorker(label).execute(); } @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } } public static class ClockWorker extends SwingWorker<Void, String> { protected static final DateFormat DF = new SimpleDateFormat("hh:mm.ss SSS a"); private JLabel label; public ClockWorker(JLabel label) { this.label = label; } @Override protected void process(List<String> chunks) { label.setText(chunks.get(chunks.size() - 1)); } @Override protected Void doInBackground() throws Exception { while (true) { publish(DF.format(new Date())); Thread.sleep(1); } } } } 示例......

InputStream