I want create a rectangle using the whole screen. By using the whole screen, I mean something like this:
To start, is that even possible in Java, using the whole screen like that? Second, how would I go about doing it? Another thing, I do not want to draw an actual rectangle, I want to create on, as in a new java.awt.Rectangle
.
nb- First thing to note, this is done using Java 7, creating a transparent window in Java 6 is done differently and is not possible below update 10 (I believe)
Basically, this creates a transparent window, sized and positioned to cover the entire virtual screen (that is, if you have multiple screens, it will cover all of them).
I then use a JPanel
as the primary container to capture mouse events and perform paint effects.
The panel is made transparent. This allows what ever is below the panel (and the frame) to remain visible. I've then over painted this with a transparent color (I did this just to highlight the fact).
When you click and drag an area, it is exposed.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Area;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MySnipTool {
public static void main(String[] args) {
new MySnipTool();
}
public MySnipTool() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new CapturePane());
Rectangle bounds = getVirtualBounds();
frame.setLocation(bounds.getLocation());
frame.setSize(bounds.getSize());
frame.setAlwaysOnTop(true);
frame.setVisible(true);
}
});
}
public class CapturePane extends JPanel {
private Rectangle selectionBounds;
private Point clickPoint;
public CapturePane() {
setOpaque(false);
MouseAdapter mouseHandler = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
System.exit(0);
}
}
@Override
public void mousePressed(MouseEvent e) {
clickPoint = e.getPoint();
selectionBounds = null;
}
@Override
public void mouseReleased(MouseEvent e) {
clickPoint = null;
}
@Override
public void mouseDragged(MouseEvent e) {
Point dragPoint = e.getPoint();
int x = Math.min(clickPoint.x, dragPoint.x);
int y = Math.min(clickPoint.y, dragPoint.y);
int width = Math.max(clickPoint.x - dragPoint.x, dragPoint.x - clickPoint.x);
int height = Math.max(clickPoint.y - dragPoint.y, dragPoint.y - clickPoint.y);
selectionBounds = new Rectangle(x, y, width, height);
repaint();
}
};
addMouseListener(mouseHandler);
addMouseMotionListener(mouseHandler);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(new Color(255, 255, 255, 128));
Area fill = new Area(new Rectangle(new Point(0, 0), getSize()));
if (selectionBounds != null) {
fill.subtract(new Area(selectionBounds));
}
g2d.fill(fill);
if (selectionBounds != null) {
g2d.setColor(Color.BLACK);
g2d.draw(selectionBounds);
}
g2d.dispose();
}
}
public static Rectangle getVirtualBounds() {
Rectangle bounds = new Rectangle(0, 0, 0, 0);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice lstGDs[] = ge.getScreenDevices();
for (GraphicsDevice gd : lstGDs) {
bounds.add(gd.getDefaultConfiguration().getBounds());
}
return bounds;
}
}
Equally, you could just create a transparent frame that the user can resize. You will be responsible for implementing all the resize code yourself, but the solution would still be a viable one.
Updated
You may also need to check to see if the OS/hardware can support transparancy...
GraphicsConfiguration config = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
if (!AWTUtilities.isTranslucencyCapable(config)) {
System.out.println("Transluceny is not supported");
}
if (!AWTUtilities.isTranslucencySupported(AWTUtilities.Translucency.PERPIXEL_TRANSPARENT)) {
System.out.println("PerPeixel Transparency is not supported");
}
Updated with alternative approach
This is an alternative approach to the problem. Basically it takes a snap shot of the screen and renders it to the window. This then allows us to control the highlighting/selection as we need.
The drawback to this is that it is a static result, you won't get any currently running animation effects.
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SnipWithScreenShoot {
public static void main(String[] args) {
new SnipWithScreenShoot();
}
public SnipWithScreenShoot() {
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) {
}
try {
JFrame frame = new JFrame("Test");
frame.setUndecorated(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (AWTException exp) {
exp.printStackTrace();
System.out.println("That sucks");
}
}
});
}
public class TestPane extends JPanel {
private BufferedImage image;
private Rectangle selection;
public TestPane() throws AWTException {
Robot bot = new Robot();
image = bot.createScreenCapture(getVirtualBounds());
MouseAdapter handler = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
selection = new Rectangle(e.getPoint());
repaint();
}
@Override
public void mouseDragged(MouseEvent e) {
Point p = e.getPoint();
int width = Math.max(selection.x - e.getX(), e.getX() - selection.x);
int height = Math.max(selection.y - e.getY(), e.getY() - selection.y);
selection.setSize(width, height);
repaint();
}
};
addMouseListener(handler);
addMouseMotionListener(handler);
}
@Override
public Dimension getPreferredSize() {
return image == null ? super.getPreferredSize() : new Dimension(image.getWidth(), image.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(image, WIDTH, 0, this);
if (selection != null) {
g2d.setColor(new Color(225, 225, 255, 128));
g2d.fill(selection);
g2d.setColor(Color.GRAY);
g2d.draw(selection);
}
g2d.dispose();
}
}
}
public static Rectangle getVirtualBounds() {
Rectangle bounds = new Rectangle(0, 0, 0, 0);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice lstGDs[] = ge.getScreenDevices();
for (GraphicsDevice gd : lstGDs) {
bounds.add(gd.getDefaultConfiguration().getBounds());
}
return bounds;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With