SWT UI Thread is not Responding - Printing Error - java

I have a Print Button in my SWT TitleAreaDialog.
viewPDFButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
try {
startPdfPrintOperation();
}
catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
I am getting a existing PDF filename and path from a user selection from a table.
I am then wantinf to print the pdf file out to a local printer. The user needs to be allowed to select the local printer of choice.
public void startPdfPrintOperation() throws Exception {
File file = new File(getPDFFileName());
RandomAccessFile raf;
raf = new RandomAccessFile(file, "r");
FileChannel channel = raf.getChannel();
ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
pdfFile = new PDFFile(buf);
PDFPrintPage pages = new PDFPrintPage(pdfFile);
// Create Print Job
pjob = PrinterJob.getPrinterJob();
pjob.setPrintable(new MyPrintable());
final HashPrintRequestAttributeSet attset;
attset = new HashPrintRequestAttributeSet ();
attset.add (new PageRanges (1, pdfFile.getNumPages ()));
if (pjob.printDialog (attset)) {
try {
pjob.print (attset);
}
catch (PrinterException e) {
e.printStackTrace();
}
}
}
class MyPrintable implements Printable {
public int print (Graphics g, PageFormat format, int index) throws PrinterException {
int pagenum = index+1;
if (pagenum < 1 || pagenum > pdfFile.getNumPages ())
return NO_SUCH_PAGE;
Graphics2D g2d = (Graphics2D) g;
AffineTransform at = g2d.getTransform ();
PDFPage pdfPage = pdfFile.getPage (pagenum);
Dimension dim;
dim = pdfPage.getUnstretchedSize ((int) format.getImageableWidth (),
(int) format.getImageableHeight (),
pdfPage.getBBox ());
Rectangle bounds = new Rectangle ((int) format.getImageableX (),
(int) format.getImageableY (),
dim.width,
dim.height);
PDFRenderer rend = new PDFRenderer (pdfPage, (Graphics2D) g, bounds, null, null);
try
{
pdfPage.waitForFinish ();
rend.run ();
}
catch (InterruptedException ie)
{
MessageDialog.openError(null, "PDF Error Message", "Needs");
}
g2d.setTransform (at);
g2d.draw (new Rectangle2D.Double (format.getImageableX (),
format.getImageableY (),
format.getImageableWidth (),
format.getImageableHeight ()));
return PAGE_EXISTS;
}
}
I am getting the above error from line 315
if (pjob.printDialog (attset)) {
The printer dialog opens the entire application is frozen and goes unresponsive. Then in about 30 secs, I get the above error.
I have tried to use Display.getDefault().asyncExec(new Runnable() ) in multiple spots but that did not help.
Could it be because the base dialog is SWT and the printer dialog is AWT?

Since you didn't define "in multiple spots", I would suggest you refactor the print job in its own class, extends Thread and implement starting the print job in the run method.
I'm not familiar with all classes in above code, you can try simply starting this thread and it will run in parallel with the SWT thread. Try avoiding shared ressources, this may help resolving your deadlock. If you want to have a UI response from this thread, you can wrap e.g. the SWT messagebox ("Printing done!") in a call to Display.getDefault().asyncExec(new Runnable() { ... }.
Furthermore, please test if the printing code without UI code produces the same exception. If it does, the environment may be misconfigured.

Related

Webcam api : Maximizing the 720p capture

I am attempting to capture a video recording through an external camera, Logitec C922. Using java, I can make this possible through webcam api.
<dependency>
<groupId>com.github.sarxos</groupId>
<artifactId>webcam-capture</artifactId>
<version>0.3.10</version>
</dependency>
<dependency>
<groupId>xuggle</groupId>
<artifactId>xuggle-xuggler</artifactId>
<version>5.4</version>
</dependency>
However, for the life of me, I cannot make it record at 60FPS. The video randomly stutters when stored, and is not smooth at all.
I can connect to the camera, using the following details.
final List<Webcam> webcams = Webcam.getWebcams();
for (final Webcam cam : webcams) {
if (cam.getName().contains("C922")) {
System.out.println("### Logitec C922 cam found");
webcam = cam;
break;
}
}
I set the size of the cam to the following:
final Dimension[] nonStandardResolutions = new Dimension[] { WebcamResolution.HD720.getSize(), };
webcam.setCustomViewSizes(nonStandardResolutions);
webcam.setViewSize(WebcamResolution.HD720.getSize());
webcam.open(true);
And then I capture the images:
while (continueRecording) {
// capture the webcam image
final BufferedImage webcamImage = ConverterFactory.convertToType(webcam.getImage(),
BufferedImage.TYPE_3BYTE_BGR);
final Date timeOfCapture = new Date();
// convert the image and store
final IConverter converter = ConverterFactory.createConverter(webcamImage, IPixelFormat.Type.YUV420P);
final IVideoPicture frame = converter.toPicture(webcamImage,
(System.currentTimeMillis() - start) * 1000);
frame.setKeyFrame(false);
frame.setQuality(0);
writer.encodeVideo(0, frame);
}
My writer is defined as follows:
final Dimension size = WebcamResolution.HD720.getSize();
final IMediaWriter writer = ToolFactory.makeWriter(videoFile.getName());
writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_H264, size.width, size.height);
I am honestly not sure what in my code could be causing this. Given that I lower the resolution, I get no problems. ( 480p ) Could the issue be with the codes I am using?
As some of the comments mentioned, introducing queues does solve the problem. Here is the general logic to performs the needed steps. Note, I've setup my code for a lower resolution, as it allows me to capture 100FPS per sec. Adjust as needed.
Class to link the image/video capture and class to edit it :
public class WebcamRecorder {
final Dimension size = WebcamResolution.QVGA.getSize();
final Stopper stopper = new Stopper();
public void startRecording() throws Exception {
final Webcam webcam = Webcam.getDefault();
webcam.setViewSize(size);
webcam.open(true);
final BlockingQueue<CapturedFrame> queue = new LinkedBlockingQueue<CapturedFrame>();
final Thread recordingThread = new Thread(new RecordingThread(queue, webcam, stopper));
final Thread imageProcessingThread = new Thread(new ImageProcessingThread(queue, size));
recordingThread.start();
imageProcessingThread.start();
}
public void stopRecording() {
stopper.setStop(true);
}
}
RecordingThread :
public void run() {
try {
System.out.println("## capturing images began");
while (true) {
final BufferedImage webcamImage = ConverterFactory.convertToType(webcam.getImage(),
BufferedImage.TYPE_3BYTE_BGR);
final Date timeOfCapture = new Date();
queue.put(new CapturedFrame(webcamImage, timeOfCapture, false));
if (stopper.isStop()) {
System.out.println("### signal to stop capturing images received");
queue.put(new CapturedFrame(null, null, true));
break;
}
}
} catch (InterruptedException e) {
System.out.println("### threading issues during recording:: " + e.getMessage());
} finally {
System.out.println("## capturing images end");
if (webcam.isOpen()) {
webcam.close();
}
}
}
ImageProcessingThread:
public void run() {
writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_H264, size.width, size.height);
try {
int frameIdx = 0;
final long start = System.currentTimeMillis();
while (true) {
final CapturedFrame capturedFrame = queue.take();
if (capturedFrame.isEnd()) {
break;
}
final BufferedImage webcamImage = capturedFrame.getImage();
size.height);
// convert the image and store
final IConverter converter = ConverterFactory.createConverter(webcamImage, IPixelFormat.Type.YUV420P);
final long end = System.currentTimeMillis();
final IVideoPicture frame = converter.toPicture(webcamImage, (end - start) * 1000);
frame.setKeyFrame((frameIdx++ == 0));
frame.setQuality(0);
writer.encodeVideo(0, frame);
}
} catch (final InterruptedException e) {
System.out.println("### threading issues during image processing:: " + e.getMessage());
} finally {
if (writer != null) {
writer.close();
}
}
The way it works is pretty simple. The WebcamRecord class creates an instance of a queue that is shared between the video capture and the image processing. The RecordingThread sends bufferedImages to the queue ( in my case, it a pojo, called CapturedFrame ( which has a BufferedImage in it ) ). The ImageProcessingThread will listen and pull data from the queue. If it does not receive a signal that the writing should end, the loop never dies.

Java Jpanel print empty page

private void cmdprintActionPerformed(java.awt.event.ActionEvent evt) {
PrinterJob job = PrinterJob.getPrinterJob();
job.setJobName("Outside Processing System");
job.setPrintable (new Printable() {
#Override
public int print(Graphics pg, PageFormat pf, int pageNum){
if (pageNum > 0){
return Printable.NO_SUCH_PAGE;
}
OPSPrintPanel panel = new OPSPrintPanel();
Graphics2D g2 =(Graphics2D)pg;
g2.translate(pf.getImageableX(), pf.getImageableY());
panel.paint(pg);
return Printable.PAGE_EXISTS;
}
});
boolean ok = job.printDialog();
if (ok) {
try {
job.print();
} catch (PrinterException ex) {
JOptionPane.showMessageDialog(null, ex);
}
}
}
I'm trying to print a panel and the codes seems okay but when I click print and view it to pdf its only a blank page. I tried so many codes that can print panel but it doesn't print. Even I reinstall my NetBeans and install an updated jdk it won't work.
Blank page
You didn't dispose object g2 and use try catch block when you print as pdf. First you have to print the image as it is and then try to translate it.
Try this, i hope it would works.
OPSPrintPanel panel = new OPSPrintPanel();
//print the panel to pdf
Document document = new Document();
try {
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("C:\\temp\\test.pdf"));
document.open();
// PdfContentByte is an object containing the user positioned text and
// graphic contents of a page. It knows how to apply the proper font encoding.
PdfContentByte contentByte = writer.getDirectContent();
PdfTemplate template = contentByte.createTemplate(500, 500);
Graphics2D g2 = template.createGraphics(500, 500);
// First print the panel as it is and then try to translate it by removing comments
// g2.translate(pf.getImageableX(), pf.getImageableY());
panel.print(g2);
g2.dispose();
// Adds a template to this content.
contentByte.addTemplate(template, 30, 300);
} catch (Exception e)
{
e.printStackTrace();
}
finally
{
if(document.isOpen())
{
document.close();
}
}

Issue with drawing png file into swing GUI

I am facing an issue that I am not able to draw an png image into my swing GUI into JPanel (which I am adding into JScrollPane after).
Here is my code I am trying to use for this.
if(processCreated == true){
System.out.println("updating tree of organisms");
processCreated = false;
updateTree();
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(Svet.class.getName()).log(Level.SEVERE, null, ex);
}
tree = new File(path+"/out.png"); //File
try {
treeImage = ImageIO.read(tree); //BufferedImage
tp = new TreePane(treeImage.getScaledInstance( 500, 500 ,treeImage.SCALE_SMOOTH)); // my class, implementation below
treeOutput.add(tp); //adding "JPanel" with picture into GUI
treeOutput.repaint();
} catch (IOException ex) {
Logger.getLogger(Svet.class.getName()).log(Level.SEVERE, null, ex);
}
}
After this the JScrollPane remains empty. Is there anything wrong with my code? You can find what is what in comments.
Here is my TreePane class
public class TreePane extends JPanel{
Image img;
public TreePane( Image img ){
this.img = img;
}
public void paintComponent(Graphics g){
super.paintComponent(g);
int imgX = 0;
int imgY = 0;
g.drawImage(img, imgX, imgY, this);
}
}
Very likely your TreePane is layed out to size 0,0 and therefore you'll never see anything. Try adding a breakpoint and inspecting in paintComponent - it might not even ever get called.
To fix, you should explicitly set the size of your TreePane before adding it to the JScrollPane.
tp = new TreePane(treeImage.getScaledInstance( 500, 500 ,treeImage.SCALE_SMOOTH)); // my class, implementation below
tp.setSize(myWidth, myHeight);
treeOutput.add(tp); //adding "JPanel" with picture into GUI
treeOutput.repaint();

GUI in JAVA to display different images in a same frame

I want to display different images in a same frame within a loop. String pathName[] contains the different paths of the images. When running this code, only last image i.e image at path pathname[last] is getting displayed on frame instead I want all images to be displayed in a continuous way (have given delay of 1sec ). Help is appreciated.
public void actionPerformed(ActionEvent event) {
int i=0;
while(i<5){
if(i>0){
Container labelParent = receiverImageLabel.getParent();
labelParent.remove(receiverImageLabel);
labelParent.validate();
labelParent.repaint();
}
try {
imageR = ImageIO.read(new File(pathName[i++])).getScaledInstance(512,512 , BufferedImage.SCALE_SMOOTH);
receivedImage = new ImageIcon(imageR);
}catch (IOException e) {
e.printStackTrace();
}
receiverImageLabel = new JLabel(receivedImage);
receiverFrame.getContentPane().add(BorderLayout.EAST,receiverImageLabel);
receiverFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
receiverFrame.setSize(800,700);
receiverFrame.setVisible(true);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Your problem is a common one: you're calling Thread.sleep(...) in a Swing GUI on the event thread and are essentially thus putting the entire GUI to sleep.
Solution: Google the Swing Timer and use this in place of your while loop/Thread.sleep(...)
Also, if the images aren't too big, then consider reading them all in at once (in a background thread), putting them into ImageIcons, and then swapping out a JLabel's ImageIconsand in your Swing Timer.
For example, you could do something like:
ImageIcon[] icons = new ImageIcon[IMAGE_COUNT];
for (int i = 0; i < IMAGE_COUNT; i++) {
BufferedImage img = ImageIO.read(...); // read in the appropriate image
// ...... here manipulate the image if desired such as re-size it
icons[i] = new ImageIcon(img); // put it into an icon
}
elsewhere:
int timerDelay = 1000;
new Timer(timerDelay, new ActionListener(){
int count = 0;
#Override
public void actionPerformed(ActionEvent e) {
if (count < IMAGE_COUNT) {
someLabel.setIcon(icons[count]);
count++;
} else {
// stop the timer
((Timer)e.getSource()).stop();
}
}
}).start();
Note: code not compiled nor tested and is posted only as a general example of steps to consider.

How to read OS X *.icns file with Java

I want to read *.icns files in OS X into a BufferedImage. Help
Try this: http://code.google.com/p/appengine-awt/source/browse/trunk/apache-sanselan/src/main/java/org/apache/sanselan/formats/icns/IcnsDecoder.java?spec=svn8&r=8
Which is actually from: http://incubator.apache.org/sanselan/site/index.html
You need to convert ICNS to another image type first, and after load this image you can delete it. This is how to convert PNG to ICNS, so you just need to do in the opposite way:
public static void Png(File png, File icns) throws IOException{
ImageIcon image = new ImageIcon(ImageIO.read(png));
ImageIconAs(image, icns);
}
public static void ImageIconAs(ImageIcon ii, File icns) throws IOException{IconAs((Icon)ii,icns);}
public static void IconAs(Icon icon, File icns) throws IOException{
if (icon != null) {
BufferedImage bi = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB );
Graphics2D g = bi.createGraphics();
icon.paintIcon(new Canvas(), g, 0, 0 );
g.dispose();
File outputfile = new File("temp000.png");
ImageIO.write(bi, "png", outputfile);
execTerminal(new String[]{ "sips", "-s", "format", "tiff",
"temp000.png","--out", "temp000.tiff" });
File apaga2 = new File("temp000.png");
apaga2.delete();
execTerminal(new String[]{ "tiff2icns", "-noLarge",
"temp000.tiff", icns.getAbsolutePath()});
File apaga = new File("temp000.tiff");
apaga.delete();
}
}
static void execTerminal(String[] cmd){
int exitCode = 0;
try {
exitCode = Runtime.getRuntime().exec(cmd).waitFor();
}
catch (InterruptedException e) {e.printStackTrace();}
catch (IOException e) {
if (exitCode != 0) System.out.println("ln signaled an error with exit code " + exitCode);
}
}
You just need to use this to call the action:
Png(png_file,icns_file);
You can youse IconManager. It works with following icons formats:
*.ico - Windows Icon
*.icl - Windows Icon Library
*.icns - Macintosh Icon

Categories

Resources