Pass in JFrame to change brightness? - java

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();
}
});
}
}

Related

Fullscreensize & Frame in front of it

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.

Java: Why validate don't work

I want to change the panel dynamically and as this answer show, they recommend to use the cardLayout. But I want to change the whole UI(no old button left) and cardLayout seems not so convenient. So I have the following code:
JFrame frame = new JFrame ("Key test");
MyDrawPanel1 dp1 = new MyDrawPanel1(frame);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible (true);
JPanel p = new JPanel ();
p.setLayout(new BorderLayout());
p.add(dp1,BorderLayout.CENTER);
frame.getContentPane().add(p);
frame.pack();
frame.setVisible (true);
And in the MyDrawPanel1 there is a button to change panel:
public MyDrawPanel1(final JFrame frame) {
clickButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
frame.getContentPane().removeAll();
//frame.validate();
frame.getContentPane().add(new MyDrawPanel2());
((JPanel)frame.getContentPane()).revalidate();
}
});
this.add(clickButton);
}
Edit:some more codes in MyDrawPanel1.
JButton clickButton = new JButton("click");
Image image = new ImageIcon("D:/0.jpg").getImage();
public void paintComponent (Graphics g) {
super.paintComponent(g);
g.drawImage(image, 3, 40, null);
}
public Dimension getPreferredSize() {
if (image != null) {
return new Dimension(image.getWidth(null), image.getHeight(null));
}
return super.getPreferredSize(); // default
}
But the first panel doesn't disappear and I have to minimize it to refresh it so I can see the second panel. My question is the why validate don't work and if there is any other alternatives. Thanks.
Edit:here are the pictures I snipped about the panel.(first panel):
(after clicked):
Edit:
The madProgrammer and Adarsh Singhal provide two ways to solve the problem. The first is the second the panel don't call the super.paintComponent(), so add it then it works fine (as this answer say, it is the eraser so the first panel was gone). The second is calling the frame.repaint(), but I don't understand why?
We've to use repaint() to tell the components to repaint themselves. Visualize it as your case. While revalidate is used to update the layouts. So, whenever you add/remove components dynamically, you need to call both of them.The following written code displays a JFrame set to CardLayout to draw Red dp1(JPanel) completely on JFrame. On dp1, there is a Jbutton. If you click that button, dp1 will be removed & dp2(JPanel) will be drawn. dp2 is Green to distinguish changes. It seems you've forgotten repaint().
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MyFrame extends JFrame{
JButton button;
private static MyFrame frame;
public MyFrame(){
this.setSize(400, 400);
this.setLayout(new CardLayout());
this.setLocationRelativeTo(null);
JPanel dp1 = new JPanel();
dp1.setBackground(Color.RED);
add(dp1);
button = new JButton("Click me to remove dp1 & draw dp2");
dp1.add (button);
JPanel dp2 = new JPanel ();
dp2.setBackground(Color.GREEN);
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
frame.getContentPane().remove(dp1);
frame.add(dp2);
frame.revalidate();
frame.repaint();
}});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible (true);
}
public static void main(String[] args) {
frame = new MyFrame();
}
}

How to change default operating system's frame around swing application

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.

Drawing a Huge Panel inside a ScrollPane through Java

My problem is I want to draw a huge Panel but its not possible to see this panel in a small size frame so i supposed to use ScrollPane and I used it..
But by scrolling clashes occurs so i cant see any panel there .i just want to fix it
Please anyone see my code and run it and help to solve the problem
import java.awt.*;
import javax.swing.*;
public class Swing{
JFrame frame;
Panel panel;
public static void main(String [] args){
Swing a = new Swing();
a.go();
}
public void go(){
frame = new JFrame();
panel = new Panel();
panel.setPreferredSize(new Dimension(5000, 5000));
JScrollPane scroll = new JScrollPane(panel);
frame.add(scroll);
frame.pack();
frame.setVisible(true);
}
class Panel extends JPanel{
public void paintComponent(Graphics g){
Graphics2D a = (Graphics2D)g;
a.setColor(Color.RED);
a.drawLine(50, 50, 5000, 5000);
}
}
}
Thanks in advance!
Always make sure to call super.paintComponent(g); to redraw the rest of the component. Otherwise these types of painting artifacts are seen.
import java.awt.*;
import javax.swing.*;
public class Swing{
JFrame frame;
Panel panel;
public static void main(String [] args){
Swing a = new Swing();
a.go();
}
public void go(){
frame = new JFrame();
panel = new Panel();
panel.setPreferredSize(new Dimension(5000, 5000));
JScrollPane scroll = new JScrollPane(panel);
frame.add(scroll);
frame.pack();
frame.setVisible(true);
}
class Panel extends JPanel{
public void paintComponent(Graphics g){
super.paintComponent(g); // VERY IMPORTANT!
Graphics2D a = (Graphics2D)g;
a.setColor(Color.RED);
a.drawLine(50, 50, 5000, 5000);
}
}
}

Class - Graphics - drawString()

I'm trying to display a message in a JPanel.
I've used the drawString() function of the Graphics class.
Here's my code :
public class Frame {
JFrame frame;
JPanel panel;
Graphics graph;
Frame() {
frame = new JFrame();
panel = new JPanel();
frame.setTitle("My wonderful window");
frame.setSize(800, 600);
frame.ContentPane(panel);
frame.setVisible(true);
}
void displayMessage(String message) {
graph = new Graphics();
graph.drawString(message, 10, 20);
}
}
I've this error :
error: Graphics is abstract; cannot be instantiated
Override the JPanel's paintComponent(Graphics g) method. IN the method you have access to a valid Graphics instance. The method called on each paint.
But may be it's better to add a JLabel to the panel. The label initially has no text and when you have a message just call setText(messageText) of the label.
You should create subclasses for your JFrame and JPanel, and override the methods you want. You could try something like:
package test;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Frame extends JFrame {
public static final String message = "HELLO WORLD!!!";
public class Panel extends JPanel {
public void paintComponent(Graphics graph) {
graph.drawString(message, 10, 20);
}
}
public Frame() {
Panel panel = new Panel();
this.setTitle("My wonderful window");
this.setSize(800, 600);
this.setContentPane(panel);
this.setVisible(true);
}
public static void main(String[] args) {
new Frame();
}
}
Also, there are a lot of great books/tutorials about this. You should read one.
Edit:
You should also read about all the JComponents (JButtons, JLabels...). They're rather useful.

Categories