2015-02-07 101 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