2014-10-11 4 views
0

Я хочу сделать экран для печати за JFrame, который я называю источником. Но JFrame (источник) сам по себе не так и напечатать его в другой JFrame, который я называю судьба ... как на картинке в ссылке: https://drive.google.com/file/d/0B4iWj2t4ATQ5ZllwVEE0M1BxUnc/view?usp=sharingПечать экрана без JFrame

Я пытался использовать setVisible(false) и после setVisible(true) но я не хочу, она закрывает и снова открыть. Как я это делаю?

Вот мой фактический код:

package tests; 

import java.awt.*; 
import java.awt.image.BufferedImage; 
import javax.swing.JFrame; 

public class Offscreen { 

    private static BufferedImage img; 

    public static void main(String[] main) throws AWTException { 
     // starts all frames 
     JFrame source = new JFrame(); 
     source.setSize(500, 500); 
     source.setLocation(700, 0); 
     source.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     source.setVisible(true); 
     JFrame destiny = new JFrame() { 
      public void paint(Graphics g) { 
       if (img != null) 
        // draw print screen 
        g.drawImage(img, 0, 0, null); 
      } 
     }; 
     destiny.setSize(500, 500);; 
     destiny.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     destiny.setVisible(true); 

     // print screen 
     Robot r = new Robot(); 
     // hide source 
     source.setVisible(false); 
     long l = System.currentTimeMillis(); 
     while (System.currentTimeMillis() - l < 200) { // take the time to hide 
     } 
     // take the picture 
     img = r.createScreenCapture(source.getBounds()); 
     // show the source again 
     source.setVisible(true); 
     // print on destiny 
     destiny.repaint(); 
    } 
} 
+2

Вы хотите делать? Это я, или у других тоже есть трудное время, чтобы расшифровать то, что вы пытаетесь сделать? –

+0

У него в кадре, который показывает печатный экран, который он берет, проблема заключается в том, что рамка видна на печатном экране, я предполагаю, что он сначала хочет принтер, а затем один раз, когда он доступен, чтобы показать его на кадре. – arynaq

ответ

2

«Предполагая, что» вы только хотите, чтобы захватить область позади активного фрейма (и, как вы говорите, без рамки), а затем что-то вроде ..

import java.awt.AWTException; 
import java.awt.AlphaComposite; 
import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Rectangle; 
import java.awt.Robot; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.ComponentAdapter; 
import java.awt.event.ComponentEvent; 
import java.awt.image.BufferedImage; 
import java.lang.reflect.InvocationTargetException; 
import java.util.concurrent.ExecutionException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.SwingWorker; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class PrintScreen01 { 

    public static void main(String[] args) { 
     new PrintScreen01(); 
    } 

    private Timer timer; 

    public PrintScreen01() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException ex) { 
       } catch (InstantiationException ex) { 
       } catch (IllegalAccessException ex) { 
       } catch (UnsupportedLookAndFeelException ex) { 
       } 

       final PrintPane printPane = new PrintPane(); 

       final JFrame frame = new JFrame("Test"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(printPane); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.addComponentListener(new ComponentAdapter() { 

        @Override 
        public void componentMoved(ComponentEvent e) { 
         timer.restart(); 
        } 

        @Override 
        public void componentResized(ComponentEvent e) { 
         timer.restart(); 
        } 

       }); 
       timer = new Timer(250, new ActionListener() { 
        @Override 
        public void actionPerformed(ActionEvent e) { 
         if (frame.isVisible()) { 
          takeSnapShot(frame, printPane); 
         } 
        } 
       }); 
       timer.setRepeats(false); 
       frame.setVisible(true); 
//    takeSnapShot(frame, printPane); 
      } 
     }); 
    } 

    public void takeSnapShot(JFrame frame, PrintPane pane) { 

     Rectangle bounds = new Rectangle(pane.getLocationOnScreen(), pane.getSize()); 
     frame.setVisible(false); 
     new SnapShotWorker(frame, pane, bounds).execute(); 

    } 

    public class SnapShotWorker extends SwingWorker<BufferedImage, BufferedImage> { 

     private JFrame frame; 
     private PrintPane pane; 
     private Rectangle captureBounds; 

     public SnapShotWorker(JFrame frame, PrintPane pane, Rectangle bounds) { 
      this.frame = frame; 
      this.pane = pane; 
      captureBounds = bounds; 
     } 

     @Override 
     protected BufferedImage doInBackground() throws Exception { 

      Thread.sleep(125); 

      BufferedImage snapShot = null; 
      try { 
       Robot bot = new Robot(); 
       snapShot = bot.createScreenCapture(captureBounds); 
      } catch (AWTException ex) { 
       ex.printStackTrace(); 
      } 
      Thread.sleep(125); 
      return snapShot; 
     } 

     @Override 
     protected void done() { 
      try { 
       BufferedImage snapShot = get(); 
       pane.setSnapShot(snapShot); 
       frame.setVisible(true); 
      } catch (InterruptedException ex) { 
       ex.printStackTrace(); 
      } catch (ExecutionException ex) { 
       ex.printStackTrace(); 
      } 
     } 



    } 

    public class PrintPane extends JPanel { 

     private BufferedImage background; 

     public PrintPane() { 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     public void setSnapShot(BufferedImage img) { 
      background = img; 
      repaint(); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      if (background != null) { 
       Graphics2D g2d = (Graphics2D) g.create(); 
       g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f)); 
       g2d.drawImage(background, 0, 0, this); 
       g2d.dispose(); 
      } 
     } 

    } 

} 

Может помочь ...

Теперь, у меня были некоторые проблемы с синхронизацией Robot, казалось бы, что часть операции пронизывается каким-то образом, это означает, что если не йо u получил время изменения рамки между невидимым и видимым «правым», вы бы действительно отменили фрейм ... раздражающий ...

Чтобы исправить это и уменьшить количество попыток, screen, я использовал javax.swing.Timer (для уменьшения попыток захвата) и SwingWorker для управления фактическим процессом моментального снимка, вытаскивая его из Диспетчерского потока событий, обеспечивая (в некоторой степени), чтобы окно было невидимым.

Я также добавил некоторые дополнительные задержки, чтобы гарантировать, что кадр был снят с экрана достаточно долго, чтобы предотвратить это был захват снимка ...

+0

Помогите много, но пользователь увидит, что кадр скрывается и открывается. Но все равно спасибо. – NX1125

+0

Нет никакого способа обойти это, если вам не нужен кадр на экране, тогда вам нужно будет скрыть его первым, вы не сможете «захватить» под активным окном – MadProgrammer

+0

[Этот пример] (http: // stackoverflow .com/questions/13948122/drawing-a-bounding-rectangle-to-select-what-area-to-record/13948198 # 13948198) - это чит ... – MadProgrammer

Смежные вопросы