For example instead of the default operating system container around the application you could have something custom like this swing project below.
You can use a transparent image on a undecorated frame with a transparent background:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TransparentImageFrame
{
private static void createAndShowUI()
{
JLabel label = new JLabel( new ImageIcon("...") );
label.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e)
{
if (e.getClickCount() == 2)
{
System.exit(0);
}
}
});
JFrame frame = new JFrame("Image Frame");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add( label );
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
The mouse will only respond to non-opaque pixels in whatever image you use.
The host OS owns the frame decorations, but you can Create Translucent and Shaped Windows and use Frame#setUndecorated(), as shown here.
Related
I have got a frame in which sometimes a dialog is opened. I would like this dialog to be attached to the existing frame, so for example when I drag that frame the opened dialog follows it. I have heard that this might be possible to achieve using GlassPane but I need some hints. Right now, when I open a new dialog and set its location relative to frame it looks like this:
I would like the "testDialog" to appear next to the frame attached to its upper-right corner.
When I drag the "test" frame, the "testDialog" follows it.
Here is a working example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Example {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
showGUI();
}
});
}
public static void showGUI() {
final JFrame frame=new JFrame("test");
JButton open=new JButton("Open new dialog");
open.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("test");
JDialog dialog=new JDialog((Frame)null,"testdialog");
dialog.setPreferredSize(new Dimension(200,300));
dialog.getContentPane().add(new JLabel("testlabel"));
dialog.pack();
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
}
});
frame.setLayout(new FlowLayout());
frame.getContentPane().add(open);
frame.getContentPane().add(new JLabel("test"));
frame.setLocationRelativeTo(null);
frame.setPreferredSize(new Dimension(400, 200));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
I am trying to make a popup over my JFrame in Swing. I have made it so that the popup will be layered over the old JFrame and disable the old one by passing in the JFrame and then .disable(). However, i am also trying to make the frame behind darken to show that it is disabled.
I found this:
stackoverflow - Change brightness of JFrame
But how do i use it to lower the brightness of the JFrame that i have as a parameter just before i disable it? Something like darken(frame) and it lowers it using the function darken(JFrame frame). Thanks!
In fact, I'm going to make my comment an answer:
To show a window over another window, and disable the lower window, make the upper window a modal JDialog, and pass the lower window in as its parent.
One way to dim a top-level window is to get its glass pane, set it visible, and draw a semi-opaque grey color over it.
Here's my test of concept code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Dialog.ModalityType;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class DimView {
protected static final Color GP_COLOR = new Color(0, 0, 0, 30);
private static void createAndShowGui() {
final JFrame frame = new JFrame("DimView");
final JPanel glassPanel = new JPanel() {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(GP_COLOR);
g.fillRect(0, 0, getWidth(), getHeight());
};
};
glassPanel.setOpaque(false);
frame.setGlassPane(glassPanel);
JPanel mainPanel = new JPanel();
mainPanel.setPreferredSize(new Dimension(400, 400));
mainPanel.setBackground(Color.pink);
mainPanel.add(new JButton(new AbstractAction("Push Me") {
#Override
public void actionPerformed(ActionEvent evt) {
glassPanel.setVisible(true);
JDialog dialog = new JDialog(frame, "Dialog",
ModalityType.APPLICATION_MODAL);
dialog.add(Box.createRigidArea(new Dimension(200, 200)));
dialog.pack();
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
glassPanel.setVisible(false);
}
}));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
The problem is when I run the code below, I see a white splash on my screen for about maybe 100ms which is extremely annoying:
import java.awt.*;
import javax.swing.*;
public class MyPanel extends JPanel {
public MyPanel() {
this.setBackground(Color.black);
JTextArea jtext = new JTextArea(10, 20);
jtext.setBackground(Color.black);
jtext.setForeground(Color.white);
jtext.setText("some stuff here");
add(jtext);
add(new JButton("some button"));
// TODO: gui elements
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("MyPanel");
frame.getContentPane().add(new MyPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
}
});
}
}
My entire work setup is in dark theme. Equivilant code written in C++ with Qt does not show any white splashs on the same system. I'm using Ubuntu 12.04 and Intel HD Graphics 3000, java version "1.7.0_45".
Please let me know how this can be fixed.
I googled this problem but all I found was: "how to create splash screen in java?" which what I'm trying to avoid.
update: solution: I'm not sure why this works:
I extended MyPanel to JFrame and put most of the functions there. then in the run() invoked it and set visible to true.
here is the code:
import java.awt.*;
import javax.swing.*;
public class MyPanel extends JFrame {
public MyPanel() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setBackground(Color.black);
JTextArea jtext = new JTextArea(10, 20);
jtext.setBackground(Color.black);
jtext.setForeground(Color.white);
jtext.setText("some stuff here");
getContentPane().add(jtext);
// TODO: gui elements
setExtendedState(JFrame.MAXIMIZED_BOTH);
setSize(350, 250);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MyPanel mypanel = new MyPanel();
mypanel.setVisible(true);
}
});
}
}
I did not see the 'white flash' here, but try this altered code that calls pack() on the frame.
import java.awt.*;
import javax.swing.*;
public class MyPanel extends JPanel {
public MyPanel() {
this.setBackground(Color.black);
JTextArea jtext = new JTextArea(10, 20);
jtext.setBackground(Color.black);
jtext.setForeground(Color.white);
jtext.setText("some stuff here");
add(jtext);
add(new JButton("some button"));
// TODO: gui elements
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("MyPanel");
frame.getContentPane().add(new MyPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.pack();
frame.setVisible(true);
}
});
}
}
Although it looks normal to me on Ubuntu 12.04 / Intel Iris Pro 5200 / Java 6, I can see the effect by running in a slowed emulator. Setting the frame's background to black before setVisible() seems to help.
frame.setBackground(Color.black);
What's is the proper way to change to background of JFrame with Sea-Glass Look and Feel, so far I tried both :
frame.getContentPane().setBackground(Color.blue);
and
JPanel x = new JPanel();
x.setBackground(Color.red);
frame.setContentPane(x);
But it didn't make any effect :
import javax.swing.*;
import com.seaglasslookandfeel.*;
import java.awt.*;
import java.awt.Color.*;
public class BORDER_TEST {
public static void main(String[] a){
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel("com.seaglasslookandfeel.SeaGlassLookAndFeel");
JFrame frame = new JFrame();
JPanel x = new JPanel();
x.setBackground(Color.red);
frame.setContentPane(x);
//frame.getContentPane().setBackground(Color.blue);
frame.setPreferredSize(new Dimension(900,350));
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
Seaglass Look and Feel is based on Nimbus, then you have to accepting its built-in themes or set Colors for Nimbus programatically
I was able to hide the the maximize icon by setting setResizable(false), how can achieve the same for the minimize icon?
Here is the way, how to remove min/max buttons from JFrame
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class JFrameTest extends JDialog {
public JFrameTest(JFrame frame, String str) {
super(frame, str);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
System.exit(0);
}
});
}
public static void main(String[] args) {
JFrameTest frame = new JFrameTest(new JFrame(), "Title");
JPanel panel = new JPanel();
panel.setSize(200, 200);
JLabel lbl = new JLabel("JFrame without max/min");
panel.add(lbl);
frame.add(panel);
frame.setSize(400, 400);
frame.setVisible(true);
}
}
But it's really nasty to users and could be walk arounded by key shortcuts etc.
Check the example Specifying Window Decorations