提交 3ca8add3 编写于 作者: A asaha

Merge

......@@ -682,6 +682,10 @@ ec72a941be0a50ab77f5375cf710bc06e4f118d3 jdk8u121-b11
2974746e56192cdd14fc2dd43179bcf28e4faf4a jdk8u121-b13
4f69f3363a2ecee8d3df2b046266a76c2a805139 jdk8u121-b31
ec26e3331158912f86268ef473e64514c70cbd52 jdk8u121-b32
cb2c7c89dd09edcda4cb7bd0db623c813d3e5dbc jdk8u121-b33
90f36d39acdc5be0665722538749c59583e3b83d jdk8u121-b34
cec5310dcc2b876dd53a057035cb63dd22f63257 jdk8u121-b35
a5c94735ad3fb33f353abc23e25915db2ff7a36e jdk8u121-b36
032874d46bf95478cb86690b3c91d335c0764b0b jdk8u131-b00
bea5b22daf5ddd941f3bcbf7a4e5fc5244ceb788 jdk8u131-b01
a01d217a232906e82f80e5bc3db4d60c4c74716e jdk8u131-b02
......
......@@ -201,6 +201,7 @@ SUNWprivate_1.1 {
Java_sun_print_CUPSPrinter_initIDs;
Java_sun_print_CUPSPrinter_getCupsServer;
Java_sun_print_CUPSPrinter_getCupsPort;
Java_sun_print_CUPSPrinter_getCupsDefaultPrinter;
Java_sun_print_CUPSPrinter_canConnect;
Java_sun_print_CUPSPrinter_getMedia;
Java_sun_print_CUPSPrinter_getPageSizes;
......
......@@ -73,6 +73,7 @@ SUNWprivate_1.1 {
Java_sun_print_CUPSPrinter_initIDs;
Java_sun_print_CUPSPrinter_getCupsServer;
Java_sun_print_CUPSPrinter_getCupsPort;
Java_sun_print_CUPSPrinter_getCupsDefaultPrinter;
Java_sun_print_CUPSPrinter_canConnect;
Java_sun_print_CUPSPrinter_getMedia;
Java_sun_print_CUPSPrinter_getPageSizes;
......
......@@ -439,6 +439,7 @@ SUNWprivate_1.1 {
Java_sun_print_CUPSPrinter_initIDs;
Java_sun_print_CUPSPrinter_getCupsServer;
Java_sun_print_CUPSPrinter_getCupsPort;
Java_sun_print_CUPSPrinter_getCupsDefaultPrinter;
Java_sun_print_CUPSPrinter_canConnect;
Java_sun_print_CUPSPrinter_getMedia;
Java_sun_print_CUPSPrinter_getPageSizes;
......
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -607,6 +607,13 @@ public class OSXOffScreenSurfaceData extends OSXSurfaceData // implements Raster
fImageInfoInt.put(kNeedToSyncFromJavaPixelsIndex, 1); // the pixels will change
}
private void syncFromCustom() {
}
private void syncToCustom() {
}
// /**
// * Invoked when the raster's contents will be taken (via the Raster.getDataBuffer() method)
// */
......
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -57,15 +57,19 @@ public class CInputMethodDescriptor implements InputMethodDescriptor {
}
static Object[] getAvailableLocalesInternal() {
List workList = nativeGetAvailableLocales();
if (workList != null) {
List<Object> workList = nativeGetAvailableLocales();
Locale currentLocale = CInputMethod.getNativeLocale();
if (workList == null || workList.isEmpty()) {
return new Object[] {
currentLocale != null ? currentLocale : Locale.getDefault()
};
} else {
if (currentLocale != null && !workList.contains(currentLocale)) {
workList.add(currentLocale);
}
return workList.toArray();
}
return new Object[] {
Locale.getDefault()
};
}
/**
......@@ -119,5 +123,5 @@ public class CInputMethodDescriptor implements InputMethodDescriptor {
}
private static native void nativeInit();
private static native List nativeGetAvailableLocales();
private static native List<Object> nativeGetAvailableLocales();
}
......@@ -34,9 +34,6 @@
#import <JavaNativeFoundation/JavaNativeFoundation.h>
#import "BufImgSurfaceData.h"
#import "ThreadUtilities.h"
//#define DEBUG 1
#if defined DEBUG
......@@ -195,10 +192,9 @@ IMAGE_SURFACE_INLINE void customPixelsFromJava(JNIEnv *env, ImageSDOps *isdo)
PRINT(" customPixelsFromJava")
SurfaceDataOps *sdo = (SurfaceDataOps*)isdo;
JNFCallVoidMethod([ThreadUtilities getJNIEnv], sdo->sdObject, jm_syncFromCustom); // AWT_THREADING Safe (known object)
JNFCallVoidMethod(env, sdo->sdObject, jm_syncFromCustom); // AWT_THREADING Safe (known object)
}
IMAGE_SURFACE_INLINE void copyBits(jint w, jint h, jint javaPixelsBytesPerRow, Pixel8bit *pixelsSrc, jint dstPixelsBytesPerRow, Pixel8bit *pixelsDst)
{
PRINT(" copyBits")
......@@ -427,7 +423,7 @@ IMAGE_SURFACE_INLINE void customPixelsToJava(JNIEnv *env, ImageSDOps *isdo)
PRINT(" customPixelsToJava")
SurfaceDataOps *sdo = (SurfaceDataOps*)isdo;
JNFCallVoidMethod([ThreadUtilities getJNIEnv], sdo->sdObject, jm_syncToCustom); // AWT_THREADING Safe (known object)
JNFCallVoidMethod(env, sdo->sdObject, jm_syncToCustom); // AWT_THREADING Safe (known object)
}
IMAGE_SURFACE_INLINE void removeAlphaPre_32bit(jint w, jint h, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel32bit *pixelsSrc)
......@@ -995,9 +991,9 @@ static void imageDataProvider_UnholdJavaPixels(void *info, const void *data, siz
{
PRINT("imageDataProvider_UnholdJavaPixels")
ImageSDOps* isdo = (ImageSDOps*)info;
unholdJavaPixels([ThreadUtilities getJNIEnv], isdo);
// Currently do nothing
}
static void imageDataProvider_FreeTempPixels(void *info, const void *data, size_t size)
{
PRINT("imageDataProvider_FreeTempPixels")
......
......@@ -165,8 +165,11 @@ public class WindowsRootPaneUI extends BasicRootPaneUI {
}
public boolean postProcessKeyEvent(KeyEvent ev) {
if(ev.isConsumed()) {
// do not manage consumed event
if(ev.isConsumed() && ev.getKeyCode() != KeyEvent.VK_ALT) {
// mnemonic combination, it's consumed, but we need
// set altKeyPressed to false, otherwise after selection
// component by mnemonic combination a menu will be open
altKeyPressed = false;
return false;
}
if (ev.getKeyCode() == KeyEvent.VK_ALT) {
......
......@@ -27,6 +27,7 @@ package sun.font;
import java.io.File;
import java.awt.Font;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
......@@ -132,6 +133,16 @@ public class FontFamily {
FileFont newFont = (FileFont)font;
File newDir = (new File(newFont.platName)).getParentFile();
if (existDir != null) {
try {
existDir = existDir.getCanonicalFile();
} catch (IOException ignored) {}
}
if (newDir != null) {
try {
newDir = newDir.getCanonicalFile();
} catch (IOException ignored) {}
}
return java.util.Objects.equals(newDir, existDir);
}
......
......@@ -51,6 +51,7 @@ public class CUPSPrinter {
private boolean initialized;
private static native String getCupsServer();
private static native int getCupsPort();
private static native String getCupsDefaultPrinter();
private static native boolean canConnect(String server, int port);
private static native boolean initIDs();
// These functions need to be synchronized as
......@@ -250,6 +251,15 @@ public class CUPSPrinter {
* Returns 2 values - index 0 is printer name, index 1 is the uri.
*/
static String[] getDefaultPrinter() {
// Try to get user/lpoptions-defined printer name from CUPS
// if not user-set, then go for server default destination
String printerInfo[] = new String[2];
printerInfo[0] = getCupsDefaultPrinter();
if (printerInfo[0] != null) {
printerInfo[1] = null;
return printerInfo.clone();
}
try {
URL url = new URL("http", getServer(), getPort(), "");
final HttpURLConnection urlConnection =
......@@ -285,7 +295,7 @@ public class CUPSPrinter {
attCl)) {
HashMap defaultMap = null;
String[] printerInfo = new String[2];
InputStream is = urlConnection.getInputStream();
HashMap[] responseMap = IPPPrintService.readIPPResponse(
is);
......
......@@ -43,6 +43,10 @@ typedef int (*fn_ippPort)(void);
typedef http_t* (*fn_httpConnect)(const char *, int);
typedef void (*fn_httpClose)(http_t *);
typedef char* (*fn_cupsGetPPD)(const char *);
typedef cups_dest_t* (*fn_cupsGetDest)(const char *name,
const char *instance, int num_dests, cups_dest_t *dests);
typedef int (*fn_cupsGetDests)(cups_dest_t **dests);
typedef void (*fn_cupsFreeDests)(int num_dests, cups_dest_t *dests);
typedef ppd_file_t* (*fn_ppdOpenFile)(const char *);
typedef void (*fn_ppdClose)(ppd_file_t *);
typedef ppd_option_t* (*fn_ppdFindOption)(ppd_file_t *, const char *);
......@@ -53,6 +57,9 @@ fn_ippPort j2d_ippPort;
fn_httpConnect j2d_httpConnect;
fn_httpClose j2d_httpClose;
fn_cupsGetPPD j2d_cupsGetPPD;
fn_cupsGetDest j2d_cupsGetDest;
fn_cupsGetDests j2d_cupsGetDests;
fn_cupsFreeDests j2d_cupsFreeDests;
fn_ppdOpenFile j2d_ppdOpenFile;
fn_ppdClose j2d_ppdClose;
fn_ppdFindOption j2d_ppdFindOption;
......@@ -106,6 +113,24 @@ Java_sun_print_CUPSPrinter_initIDs(JNIEnv *env,
return JNI_FALSE;
}
j2d_cupsGetDest = (fn_cupsGetDest)dlsym(handle, "cupsGetDest");
if (j2d_cupsGetDest == NULL) {
dlclose(handle);
return JNI_FALSE;
}
j2d_cupsGetDests = (fn_cupsGetDests)dlsym(handle, "cupsGetDests");
if (j2d_cupsGetDests == NULL) {
dlclose(handle);
return JNI_FALSE;
}
j2d_cupsFreeDests = (fn_cupsFreeDests)dlsym(handle, "cupsFreeDests");
if (j2d_cupsFreeDests == NULL) {
dlclose(handle);
return JNI_FALSE;
}
j2d_ppdOpenFile = (fn_ppdOpenFile)dlsym(handle, "ppdOpenFile");
if (j2d_ppdOpenFile == NULL) {
dlclose(handle);
......@@ -169,6 +194,30 @@ Java_sun_print_CUPSPrinter_getCupsPort(JNIEnv *env,
}
/*
* Gets CUPS default printer name.
*
*/
JNIEXPORT jstring JNICALL
Java_sun_print_CUPSPrinter_getCupsDefaultPrinter(JNIEnv *env,
jobject printObj)
{
jstring cDefPrinter = NULL;
cups_dest_t *dests;
char *defaultPrinter = NULL;
int num_dests = j2d_cupsGetDests(&dests);
int i = 0;
cups_dest_t *dest = j2d_cupsGetDest(NULL, NULL, num_dests, dests);
if (dest != NULL) {
defaultPrinter = dest->name;
if (defaultPrinter != NULL) {
cDefPrinter = JNU_NewStringPlatform(env, defaultPrinter);
}
}
j2d_cupsFreeDests(num_dests, dests);
return cDefPrinter;
}
/*
* Checks if connection can be made to the server.
*
......
......@@ -4625,6 +4625,10 @@ final public class AccessBridge extends AccessBridgeLoader {
private void _getVisibleChildrenCount(final AccessibleContext ac) {
if (ac == null)
return;
if(ac instanceof AccessibleExtendedTable) {
_getVisibleChildrenCount((AccessibleExtendedTable)ac);
return;
}
int numChildren = InvocationUtils.invokeAndWait(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
......@@ -4666,6 +4670,83 @@ final public class AccessBridge extends AccessBridgeLoader {
}
}
/*
* Recursively descends AccessibleContext and gets the number
* of visible children. Stops search if get to invisible part of table.
*/
private void _getVisibleChildrenCount(final AccessibleExtendedTable acTable) {
if (acTable == null)
return;
int lastVisibleRow = -1;
int lastVisibleColumn = -1;
boolean foundVisible = false;
int rowCount = InvocationUtils.invokeAndWait(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return acTable.getAccessibleRowCount();
}
}, acTable);
int columnCount = InvocationUtils.invokeAndWait(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return acTable.getAccessibleColumnCount();
}
}, acTable);
for (int rowIdx = 0; rowIdx < rowCount; rowIdx++) {
for (int columnIdx = 0; columnIdx < columnCount; columnIdx++) {
if (lastVisibleRow != -1 && rowIdx > lastVisibleRow) {
continue;
}
if (lastVisibleColumn != -1 && columnIdx > lastVisibleColumn) {
continue;
}
int finalRowIdx = rowIdx;
int finalColumnIdx = columnIdx;
final AccessibleContext ac2 = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
@Override
public AccessibleContext call() throws Exception {
Accessible a = acTable.getAccessibleAt(finalRowIdx, finalColumnIdx);
if (a == null)
return null;
else
return a.getAccessibleContext();
}
}, acTable);
if (ac2 == null ||
(!InvocationUtils.invokeAndWait(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING);
}
}, acTable))
) {
if (foundVisible) {
if (columnIdx != 0 && lastVisibleColumn == -1) {
//the same row, so we found the last visible column
lastVisibleColumn = columnIdx - 1;
} else if (columnIdx == 0 && lastVisibleRow == -1) {
lastVisibleRow = rowIdx - 1;
}
}
continue;
}
foundVisible = true;
_visibleChildrenCount++;
if (InvocationUtils.invokeAndWait(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return ac2.getAccessibleChildrenCount();
}
}, acTable) > 0) {
_getVisibleChildrenCount(ac2);
}
}
}
}
/**
* Gets the visible child of an AccessibleContext at the
* specified index
......@@ -4702,7 +4783,10 @@ final public class AccessBridge extends AccessBridgeLoader {
if (_visibleChild != null) {
return;
}
if(ac instanceof AccessibleExtendedTable) {
_getVisibleChild((AccessibleExtendedTable)ac, index);
return;
}
int numChildren = InvocationUtils.invokeAndWait(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
......@@ -4711,7 +4795,7 @@ final public class AccessBridge extends AccessBridgeLoader {
}, ac);
for (int i = 0; i < numChildren; i++) {
final int idx=i;
final AccessibleContext ac2=InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
final AccessibleContext ac2 = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
@Override
public AccessibleContext call() throws Exception {
Accessible a = ac.getAccessibleChild(idx);
......@@ -4748,6 +4832,82 @@ final public class AccessBridge extends AccessBridgeLoader {
}
}
private void _getVisibleChild(final AccessibleExtendedTable acTable, final int index) {
if (_visibleChild != null) {
return;
}
int lastVisibleRow = -1;
int lastVisibleColumn = -1;
boolean foundVisible = false;
int rowCount = InvocationUtils.invokeAndWait(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return acTable.getAccessibleRowCount();
}
}, acTable);
int columnCount = InvocationUtils.invokeAndWait(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return acTable.getAccessibleColumnCount();
}
}, acTable);
for (int rowIdx = 0; rowIdx < rowCount; rowIdx++) {
for (int columnIdx = 0; columnIdx < columnCount; columnIdx++) {
if (lastVisibleRow != -1 && rowIdx > lastVisibleRow) {
continue;
}
if (lastVisibleColumn != -1 && columnIdx > lastVisibleColumn) {
continue;
}
int finalRowIdx = rowIdx;
int finalColumnIdx = columnIdx;
final AccessibleContext ac2 = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
@Override
public AccessibleContext call() throws Exception {
Accessible a = acTable.getAccessibleAt(finalRowIdx, finalColumnIdx);
if (a == null)
return null;
else
return a.getAccessibleContext();
}
}, acTable);
if (ac2 == null ||
(!InvocationUtils.invokeAndWait(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING);
}
}, acTable))) {
if (foundVisible) {
if (columnIdx != 0 && lastVisibleColumn == -1) {
//the same row, so we found the last visible column
lastVisibleColumn = columnIdx - 1;
} else if (columnIdx == 0 && lastVisibleRow == -1) {
lastVisibleRow = rowIdx - 1;
}
}
continue;
}
foundVisible = true;
if (!_foundVisibleChild && _currentVisibleIndex == index) {
_visibleChild = ac2;
_foundVisibleChild = true;
return;
}
_currentVisibleIndex++;
if (InvocationUtils.invokeAndWait(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return ac2.getAccessibleChildrenCount();
}
}, acTable) > 0) {
_getVisibleChild(ac2, index);
}
}
}
}
/* ===== Java object memory management code ===== */
......@@ -7123,6 +7283,25 @@ final public class AccessBridge extends AccessBridgeLoader {
*/
private static class InvocationUtils {
/**
* Invokes a {@code Callable} in the {@code AppContext} of the given {@code Accessible}
* and waits for it to finish blocking the caller thread.
*
* @param callable the {@code Callable} to invoke
* @param accessibleTable the {@code AccessibleExtendedTable} which would be used to find the right context
* for the task execution
* @param <T> type parameter for the result value
*
* @return the result of the {@code Callable} execution
*/
public static <T> T invokeAndWait(final Callable<T> callable,
final AccessibleExtendedTable accessibleTable) {
if (accessibleTable instanceof AccessibleContext) {
return invokeAndWait(callable, (AccessibleContext)accessibleTable);
}
throw new RuntimeException("Unmapped AccessibleContext used to dispatch event: " + accessibleTable);
}
/**
* Invokes a {@code Callable} in the {@code AppContext} of the given {@code Accessible}
* and waits for it to finish blocking the caller thread.
......
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 8173145
@summary Menu is activated after using mnemonic Alt/Key combination
@modules java.desktop/com.sun.java.swing.plaf.windows
@run main Test8173145
*/
import java.awt.*;
import java.awt.event.KeyEvent;
import java.lang.reflect.InvocationTargetException;
import javax.swing.*;
public class Test8173145 {
private volatile static JButton btn;
private volatile static boolean uiCreated;
public static void main(String[] args) throws InvocationTargetException, InterruptedException, AWTException {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
try {
uiCreated = createGUI();
} catch (Exception e) {
e.printStackTrace();
}
}
});
if (uiCreated) {
test();
} else {
//no windows l&f, skip the test
}
}
private static void test() {
final Robot robot;
try {
robot = new Robot();
} catch (AWTException e) {
throw new RuntimeException(e);
}
robot.setAutoDelay(100);
robot.waitForIdle();
robot.keyPress(KeyEvent.VK_ALT);
robot.keyPress(KeyEvent.VK_M);
robot.keyRelease(KeyEvent.VK_M);
robot.keyRelease(KeyEvent.VK_ALT);
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
if (focusOwner != btn) {
throw new RuntimeException("Wrong focus owner");
}
}
private static boolean createGUI() {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception e) {
return false;
}
JFrame f = new JFrame();
JPanel panel = new JPanel();
btn = new JButton("Mmmmm");
btn.setMnemonic(KeyEvent.VK_M);
btn.setDisplayedMnemonicIndex(0);
panel.add(btn);
JTextField tf = new JTextField();
tf.setColumns(10);
panel.add(tf);
f.setJMenuBar(getMenuBar());
f.add(panel);
f.pack();
f.setVisible(true);
tf.requestFocus();
return true;
}
static JMenuBar getMenuBar() {
JMenuBar menuBar;
JMenu menu;
menuBar = new JMenuBar();
menu = new JMenu("Menu");
menuBar.add(menu);
JMenuItem mi = new JMenuItem("test");
menu.add(mi);
return menuBar;
}
}
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8163889
* @summary Printing crashes on OSX.
* @run main PrintCrashTest
*/
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.standard.Destination;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.awt.print.Printable;
import java.awt.print.PrinterJob;
import java.io.File;
public class PrintCrashTest {
public static void main(String[] args) throws Exception {
PrinterJob printerJob = PrinterJob.getPrinterJob();
printerJob.setPrintable((graphics, pageFormat, pageIndex) -> {
if (pageIndex != 0) {
return Printable.NO_SUCH_PAGE;
} else {
Shape shape = new Rectangle(110, 110, 10, 10);
Rectangle rect = shape.getBounds();
BufferedImage image = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice()
.getDefaultConfiguration().createCompatibleImage(rect.width, rect.height, Transparency.BITMASK);
graphics.drawImage(image, rect.x, rect.y, rect.width, rect.height, null);
return Printable.PAGE_EXISTS;
}
});
File file = null;
try {
HashPrintRequestAttributeSet hashPrintRequestAttributeSet = new HashPrintRequestAttributeSet();
file = File.createTempFile("out", "ps");
file.deleteOnExit();
Destination destination = new Destination(file.toURI());
hashPrintRequestAttributeSet.add(destination);
printerJob.print(hashPrintRequestAttributeSet);
} finally {
if (file != null) {
file.delete();
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册