Can't Transparent and Undecorated Jframe in Jdk7 When Enabling Nimbus

Can't transparent and undecorated JFrame in JDK7 when enabling nimbus

  • accepted answer by @JamesCherrill on Daniweb,

  • 1st. Top-Level Container created on InitialThread must be decorated and isDisplayable(), then after is possible whatever with rest of

  • problably required short delaying by Swing Timer

.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class DemoWindows implements ActionListener {

public static void main(String[] args) {
// create a new demo, and update it every 50 mSec
new Timer(30, new DemoWindows()).start();
}
int phase = 0; // demo runs a number of consecutive phases
int count = 0; // each of which takes a number of timesteps
JFrame window1 = new JFrame("Java windows demo");
JLabel text1 = new JLabel("<HTML><H1>Hello" + "<BR>Everyone");
// "<HTML><H1>This is a demo of some of the effects"
// + "<BR>that can be achieved with the new Java"
// + "<BR>transparent window methods</H1>"
// + "<BR>(requires latest version of Java)");
JFrame window2 = new JFrame("Java windows demo");
JLabel text2 = new JLabel("<HTML><center>Java<BR>rocks");
JButton button = new JButton("Whatever");
int w, h, r, x, y; // parameters of iris circle

DemoWindows() {
// build and diplay the windows
window1.add(text1);
window1.pack();
window1.setLocationRelativeTo(null);
window1.setVisible(true);
window2.setUndecorated(true);
window2.setBackground(new Color(0, 0, 0, 0)); // alpha <1 = transparent
window2.setOpacity(0.0f);
text2.setFont(new Font("Arial", 1, 60));
text2.setForeground(Color.red);
window2.add(text2);
window2.add(button, BorderLayout.SOUTH);
window2.pack();
window2.setLocationRelativeTo(null);
window2.setVisible(true);
// parameters of the smallest circle that encloses window2
// this is the starting pouint for the "iris out" effect
w = window2.getWidth();
h = window2.getHeight();
r = (int) Math.sqrt(w * w + h * h) / 2; // radius
x = w / 2 - r; // top left coordinates of circle
y = h / 2 - r;
}

@Override
public void actionPerformed(ActionEvent e) {
try {// L&F changed on Runtime, repeatly fired from Swing Timer
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (ClassNotFoundException ex) {
Logger.getLogger(DemoWindows.class.getName()).log(Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
Logger.getLogger(DemoWindows.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(DemoWindows.class.getName()).log(Level.SEVERE, null, ex);
} catch (UnsupportedLookAndFeelException ex) {
Logger.getLogger(DemoWindows.class.getName()).log(Level.SEVERE, null, ex);
}
SwingUtilities.updateComponentTreeUI(window2);
// called by timer 20 times per sec
// goes thru a number of phases, each a few seconds long
switch (phase) {
case 0: { // initial pause
if (++count > 50) {
phase = 1; // go to next phase
count = 0;
}
break;
}
case 1: { // fade in
if (++count < 100) {
window2.setOpacity(0.01f * count);
} else {
phase = 2; // go to next phase
count = 0;
}
break;
}
case 2: { // move
if (++count < 160) {
if (count < 28 || count > 80) {// pause for best effect
window2.setLocation(window2.getX() + 1, window2.getY() + 1);
}
} else {
phase = 3; // go to next phase
count = 0;
}
break;
}
case 3: {// iris out
if (++count < r) {
Shape shape = new Ellipse2D.Double(
x + count, y + count, 2 * (r - count), 2 * (r - count));
window2.setShape(shape);
} else {
phase = 99; // go to final (exit) phase
}
break;
}
case 99:
System.exit(0);
}
}
}

Java undecorated jFrame not working on Windows

In the constructor, you are calling setDefaultLookAndFeelDecorated(true). This does not affect the first frame (as that is already created), but influences all the subsequent ones, that then get the default decorations the current window manager defines - which might be different on Mac and on Win.

Simply removing the call should resolve the problem.

Is The Java Tutorials Translucent Window example giving trouble to those playing with jdk7?

Right from the JavaDocs for java.awt.frame.setOpacity() in JDK7:

The following conditions must be met in order to set the opacity value less than 1.0f:

  • The TRANSLUCENT translucency must be supported by the underlying system
  • The window must be undecorated (see setUndecorated(boolean) and Dialog.setUndecorated(boolean))
  • The window must not be in full-screen mode (see GraphicsDevice.setFullScreenWindow(Window))

If the requested opacity value is less than 1.0f, and any of the above conditions are not met, the window opacity will not change, and the IllegalComponentStateException will be thrown.

The behavior that you are seeing is documented and is expected behavior.

how to set semi-transparent jframe when submit button is clicked?

Unfortunately I think there's no way to keep the system window decoration, you will probably have to go with the default one. Since I'm not 100% sure if you want to toggle the opacity of the whole frame or just the frame's background, I've included both functions in my example. (mKorbels answer help you more if you don't want to have a decoration)

Code:

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToggleButton;

public class TransparentExample extends JFrame {

public TransparentExample() {

super("TransparentExample");
Color defaultBackground = getBackground();
float defaultOpacity = getOpacity();

JToggleButton button1 = new JToggleButton("Toggle background transparency");
button1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (button1.isSelected()) {
setBackground(new Color(defaultBackground.getRed(), defaultBackground.getGreen(),
defaultBackground.getBlue(), 150));
} else {
setBackground(defaultBackground);
}
}
});

JToggleButton button2 = new JToggleButton("Toggle opacity of whole frame");
button2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dispose();
if (button2.isSelected()) {
setOpacity(0.55f);
} else {
setOpacity(defaultOpacity);
}
setVisible(true);
}
});

getContentPane().setLayout(new FlowLayout());
getContentPane().add(button1);
getContentPane().add(button2);
setSize(800, 600);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame.setDefaultLookAndFeelDecorated(true);
TransparentExample frame = new TransparentExample();
frame.setVisible(true);
}
});
}

}

Picture of frame with no togglebutton selected:
Sample Image

Picture of frame with the first togglebutton selected:
Sample Image

Picture of frame with the second togglebutton selected:
Sample Image

Setting the JFrame background transparent making PopupMenu blank

Background:
I'm not sure why using transparent / semi-transparent backgrounds causes problems with heavyweight popups and how they paint, but it does -- regarless of whether or not you use AWTUtilities.setWindowOpaque(window, false) or frame.setBackground(new Color(0, 0, 0, 0)).

The HeavyWeightPopups get created when a popup can't fit all the way inside the target Window. So +User2280704 your problem also presents if you click at the very bottom of your window. LightWeightPopups do not have this problem -- hence, menus work in the middle of your window.

Also, interesting to note, typically the menu will render fine the first time, just not the following times.

Answer:
I've come up with a workaround that invokes a repaint after any popups display. Simply invoke the following code when you launch your application.

PopupFactory.setSharedInstance(new PopupFactory() 
{
@Override
public Popup getPopup(Component owner, final Component contents, int x, int y) throws IllegalArgumentException
{
Popup popup = super.getPopup(owner, contents, x, y);
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
contents.repaint();
}
});
return popup;
}
});

Java / Swing - Creating a notification JFrame, and the error The frame is displayable

  • +1 thanks for this thread, your code solved quite correctly undecorated conatiner, everything is about correct ordering of methods (wooolaaa we are back to Java_1.4.2 edges)

  • but bug still is there, isn't possible to create decorated JFrame with changed Look And Feel

  • based on proper ordering of methods

Sample Image

import java.awt.*;
import javax.swing.*;

public class TranslucentWindow extends JFrame {

private static final long serialVersionUID = 1L;

public TranslucentWindow() {
super("Test translucent window");
setLayout(new FlowLayout());
add(new JButton("test"));
add(new JCheckBox("test"));
add(new JRadioButton("test"));
add(new JProgressBar(0, 100));
JPanel panel = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
private static final long serialVersionUID = 1L;

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(0, 0, getWidth(), getHeight());
}
};
panel.add(new JLabel("Very long textxxxxxxxxxxxxxxxxxxxxx "));
add(panel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setUndecorated(true);
pack();
setLocationRelativeTo(null);
setOpacity(0.70f);
}

public static void main(String[] args) {
try {
for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
//JFrame.setDefaultLookAndFeelDecorated(true);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Window w = new TranslucentWindow();
w.setVisible(true);
}
});
}
}


Related Topics



Leave a reply



Submit