JFrame,错误无法对非静态字段进行静态引用
JFrame, Error Cannot make a static reference of the non-static field
我正在尝试通过 SerialRead 方法设置数据变量,但我得到了 "Cannot make a static reference of the non-static field 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 标签上的文本以显示数据变量?
谢谢
EDIT3:我用swingworker更新了代码,执行和println在控制台看数据
SerialReader
是 Final
的静态内部 class,因此无法访问 Final
中的任何非静态字段。由于您显然不在 Final
之外使用 SerialReader
,只需将其设为非静态即可(甚至可以是私有内部 class)。同样适用于 SerialWriter
.
SerialReader
声明为 static
,因此它无法访问外部 Final
class 的实例字段,因为可以创建 SerialReader
不需要先 Final
的实例。
相反,您应该将要更新的 JLabel
的引用传递给 SerialReader
class
public static class SerialReader implements Runnable
{ //Final frame = new Final();
InputStream in;
private JLabel label;
public SerialReader ( InputStream in, JLabel label ) {
this.label = label;
//...
然后您将使用它从您的 运行 方法中进行更新。
您可以简单地使 class 成为非静态的,但这取决于您的需要
您遇到的另一个问题是 Swing 不是线程安全的,因此实际上不建议从 run
方法中对 JLabel
的实例调用 setText
。
通常,我建议使用 SwingWorker
,因为它具有允许您从后台线程 publish
结果和事件上下文中 process
结果的方法调度线程,允许您安全地修改 UI 的状态,但在这种情况下,您可以使用 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
,这可能会导致更多问题,在这种情况下,我会改用 SwingWorker
。
仔细查看 Worker Threads and SwingWorker 了解更多详情
SwingWorker
示例...
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
示例...
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);
}
}
}
}
"Faked" InputStream
示例...
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
import javax.swing.WindowConstants;
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("Banana");
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 {
System.out.println("...");
new SerialReader(new FakeInputStream(), Etiqueta2).execute();
// 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> {
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;
}
@Override
protected void done() {
try {
get();
} catch (InterruptedException | ExecutionException ex) {
ex.printStackTrace();
}
}
}
public static void main(String[] args) {
try {
(new Final()).connect("COM7");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static class FakeInputStream extends InputStream {
private Random rnd = new Random();
@Override
public int read() throws IOException {
return 33 + rnd.nextInt(125-33); // Ascii characters
}
}
}
我正在尝试通过 SerialRead 方法设置数据变量,但我得到了 "Cannot make a static reference of the non-static field 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 标签上的文本以显示数据变量?
谢谢
EDIT3:我用swingworker更新了代码,执行和println在控制台看数据
SerialReader
是 Final
的静态内部 class,因此无法访问 Final
中的任何非静态字段。由于您显然不在 Final
之外使用 SerialReader
,只需将其设为非静态即可(甚至可以是私有内部 class)。同样适用于 SerialWriter
.
SerialReader
声明为 static
,因此它无法访问外部 Final
class 的实例字段,因为可以创建 SerialReader
不需要先 Final
的实例。
相反,您应该将要更新的 JLabel
的引用传递给 SerialReader
class
public static class SerialReader implements Runnable
{ //Final frame = new Final();
InputStream in;
private JLabel label;
public SerialReader ( InputStream in, JLabel label ) {
this.label = label;
//...
然后您将使用它从您的 运行 方法中进行更新。
您可以简单地使 class 成为非静态的,但这取决于您的需要
您遇到的另一个问题是 Swing 不是线程安全的,因此实际上不建议从 run
方法中对 JLabel
的实例调用 setText
。
通常,我建议使用 SwingWorker
,因为它具有允许您从后台线程 publish
结果和事件上下文中 process
结果的方法调度线程,允许您安全地修改 UI 的状态,但在这种情况下,您可以使用 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
,这可能会导致更多问题,在这种情况下,我会改用 SwingWorker
。
仔细查看 Worker Threads and SwingWorker 了解更多详情
SwingWorker
示例...
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
示例...
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);
}
}
}
}
"Faked" InputStream
示例...
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
import javax.swing.WindowConstants;
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("Banana");
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 {
System.out.println("...");
new SerialReader(new FakeInputStream(), Etiqueta2).execute();
// 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> {
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;
}
@Override
protected void done() {
try {
get();
} catch (InterruptedException | ExecutionException ex) {
ex.printStackTrace();
}
}
}
public static void main(String[] args) {
try {
(new Final()).connect("COM7");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static class FakeInputStream extends InputStream {
private Random rnd = new Random();
@Override
public int read() throws IOException {
return 33 + rnd.nextInt(125-33); // Ascii characters
}
}
}