I am (still) a beginner in Java, and I created a little software which contains a main frame.
I need to cover all the Desktop behind my software such as a windows 98 installing screen : (I need the black and blue screen behing, covering all the task bar etc).
In order to do this, I used GraphicsDevice which goes full screen. It is exactly what I needed :
public class Fond_noir extends JFrame {
private boolean isFullScreen = false;
private GraphicsDevice device;
public Fond_noir(int etat) {
GraphicsEnvironment env = GraphicsEnvironment
.getLocalGraphicsEnvironment();
this.device = env.getDefaultScreenDevice();
initFullScreen(etat);
}
private void initFullScreen(int etat) {
isFullScreen = device.isFullScreenSupported();
if (etat==0)
{
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
}
if (etat==1)
{
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
}
setUndecorated(isFullScreen);
setResizable(!isFullScreen);
if (isFullScreen) {
// Full-screen mode
device.setFullScreenWindow(this);
validate();
} else {
// Windowed mode
this.setExtendedState(MAXIMIZED_BOTH);
this.setVisible(true);
}
}
}
Then, I call this method in a main somewhere else, (there's no problem with this) :
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Fond_noir(0);
Choix_Langue inst = new Choix_Langue(); // main frame
inst.setLocationRelativeTo(null);
inst.setVisible(true);
} } ); }
But the problem is, that my main frame can't show-up, and it's hidden behind my fullscreen.. I'd like the opposite !
Or when I click on my main frame in my task bar (aften using the window key of my keyboard ofc..) I can only see my main frame, and the fullscreen is not showing-up with the frame
=> Is there a way to show both my frame and my GraphicsDevice ? Using "priorities" between them..?
Thanks for reading !
Use this:
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setUndecorated(true);
frame.setAlwaysOnTop(true)
Undecorated will remove the titlebars. Also instead of trying to show both the frames seperately. Add the small one to the bigger one.
bigFrame.add(smallFrame);
bigFrame.setVisible(true);
Example to show that it works:
I'm not sure you need to go full screen exclusive mode, for example, you can size a border-less frame to fit the default screen size and make it always on top to help it cover all other windows in the system and then simply use a JDialog as the primary interface to work with the user, for example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.LinearGradientPaint;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class FullScreenBackground {
public static void main(String[] args) {
new FullScreenBackground();
}
public FullScreenBackground() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
JFrame frame = new JFrame("Testing");
frame.setAlwaysOnTop(true);
frame.setUndecorated(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new BackgroundPane());
frame.setLocation(0, 0);
frame.setSize(dim);
frame.setVisible(true);
JDialog dialog = new JDialog(frame);
dialog.setContentPane(new InstallPane());
dialog.pack();
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
}
});
}
public class InstallPane extends JPanel {
public InstallPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel("<html><h1>Welcome to my fancy pancy background screen<h1></html>"), gbc);
}
}
public class BackgroundPane extends JPanel {
private BufferedImage bg;
public BackgroundPane() {
}
#Override
public void invalidate() {
super.invalidate();
bg = null;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (bg == null) {
bg = new BufferedImage(1, getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bg.createGraphics();
LinearGradientPaint lgp = new LinearGradientPaint(
new Point(0, 0),
new Point(0, getHeight()),
new float[]{0f, 1f},
new Color[]{Color.BLACK, Color.BLUE}
);
g2d.setPaint(lgp);
g2d.fillRect(0, 0, 1, getHeight());
}
g.drawImage(bg, 0, 0, getWidth(), getHeight(), this);
}
}
}
Updated
If changing all the "frames" is not hard, you could consider making the following changes to the above example...
JFrame frame = new JFrame("Testing");
frame.setAlwaysOnTop(true);
frame.setUndecorated(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new BackgroundPane());
frame.setLocation(0, 0);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setSize(dim);
// This will stop the background window from become focused,
// potentially hiding the other windows
frame.setFocusableWindowState(false);
frame.setFocusable(false);
frame.setVisible(true);
JFrame dialog = new JFrame();
// Will need to add this to each frame...
dialog.setAlwaysOnTop(true);
dialog.setContentPane(new InstallPane());
dialog.pack();
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
The other problem you might face is the fact that alwaysOnTop is platform dependent, meaning that it might behaviour differently on different platforms.
Changing extends JFrame to extends JDialog really would be a simpler and more stable change...
I found a solution with all your anwers.
Instead of using another frame I used a JWindow for the background :
public class Fond_noir extends JWindow{
Panel panel = new Panel();
public Fond_noir(int etat) {
if (etat==0)
{
setSize(2300,4000);
setLocationRelativeTo(null);
setVisible(true);
}
if (etat==1)
{
dispose();
}
panel.setBackground(Color.black);
add(panel);
}
class Panel extends JPanel{
public void paintComponent(Graphics g){
super.paintComponent(g);
}
}
}
Then while trying to change the "extends JFrame" of my main frame to "extends JDialog", it made me delete this horrible line in the code : this.setState(Frame.ICONIFIED); !!!!
It explains why I had to look for my icon all the time.. So I kept my JFrame..
So now it opens a background window AND the frame at the same time :)
Thank you everyone ! Next time I won't use that much frames.
Related
My Problem is that there's a little bar at the top of my screen which i want to remove (I want the picture to be fullscreen). I'm not sure though from which source this bar is caused.
picture
Here's my code till now:
lpane = new JLayeredPane();
lpane.setBackground(Color.BLACK);
panelBlue = new JPanel();
panelGreen = new JPanel();
frame.add(lpane);
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
frame.setUndecorated(true);
lpane.setBounds(0, 0, 1920, 1080);
BufferedImage background = null;
BufferedImage title = null;
try{
background = javax.imageio.ImageIO.read(getClass().getResource("resources/background.jpg"));
}catch(IOException ex){
sendErrorMessage("Picture couldn't be loaded"); //custom Errormessage Method
}
JLabel picLabel = new JLabel(new ImageIcon(background));
ImageIcon buttonbackground = new ImageIcon(flames);
panelBlue.add(picLabel);
panelBlue.setBounds(0, 0, 1920, 1080);
panelBlue.setOpaque(true);
frame.pack();
frame.setVisible(true);
I'm not sure if the cause is the JLabel or if it has something to do with the undecorated frame.
What's the cause and how can i remove the bar?
Thx in advance
Don't use setBounds. This is just plain wrong. The proper way is to use an appropriate LayoutManager. Additionaly, if you use pack(), using setBounds before is useless.
To put you frame in fullscreen, you can use any of the following:
frame.setExtendedState(frame.getExtendedState() & JFrame.MAXIMIZED_BOTH);
GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(frame);
See this example that illustrates this:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UnsupportedLookAndFeelException;
public class TestFullScreen {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
new TestFullScreen().initUI();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
});
}
public static class ImagePanel extends JPanel {
private ImageIcon imageIcon;
public ImagePanel(ImageIcon imageIcon) {
super();
this.imageIcon = imageIcon;
};
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(imageIcon.getImage(), 0, 0, getWidth(), getHeight(), this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(imageIcon.getIconWidth(), imageIcon.getIconHeight());
}
}
protected void initUI() throws MalformedURLException {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new ImagePanel(new ImageIcon(new URL("http://blog.timesunion.com/opinion/files/2011/10/brickwall.jpg"))));
frame.setUndecorated(true);
frame.pack();
frame.setExtendedState(frame.getExtendedState() & JFrame.MAXIMIZED_BOTH);
// GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(frame);
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();
}
});
}
}
I'm trying to create a jframe that the user can click through. I'm not looking for opacity but transparency.
I need a solution that works on all OS and not just Windows because I can't use
WindowUtils.setWindowTransparent(frame, true);
WindowUtils.setWindowAlpha(frame, 0.6f);
or
AWTUtilities.setWindowOpaque(this, false);
AWTUtilities.setWindowOpacity(this, 0.8f);
Can I accomplish this with java alone? It's ok if there is a library that I must use.
EDIT: I have my jframe undecorated and here is the code for it.
frame = new JDialog();
frame.setUndecorated(true);
frame.setVisible(true);
frame.setOpacity(Shared.opacity);
frame.setLocation(0, 0);
frame.setSize(Shared.screenWidth, Shared.screenHeight);
When I say the user can click through what I mean is that if my frame is on top but they have a window under mine, clicking on mine would bring the one under on top.
A completely transparent window can be achieved in Java 7 by using a completely transparent background color, for example...
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
The problem you will have is, that anywhere there is any kind of solid pixel (even if it is transparent), it will stop the mouse events from going beyond the window...
This means that every child component you add to the frame (that you want to be able to click through) will need to be transparent as well.
I use a similar technique for some of my utility programs and include a MouseListener on the main opaque component to make the window more visible so I can drag it if I want to it, but that's stuff for another question ;)
import java.awt.AlphaComposite;
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.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ClickThroughWindow {
public static void main(String[] args) {
new ClickThroughWindow();
}
public ClickThroughWindow() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.setAlwaysOnTop(true);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setOpaque(false);
setLayout(new GridBagLayout());
add(new JLabel("Hello"));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(getBackground());
// g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
// g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setColor(Color.BLACK);
g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
g2d.dispose();
}
}
}
You can find more details at How to Create Translucent and Shaped Windows, in particular How to Implement Per-Pixel Translucency
so I'm trying to insert an image underneath a JTextArea, but I havent had much luck, could anyone please help? Basically what I'm asking is if anybody could help make another class or subclass that does this. Heres my code:
import java.awt.*;
import javax.swing.*;
public class t{
private JFrame f; //Main frame
private JTextArea t; // Text area private JScrollPane sbrText; // Scroll pane for text area
private JButton btnQuit; // Quit Program
public t(){ //Constructor
// Create Frame
f = new JFrame("Test");
f.getContentPane().setLayout(new FlowLayout());
String essay = "Test";
// Create Scrolling Text Area in Swing
t = new JTextArea(essay, 25, 35);
t.setEditable(false);
Font f = new Font("Verdana", Font.BOLD, 12 );
t.setFont( f );
t.setLineWrap(true);
sbrText = new JScrollPane(t);
sbrText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
// Create Quit Button
btnQuit = new JButton("Quit");
btnQuit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.exit(0);
} } );
}
public void launchFrame(){ // Create Layout
// Add text area and button to frame
f.getContentPane().add(sbrText);
f.getContentPane().add(btnQuit);
// Close when the close button is clicked
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Display Frame
f.pack(); // Adjusts frame to size of components
f.setSize(450,480);
f.setResizable(false);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String args[]){
t gui = new t();
gui.launchFrame();
}
}
The basic issue is that JTextArea will paint it's background and it's text within the paintComponent.
The simplest solution is to make the JTextArea transparent and take over the control of painting the background.
This example basically fills the background with the background color, paints the image and then calls super.paintComponent to allow the text to be rendered.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TransparentTextArea {
public static void main(String[] args) {
new TransparentTextArea();
}
public TransparentTextArea() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(new CustomTextArea()));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class CustomTextArea extends JTextArea {
private BufferedImage image;
public CustomTextArea() {
super(20, 20);
try {
image = ImageIO.read(new File("/Users/swhitehead/Dropbox/MegaTokyo/Miho_Small_02.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public boolean isOpaque() {
return false;
}
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(getBackground());
g2d.fillRect(0, 0, getWidth(), getHeight());
if (image != null) {
int x = getWidth() - image.getWidth();
int y = getHeight() - image.getHeight();
g2d.drawImage(image, x, y, this);
}
super.paintComponent(g2d);
g2d.dispose();
}
}
}
Check out the Background Panel. When you add a scrollpane to the panel it will make the scrollpane, viewport and text area all non-opaque so you can see the image.
In the below example, how can I get the JPanel to take up all of the JFrame? I set the preferred size to 800x420 but it only actually fills 792x391.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BSTest extends JFrame {
BufferStrategy bs;
DrawPanel panel = new DrawPanel();
public BSTest() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout()); // edited line
setVisible(true);
setSize(800,420);
setLocationRelativeTo(null);
setIgnoreRepaint(true);
createBufferStrategy(2);
bs = getBufferStrategy();
panel.setIgnoreRepaint(true);
panel.setPreferredSize(new Dimension(800,420));
add(panel, BorderLayout.CENTER); // edited line
panel.drawStuff();
}
public class DrawPanel extends JPanel {
public void drawStuff() {
while(true) {
try {
Graphics2D g = (Graphics2D)bs.getDrawGraphics();
g.setColor(Color.BLACK);
System.out.println("W:"+getSize().width+", H:"+getSize().height);
g.fillRect(0,0,getSize().width,getSize().height);
bs.show();
g.dispose();
Thread.sleep(20);
} catch (Exception e) { System.exit(0); }
}
}
}
public static void main(String[] args) {
BSTest bst = new BSTest();
}
}
If you are having only one panel in frame and nothing else then try this:
Set BorderLayout in frame.
Add panel in frame with BorderLayout.CENTER
May be this is happening because of while loop in JPanel.(Not sure why? finding actual reason. Will update when find it.) If you replace it with paintComponent(g) method all works fine:
public BSTest() {
//--- your code as it is
add(panel, BorderLayout.CENTER);
//-- removed panel.drawStuff();
}
public class DrawPanel extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
System.out.println("W:" + getSize().width + ", H:" + getSize().height);
g2d.fillRect(0, 0, getSize().width, getSize().height);
}
}
//your code as it is.
Here's an alternative using pack instead.
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PackExample extends JFrame {
public PackExample(){
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(800,600));
panel.setBackground(Color.green);
add(panel);
pack();
setVisible(true);
}
public static void main(String[] args){
new PackExample();
}
}
This took me forever to figure out but its actually the simplest code ever.
Just create a parent panel and pass GridLayout then add your child panel like this.
JPanel parentPanel= new JPanel(new GridLyout());
JPanel childPanel= new JPanel();
parentPanel.add(childPanel);
If you want to fill the JFrame with the whole of JPanel you need to setUndecorated to true i.e. frame.setUndecorated(true);. But now you have to worry about your MAXIMIZE< MINIMIZE, and CLOSE Buttons, towards the top right side(Windows Operating System)