53996

How to remove drop shadow of Java AWT Frame on OSX?

Question:

Is it possible to disable the drop shadow of a Java AWT application on OS X? I want to create a transparent window, which works fine, but I cannot get rid of the drop shadow.

If I was using a JFrame this could be done using:

JRootPane root = frame.getRootPane(); root.putClientProperty( "Window.shadow", Boolean.FALSE );

Any similar possibility for an AWT Frame?

I' using the Framework <a href="http://processing.org/" rel="nofollow">Processing</a> and my code there looks like this:

void setup(){ frame.removeNotify(); frame.setUndecorated(true); }

Processing itself does the main Frame creation, here is the <a href="http://code.google.com/p/processing/source/browse/trunk/processing/core/src/processing/core/PApplet.java" rel="nofollow">source</a>.

Answer1:

This is a simple application that uses a transparent window running on Max OS X 10.7.5 under Java 7 (has run under Java 6) which has no problems...

<img alt="enter image description here" class="b-lazy" data-src="https://i.stack.imgur.com/8DBfe.png" data-original="https://i.stack.imgur.com/8DBfe.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" />

Share some code so we can replicate the issue

<strong>Updated from feedback</strong>

I have tested this on Mac OS 10.7.5 & 10.8.2, using JDK 1.7.0_07 & 1.6.0_37

Without and with Window.shadow property...

<img alt="enter image description here" class="b-lazy" data-src="https://i.stack.imgur.com/A8AqY.png" data-original="https://i.stack.imgur.com/A8AqY.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" /><img alt="enter image description here" class="b-lazy" data-src="https://i.stack.imgur.com/twJZq.png" data-original="https://i.stack.imgur.com/twJZq.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" />

Without going into a lot of tests and without further information, I would suggest you want to make this call as early as you can. If that doesn't work, make it the last call before you make the window visible.

This may be related to how Java/AWT connects to it's native peer, presumably, once the connection is made, you will no longer be able to effect these kinds of properties...

public class TransparentFrame { public static void main(String[] args) { new TransparentFrame(); } public TransparentFrame() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception ex) { } // Use this to test the transparentancy API //doTransparentFrame(); doDropShadow(); } }); } protected void doDropShadow() { String version = System.getProperty("java.version"); System.out.println(version); JFrame frame = new JFrame("Testing"); JRootPane root = frame.getRootPane(); root.putClientProperty("Window.shadow", root); frame.setUndecorated(true); frame.setContentPane(new ContentPane()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new ImagePane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } protected void doTransparentFrame() { JFrame frame = new JFrame("Testing"); frame.setUndecorated(true); frame.setContentPane(new ContentPane()); String version = System.getProperty("java.version"); System.out.println(version); if (version.startsWith("1.7")) { frame.setBackground(new Color(0, 0, 0, 0)); } else if (version.startsWith("1.6")) { if (supportsPerAlphaPixel()) { setOpaque(frame, false); } else { System.out.println("Per Pixel Alphering is not support with Java " + version); System.exit(1); } } else { System.out.println("Per Pixel Alphering is not support with Java " + version); System.exit(1); } frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new ImagePane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static boolean supportsPerAlphaPixel() { boolean support = false; try { Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities"); support = true; } catch (Exception exp) { } return support; } public static void setOpaque(Window window, boolean opaque) { try { Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities"); if (awtUtilsClass != null) { Method method = awtUtilsClass.getMethod("setWindowOpaque", Window.class, boolean.class); method.invoke(null, window, opaque); } } catch (Exception exp) { } } public class ContentPane extends JPanel { public ContentPane() { setOpaque(false); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.RED); g.drawRect(0, 0, getWidth() - 1, getHeight() - 1); } } public class ImagePane extends JPanel { private BufferedImage background; private BufferedImage offImage; private Ellipse2D offButton; private boolean mouseIn; public ImagePane() { setOpaque(false); try { background = ImageIO.read(new File("tamagotchi400.png")); offImage = ImageIO.read(new File("powerSmall.png")); } catch (IOException ex) { ex.printStackTrace(); } offButton = new Ellipse2D.Float(212, 330, 25, 25); MouseAdapter handler = new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 1 && e.getButton() == MouseEvent.BUTTON1) { if (offButton.contains(e.getPoint())) { Window window = SwingUtilities.getWindowAncestor(ImagePane.this); if (window != null) { window.dispose(); } } } } @Override public void mouseMoved(MouseEvent e) { Cursor cursor = Cursor.getDefaultCursor(); if (offButton.contains(e.getPoint())) { cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); } setCursor(cursor); } @Override public void mouseEntered(MouseEvent e) { mouseIn = true; repaint(); } @Override public void mouseExited(MouseEvent e) { mouseIn = false; repaint(); } }; addMouseListener(handler); addMouseMotionListener(handler); } @Override public Dimension getPreferredSize() { return background == null ? new Dimension(400, 400) : new Dimension(background.getWidth(), background.getHeight()); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (background != null) { Graphics2D g2d = (Graphics2D) g.create(); int x = (getWidth() - background.getWidth()) / 2; int y = (getHeight() - background.getHeight()) / 2; g2d.drawImage(background, x, y, this); if (mouseIn && offImage != null) { g2d.drawImage(offImage, (int) offButton.getX(), (int) offButton.getY(), this); } g2d.dispose(); } } } }

The code also includes transparency test code to test the transparency API now available in Java 1.7 and Java 1.6_10+. I've used this code successfully in a number of projects, its less cumbersome then the AWT Robot "hack" and provides a live back ground, but that's a choice you need to make.

<strong>Updated</strong>

Demonstration using java.awt.Frame

<img alt="enter image description here" class="b-lazy" data-src="https://i.stack.imgur.com/bIVMa.png" data-original="https://i.stack.imgur.com/bIVMa.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" />

public class TestTransparentFrame { public static void main(String[] args) { new TestTransparentFrame(); } public TestTransparentFrame() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception exp) { } Frame frame = new Frame("Test"); frame.setUndecorated(true); setOpaque(frame, false); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setLayout(new BorderLayout()); frame.add(new ContentPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class ContentPane extends JPanel { private BufferedImage background; public ContentPane() { try { background = ImageIO.read(new File("duke.png")); } catch (IOException ex) { ex.printStackTrace(); } setOpaque(false); JButton close = new JButton("Close"); close.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { SwingUtilities.getWindowAncestor(ContentPane.this).dispose(); } }); setBorder(new LineBorder(Color.RED)); setLayout(new GridBagLayout()); add(close); } @Override public Dimension getPreferredSize() { return background == null ? new Dimension(200, 200) : new Dimension(background.getWidth(), background.getHeight()); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (background != null) { g.drawImage(background, 0, 0, this); } } } public static boolean supportsPerAlphaPixel() { boolean support = false; String version = System.getProperty("java.version"); if (version.startsWith("1.6")) { try { Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities"); support = true; } catch (Exception exp) { } } else if (version.startsWith("1.7")) { try { Class<?> winTransClass = Class.forName("java.awt.GraphicsDevice$WindowTranslucency"); Field field = winTransClass.getField("TRANSLUCENT"); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice gd = ge.getDefaultScreenDevice(); gd.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.TRANSLUCENT); Method isWindowTranslucencySupported = GraphicsDevice.class.getMethod("isWindowTranslucencySupported", winTransClass); System.out.println(isWindowTranslucencySupported); Object value = isWindowTranslucencySupported.invoke(gd, field.get(null)); if (value instanceof Boolean) { support = ((Boolean) value).booleanValue(); } } catch (Exception exp) { } } return support; } public static void setOpaque(Window window, boolean opaque) { String version = System.getProperty("java.version"); if (version.startsWith("1.6")) { try { Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities"); if (awtUtilsClass != null) { Method method = awtUtilsClass.getMethod("setWindowOpaque", Window.class, boolean.class); method.invoke(null, window, opaque); } } catch (Exception exp) { } } else if (version.startsWith("1.7")) { Color color = UIManager.getColor("Panel.background"); if (opaque) { color = new Color(color.getRed(), color.getGreen(), color.getBlue()); } else { color = new Color(color.getRed(), color.getGreen(), color.getBlue(), 0); } window.setBackground(color); } } }

Tested on Windows 7 Java 1.6 & 1.7, Mac OS 10.7.5 & 10.8.2, using JDK 1.7.0_07 & 1.6.0_37

It appears that you don't understand the window hierarchy in Java

All "windows" in Java derive from java.awt.Window.

JFrame extends Frame which extends Window.

Answer2:

Using this line, it works:

AWTUtilities.setWindowOpaque(frame, false);

Eclipse prints out a warning on this and I had to change some settings to comile it, so I guess there may be better ways. I read <a href="http://www.visualinformation.org/2009/09/transparent-application-window-in-processing/" rel="nofollow">here</a>, that this is supported since OS X 10.6 (Lion).

Recommend

  • Populating Spinner with JSON
  • C# SerialPort.Open() does not throw an exception if port is already open in Mono
  • Android displaying images dynamically
  • Adding object to database using table-per-type inheritance in Mvc 4
  • Should try-catch be avoided for known cases
  • The model item passed into the dictionary is of type A, but this dictionary requires a model item of
  • Turning String textfile into object array
  • my output parameters are always null when i use BeginExecuteNonQuery
  • Error 403 when trying to sign in to Google Game Services in android
  • How to make timer task to wait till runOnUiThread completed
  • Manually ending the IntentService worker thread
  • p:panelGrid inside p:panelGrid, how to remove borders in an outer p:panelGrid?
  • how to end the nested loop
  • how to connect to a mysql database through eclipse
  • Uploading image using SpringMVC 4.0 Multipart
  • Property file in java
  • Ajax add to cart is not adding products to the cart
  • Function insertMany() unordered: proper way to get both the errors and the result?
  • Task.IsCancelled doesn't work
  • Apache Lucene - Improving the results of Spell Checker
  • adjust iframe height based on the content
  • parsing numbers from a text file
  • Nodejs bluebird promise fails while processing image
  • How to handle empty space in url when downloading image from web?
  • Smack 4.1.0 android Roster not displaying
  • extjs4 catching the scroll event on panel
  • C++ Single function pointer for all template instances
  • How to copy styled text in JTextPane
  • Why does it draw lines in the wrong place?
  • CakePHP 2.0.4 - findBy magic methods with conditions
  • Converting a WriteableBitmap image ToArray in UWP
  • Hardware Accelerated Image Scaling in windows using C++
  • iOS: Detect app start via notification press
  • How to attach a node.js readable stream to a Sendgrid email?
  • Reading JSON from a file using C++ REST SDK (Casablanca)
  • Why value captured by reference in lambda is broken? [duplicate]
  • javascript inside java/jsp code
  • Hazelcast - OperationTimeoutException
  • RestKit - RKRequestDelegate does not exist
  • Revoking OAuth Access Token Results in 404 Not Found