有没有一种好的方法在Swing应用程序中保留打印机设置?

13

我们正在使用新的Java打印API,它使用PrinterJob.printDialog(attributes)来显示对话框。

为了保存用户的设置以便下一次使用,我想做这个:

PrintRequestAttributeSet attributes = loadAttributesFromPreferences();
if (printJob.printDialog(attributes)) {
    // print, and then...

    saveAttributesToPreferences(attributes);
}
然而,我通过这样做发现有时候属性会得到一些错误的数据,然后当你打印时,你会得到一个空白页面。接着,代码会将被损坏的设置保存到首选项中,所有后续的打印操作都会使用损坏的设置。此外,为了让新运行的设置与用户选择的上一次运行的设置相同,整个任务的目的也没有实现,因为新的对话框似乎没有使用旧的设置。
所以,我想知道是否有一种正确的方法来做这件事情。毕竟,Sun 没有打算让用户每次启动应用程序时都要选择打印机、页面大小、方向和边距设置。

编辑以显示存储方法的实现:

private PrintRequestAttributeSet loadAttributesFromPreferences()
{
    PrintRequestAttributeSet attributes = null;

    byte[] marshaledAttributes = preferences.getByteArray(PRINT_REQUEST_ATTRIBUTES_KEY, null);
    if (marshaledAttributes != null)
    {
        try
        {
            @SuppressWarnings({"IOResourceOpenedButNotSafelyClosed"})
            ObjectInput objectInput = new ObjectInputStream(new ByteArrayInputStream(marshaledAttributes));

            attributes = (PrintRequestAttributeSet) objectInput.readObject();
        }
        catch (IOException e)
        {
            // Can occur due to invalid object data e.g. InvalidClassException, StreamCorruptedException
            Logger.getLogger(getClass()).warn("Error trying to read print attributes from preferences", e);
        }
        catch (ClassNotFoundException e)
        {
            Logger.getLogger(getClass()).warn("Class not found trying to read print attributes from preferences", e);
        }
    }

    if (attributes == null)
    {
        attributes = new HashPrintRequestAttributeSet();
    }

    return attributes;
}

private void saveAttributesToPreferences(PrintRequestAttributeSet attributes)
{
    ByteArrayOutputStream storage = new ByteArrayOutputStream();
    try
    {
        ObjectOutput objectOutput = new ObjectOutputStream(storage);
        try
        {
            objectOutput.writeObject(attributes);
        }
        finally
        {
            objectOutput.close(); // side-effect of flushing the underlying stream
        }
    }
    catch (IOException e)
    {
        throw new IllegalStateException("I/O error writing to a stream going to a byte array", e);
    }

    preferences.putByteArray(PRINT_REQUEST_ATTRIBUTES_KEY, storage.toByteArray());
}

编辑:好的,看起来它没有记住打印机的原因是它根本没有在PrintRequestAttributeSet中。确实,边距和页面大小被记住了,至少在设置被随机毒害之前是这样的。但是用户选择的打印机不在这里:

[0] = {java.util.HashMap$Entry@9494} class javax.print.attribute.standard.Media -> na-letter
[1] = {java.util.HashMap$Entry@9501} class javax.print.attribute.standard.Copies -> 1
[2] = {java.util.HashMap$Entry@9510} class javax.print.attribute.standard.MediaPrintableArea -> (10.0,10.0)->(195.9,259.4)mm
[3] = {java.util.HashMap$Entry@9519} class javax.print.attribute.standard.OrientationRequested -> portrait

你已经验证了 saveAttributesToPreferences() 的正确操作吗? - trashgod
定义“正确”。它将其序列化为字节数组并将其存储到首选项中,但是否正确取决于这个问题的答案。 - Hakanai
1个回答

1

看起来你需要的是PrintServiceAttributeSet,而不是PrintRequestAttributeSet

请查看PrintServiceAttribute接口,看看你需要的元素是否已经被实现为类。如果没有,你可以自己实现PrintServiceAttribute类(们)。


是的...就是那个。除了需要小心地删除一些最终出现在属性集中的东西之外,它在序列化两个集合时都可以工作。 - Hakanai
我可以看到你如何获取这些属性,但是如何在另一个PrinterJob中恢复它们呢? - Maurice Perry
@Maurice Perry: Trejkaz在他的问题中有一个loadAttributesFromPreferences()方法。您可以将属性保存在首选项或资源文件中,稍后再读取它们。 - Gilbert Le Blanc
是的,但是一旦你读取了这些属性,你如何使用它们来打印呢? - Maurice Perry
创建一个新的PrintServiceAttributeSet。 - Gilbert Le Blanc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接