1

I'm developing a Java app which will take a screen shot, I have 3 monitors in my office, so I want my app to be able to take a screen shot of the display I'm interested in. What it can do now is to take a screen shot of each screen and save the 3 files. But I don't want to get 3 file each time I run my Java app. Therefore I want to know if there is a way to detect from which screen my Java app is run, and only take the screen shot of that screen, but my question got no answer : How to determine in which monitor my Java app is running?

I thought about creating a shortcut of my Java app's jar file on desktop, then set it's property's target to : "C:\Program Files\AdoptOpenJDK\jdk-8.0.222.10-hotspot\bin\javaw.exe" -jar C:\Dir_Screen_Shoter\dist\Screen_Shoter.jar

Then I pinned the shortcut to Windows task bar, looking like this :

enter image description here

But the problem is : no matter from which display [ it shows up on every display ] I clicked it, my app always runs [ opens ] on the center [main ] display, so my question is : is there a way I can run this app on the display I clicked it, and that it can detect which monitor it is running from ?

I thought about something like : shift-click, alt-click or hold down ctrl then click on the app on tack bar, but it won't detect all those, so what is a good solution so when I run the app, it will know which display to take a screen shot, it's easy if my app opens a window and let user choose which monitor to act on, but I do not want that, I just want it to take a screen shot without opening an application window.

I've found some related questions, but none of them answers my question :

Show JFrame in a specific screen in dual monitor configuration

How to detect the current display with Java?

[ I tried this one, but it always show device Id == 1 ]

My app looks like this so far :

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Screen_Shoter extends JPanel
{
  static Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
  static JFrame frame=new JFrame("Screen_Shoter");
  static int W=screenSize.width,H=screenSize.height;
  SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  String Result="Screen_Size : "+W+" x "+H+"\n",Dir_Screenshots="C:/Dir_Screenshots/",Screen_Shot_File_Name=Dir_Screenshots+format.format(new Date()).replace("-","_").replace(" ","_").replace(":","_")+"_.png";
  JLabel infoLabel=new JLabel();

  public Screen_Shoter()                                             // Get ScreenShots From Multiple Monitors
  {
    GraphicsEnvironment ge=GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice[] gDevs=ge.getScreenDevices();

    if (!new File(Dir_Screenshots).exists()) new File(Dir_Screenshots).mkdirs();

    int defaultScreenIndex=getScreenIndex();
    Out("defaultScreenIndex = "+defaultScreenIndex+"\n");
    for (GraphicsDevice gDev : gDevs)
    {
      DisplayMode mode=gDev.getDisplayMode();
      Rectangle bounds=gDev.getDefaultConfiguration().getBounds();
      Out("[ "+gDev.getIDstring()+" ]  Min : ( "+bounds.getMinX()+" , "+bounds.getMinY()+" ) ; Max : ( "+bounds.getMaxX()+" , "+bounds.getMaxY()+" )   W = "+mode.getWidth()+" , H = "+mode.getHeight());

      try
      {
        Robot robot=new Robot();
        BufferedImage image=robot.createScreenCapture(new Rectangle((int)bounds.getMinX(),(int)bounds.getMinY(),(int)bounds.getWidth(),(int)bounds.getHeight()));
        ImageIO.write(image,"png",new File(Screen_Shot_File_Name.replace(".png",gDev.getIDstring().replace("\\","")+".png")));
      }
      catch (AWTException e) { e.printStackTrace(); }
      catch (IOException e) { e.printStackTrace(); }
    }

    infoLabel.setFont(new Font("Times New Roman",0,15));
    infoLabel.setForeground(new Color(0,0,218));
    infoLabel.setText("<html>"+Result.replace("\n","<P>")+"</html>");
    add(infoLabel);
  }

  int getScreenIndex()
  {
    int myScreenIndex=-1;

    GraphicsConfiguration config=frame.getGraphicsConfiguration();
    GraphicsDevice myScreen=config.getDevice();

    GraphicsEnvironment env=GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice[] allScreens=env.getScreenDevices();

    for (int i=0;i<allScreens.length;i++)
    {
      if (allScreens[i].equals(myScreen))
      {
        myScreenIndex=i;
        break;
      }
    }
    Out("frame : "+frame.getBounds());
    return myScreenIndex;
  }

  private static void showOnScreen(int screen,Window frame)
  {
    GraphicsEnvironment ge=GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice[] gd=ge.getScreenDevices();
    GraphicsDevice graphicsDevice;
    if (screen>-1 && screen<gd.length) graphicsDevice=gd[screen];
    else if (gd.length>0) graphicsDevice=gd[0];
    else throw new RuntimeException("No Screens Found");

    Rectangle bounds=graphicsDevice.getDefaultConfiguration().getBounds();
    int screenWidth=graphicsDevice.getDisplayMode().getWidth();
    int screenHeight=graphicsDevice.getDisplayMode().getHeight();
    frame.setLocation(bounds.x+(screenWidth-frame.getPreferredSize().width)/2,bounds.y+(screenHeight-frame.getPreferredSize().height)/2);
//    frame.setLocation(bounds.x,bounds.y);
    frame.setVisible(true);
  }

  private void out(String message)
  {
    System.out.print(message);
    Result+=message;
  }

  private void Out(String message)
  {
    System.out.println(message);
    Result+=message+"\n";
  }

  // Create the GUI and show it. For thread safety, this method should be invoked from the event-dispatching thread.
  static void createAndShowGUI()
  {
    final Screen_Shoter demo=new Screen_Shoter();

    frame.add(demo);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setBounds(0,0,600,178);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);                      // For test only
//    showOnScreen(0,frame);
  }

  public static void main(String[] args)
  {    
    // Schedule a job for the event-dispatching thread : creating and showing this application's GUI.
    SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } });
  }
}
Frank
  • 30,590
  • 58
  • 161
  • 244

1 Answers1

0

Try having your program look for the mouse pointers location and if on that screen take picture when app is clicked

John F
  • 1