2015-02-07 104 views
0

我正在制作一个应用程序来控制串行连接的打印机,我想提供一个静态工厂方法PrinterLocator.FindPrinters(),它将返回连接到我系统的可用打印机的阵列。创建一个静态工厂

作为示例,串行库提供了Serial.list()这是一个静态方法,返回与我的系统中可用端口相对应的字符串数组。我试图创建类似的东西,但我得到一个错误“没有可以访问类型SLPDriver的封闭实例,必须使用一个封闭的SLPDriver类型实例来限定分配”

实现此设计模式的正确方法是什么?

SLPDriver:

SerialPrinter myPrinter; 


void setup() 
{ 
    SerialPrinter[] availablePrinters = PrinterLocator.FindPrinters(); 
    if(availablePrinters.length > 0) 
    { 
    myPrinter = availablePrinters[0]; 
    } 
} 

void draw() 
{ 
} 

SerialPrinter:

import processing.serial.*; 

static class PrinterLocator 
{ 
    static final int baudRates[] = {2400, 4800, 9600, 19200, 38400, 57600, 115200}; 
    static final int baudCount = baudRates.length; 

    static SerialPrinter[] FindPrinters() 
    { 
    SerialPrinter[] foundPrinters, tempPrinters; 
    foundPrinters = new SerialPrinter[0]; 
    String[] foundPorts = Serial.list(); 
    int numPorts = foundPorts.length; 
    int numPrintersFound = 0; 
    if(numPorts <= 0) return foundPrinters; 

    SerialPrinter testPrinter; 

    tempPrinters = new SerialPrinter[numPorts]; 
    for(int i = 0; i < numPorts; i++) 
    { 
     for(int b = 0; b < baudCount; b++) 
     { 
     testPrinter = new SerialPrinter("test", foundPorts[i], baudRates[b]); 
     if(testPrinter.IsValid()) 
     { 
      tempPrinters[numPrintersFound] = testPrinter; 
      numPrintersFound++; 
      break; 
     } 
     } 
    } 

    if(numPrintersFound > 0) 
    { 
     foundPrinters = new SerialPrinter[numPrintersFound]; 
     for(int i = 0; i < numPrintersFound; i++) 
     { 
     foundPrinters[i] = tempPrinters[i]; 
     } 
    } 

    return foundPrinters; 
    } 

} 

class SerialPrinter 
{ 
    //Members 
    private Serial myPort; 
    private String printerName; 
    private boolean valid; 
    private String portName; 
    private int baudRate; 

    public SerialPrinter() 
    { 
    this("","",0); 
    } 

    public SerialPrinter(String name, String port, int baud) 
    { 
    printerName = name; 
    Configure(port, baud); 
    } 

    public boolean IsValid() 
    { 
    return valid; 
    } 

    public boolean Configure(String port, int baud) 
    { 
    print("Configuring Printer "); 
    print(port); 
    print("@"); 
    print(baud); 
    print(": "); 
    try 
    { 
     myPort.stop(); 
     myPort = null; 
    } 
    catch (Exception e) {} 

    portName = port; 
    baudRate = baud; 
    try 
    { 
     myPort = new Serial(this, port, baud); 
     myPort.clear(); 
     myPort.write(0xA5); 
     int timeout = millis() + 1000; 
     while((millis() < timeout) && (myPort.available() == 0)) { } 
     if(myPort.available() > 0) 
     { 
     int inByte = myPort.read(); 
     if(inByte == 0xC9) 
     { 
      valid = true; 
     } 
     else 
     { 
      valid = false; 
     } 
     } 
     else 
     { 
     valid = false; 
     } 
    } 
    catch (Exception e) 
    { 
     valid = false; 
    } 
    if(valid) 
    { 
     println("[OK]"); 
    } 
    else 
    { 
     println("[ERR]"); 
    } 
    return valid; 
    } 
} 
+0

哪条线是错误的? – immibis 2015-02-08 00:07:10

+0

'testPrinter = new SerialPrinter(“test”,foundPorts [i],baudRates [b]);'in SerialPrinter – Nechoha 2015-02-08 00:10:23

回答

0

型SLPDriver没有外围实例访问。必须SLPDriver

该错误指示SerialPrinter是一个内部类的SLPDriver类型的包封实例限定的分配。

您也需要到类声明更改为静态:

static class SerialPrinter 
{ 
    ... 

或者如果它应该是内在的,你需要使用一个SLPDriver实例来创建SerialPrinter

someSLPDriver.new SerialPrinter(...) 

http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html


Serial构造函数似乎需要PApplet的实例。实例化表达式应该也会给你一个错误,因为this指的是SerialPrinter,而不是PApplet

有些事情,你可以尝试是这样的:

... 

static class PrinterLocator { 
    ... 

    static SerialPrinter[] FindPrinters(SLPDriver context) { 
     ... 

     ... = context.new SerialPrinter(...); 
    } 
} 

class SerialPrinter { 
    ... 

    public boolean Configure(...) { 
     ... 

     ... = new Serial(PApplet.this, ...); 
    } 
} 

当你的小应用程序的范围内调用FindPrinters,你需要调用它像

... = PrinterLocator.FindPrinters(this); 
+0

Serial Library的API文档指出Serial的构造函数需要引用'this',它不存在于静态类的上下文。 https://processing.org/reference/libraries/serial/Serial.html此外,我不打算创建一个静态类,只是一个静态工厂方法。 – Nechoha 2015-02-08 01:32:21

+1

我编辑澄清。但是你需要做我建议的事情之一。你不能真的有你的蛋糕,也不能在这里吃。你还应该阅读我链接的教程。一个静态类就像一个顶级类。请注意,如果您在Processing中声明顶级类,则它实际上是内部的,因为“全局”上下文位于applet的实例中。 – Radiodef 2015-02-08 02:08:36