Set JPanel background transparent, setOpaque() doesn't let me paint - java

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Tetris extends JFrame {
public Tetris() {
add(new GamePanel());
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
setSize(800, 600);
setVisible(true);
setLocationRelativeTo(null);
setTitle("Tetris");
}
public class GamePanel extends JPanel {
public GamePanel(){
TetrisBoard tetraBoard= new TetrisBoard();
GridBagLayout layout= new GridBagLayout();
this.setLayout(layout);
GridBagConstraints c = new GridBagConstraints();
c.gridx = 2;
c.gridy = 1;
c.ipadx = 190;
c.ipady = 390;
c.insets.left= 360;
layout.setConstraints(tetraBoard, c);
this.add(tetraBoard);
setBackground(Color.WHITE);
}
#Override
public void paint(Graphics g){
super.paint(g);
g.setFont(new Font("Birth Std", Font.PLAIN, 12));
g.setColor(Color.LIGHT_GRAY);
g.drawString("200", 36, 63);
g.drawString("200", 36, 88);
g.drawString("200", 36, 114);
}
}//GamePanel class
public class TetrisBoard extends JPanel implements Runnable{
private Thread animator= new Thread(this);
private final int DELAY= 50;
public TetrisBoard(){
setFocusable(true);
//setBackground(Color.WHITE);
setDoubleBuffered(true);
//this.setBackground(Color.BLACK);
setOpaque(false);
}
#Override
public void addNotify() {
super.addNotify();
animator = new Thread(this);
animator.start();
}//addNotify
#Override
public void paint (Graphics g){
super.paint(g);
g.drawRect (20, 30, 130, 50);
}//paint
#Override
public void run() {
long beforeTime, timeDiff, sleep;
beforeTime = System.currentTimeMillis();
while (true) {
repaint();
timeDiff = System.currentTimeMillis() - beforeTime;
sleep = DELAY - timeDiff;
if (sleep < 0)
sleep = 2;
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
System.out.println("interrupted");
}
beforeTime = System.currentTimeMillis();
}
}
}//TetrisBoard class
public static void main(String[] args) {
Tetris t = new Tetris();
}
}
With this code the result is that it doesn't paint anything at all. I just want the background to be transparent not the images painted over the background, but it looks like the paint method doesn't paint if I setOpaque(false).
Edit: as requested I posted a simple code, TetraBoard is added to the GamePanel (using that GridBagLayout), and GamePanel is added to the frame, those 3 classes are separate files. I want TetraBoard to have a transparent background, so that I can see the background of GamePanel, but what I paint on tetraboard must be visible. If I setOpaque(false), TetraBoard is transparent, but it set on transparent everything I paint on it.

Edit: Assuming I understand what you're trying to do, replace the following line in the TetrisBoard constructor:
setOpaque(false);
with:
setBackground(new Color(0,0,0,0));

For example:
JPanel p = new JPanel() {
#Override
public void paintComponent(Graphics g) { // as suggested Andrew
g.setColor(Color.RED);
g.drawArc(0, 0, 100, 100, 0, 360); // arc will be painted on transparent bg
}
};
p.setBackground(new Color(0, 0, 0, 0)); // as suggested Perry
...
So, you have to do two actions:
1) override paintComponent(Graphics g) of JPanel
2) and set bg color to transparent: new Color(0, 0, 0, 0)

Related

Transparent JFrame doesn't clear on repaint

When I try to repaint a transparent window, and draw a rectangle on it, the previous rectangle will stay. The goal is to select an area on your screen by clicking and moving your mouse. It'll look like this if you move your mouse for a while
By removing the transparency it works just fine.
I tried everything I could find on Stack Overflow about this topic, But I wasn't able to get it working on both Windows and Linux.
Main class
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
public class Main {
private JFrame frame;
private boolean pressing = false;
private boolean selected = false;
private ScreenSelectPanel p;
public Main() {
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame = new JFrame("ScreenSelection");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(dim);
frame.setUndecorated(true);
frame.setContentPane(p = new ScreenSelectPanel());
registerListeners();
frame.getContentPane().setBackground(new Color(255, 255, 255, 0));
frame.setBackground(new Color(255, 255, 255, 0));
frame.setLayout(new BorderLayout());
frame.setAlwaysOnTop(true);
frame.setVisible(true);
}
private void registerListeners() {
p.setFocusable(true);
p.requestFocusInWindow();
p.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
if (selected)
return;
setLoc(e);
p.repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
if (selected)
return;
setLoc(e);
if (!pressing)
setStartLoc(e);
p.repaint();
}
});
p.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
setLoc(e);
setStartLoc(e);
p.repaint();
}
#Override
public void mouseEntered(MouseEvent e) {
setLoc(e);
setStartLoc(e);
p.repaint();
}
});
}
public void setStartLoc(MouseEvent e) {
p.mouseStartX = e.getX();
p.mouseStartY = e.getY();
}
public void setLoc(MouseEvent e) {
p.mouseX = e.getX();
p.mouseY = e.getY();
}
public static void main(String[] args) {
new Main();
}
}
ScreenSelectPanel class
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
public class ScreenSelectPanel extends JPanel {
public int mouseX = 0;
public int mouseY = 0;
public int mouseStartX = 0;
public int mouseStartY = 0;
private Color borderColor;
public ScreenSelectPanel() {
setOpaque(false);
borderColor = Color.BLACK;
}
public void setBorderColor(Color c) {
this.borderColor = c;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(borderColor);
Rectangle rect = new Rectangle();
rect.setFrameFromDiagonal(new Point2D.Float(mouseStartX, mouseStartY), new Point2D.Float(mouseX, mouseY));
Stroke dashed = new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{9}, 0);
g2d.setStroke(dashed);
g2d.drawRect(rect.x, rect.y, rect.width, rect.height);
g2d.dispose();
}
}
Thanks :)
You can't use transparency with Swing components. A transparent background causes these types of painting problems. A Swing component is either opaque or non-opaque.
Check out Backgrounds With Transparency for more information on this problem. However in this cause it is not the problem because you are trying to use full transparency on the Swing panel.
When I try to repaint a transparent window, and draw a rectangle on it, the previous rectangle will stay.
The code you posted does anything (at least on Windows). When you set a frame to be completely transparent then the MouseEvents are no longer handled by Swing and instead are handled by the application below the frame.
I made the following changes to your code and it seems to work for me:
//frame.getContentPane().setBackground(new Color(255, 255, 255, 0));
//frame.setBackground(new Color(255, 255, 255, 0));
frame.setBackground(new Color(255, 255, 255, 10));

Java color changing Graphics with Timer

I want to draw a disc that changes colors twice a second. The disk is drawn on a DrawPanel which extends a JPanel and in the main method the DrawPanel is added to a frame.
For the colorchanging I use a timer which works when I'm trying to change the background of the DrawPanel in the main method (what i commented out).
Can someone tell me why it doesn't work for the Graphics g object or any other suggestions?
I just copied the code from the main method and added it into the paintComponent() method, but here it doesn't work.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class DrawPanel extends JPanel{
public GridBagLayout gbl;
//position and dimension
int x = 0, y = 0, width = 200, height = 200;
public DrawPanel(){
repaint();
}
public DrawPanel(GridBagLayout gridBagLayout) {
this.gbl = gridBagLayout;
}
public void paintComponent(Graphics g){
//Overwriting of old picture
super.paintComponent(g);
ActionListener action = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Random gen = new Random();
Color color = new Color(gen.nextInt(256), gen.nextInt(256), gen.nextInt(256));
//Draw color disk
g.setColor(color);
g.fillArc(x, y, width, height, 0, 360);
}
};
Timer t = new Timer(500, action);
t.setRepeats(true);
t.setInitialDelay(0);
t.start();
//Draw boundary of circle
g.setColor(Color.BLACK);
g.drawArc(x, y, width, height, 0, 360);
}
public static void main(String[] args) {
final JFrame frame = new JFrame();
frame.setSize(300, 300);
final DrawPanel panel = new DrawPanel();
panel.setOpaque(true);
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
// ActionListener action = new ActionListener() {
// #Override
// public void actionPerformed(ActionEvent e) {
// Random gen = new Random();
// Color color = new Color(gen.nextInt(256), gen.nextInt(256), gen.nextInt(256));
// panel.setBackground(color);
// }
// };
//
// Timer t = new Timer(500, action);
// t.setRepeats(true);
// t.setInitialDelay(0);
// t.start();
}
}
The Graphics object is transient, so you should not cache it even if the compiler allows that. Instead establish the timer in the constructor of the class, set the BG of the panel, then call for a repaint. E.G.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;
public class DrawPanel extends JPanel {
Random gen = new Random();
//position and dimension
int x = 0, y = 0, width = 200, height = 200;
Color drawColor = Color.BLACK;
public DrawPanel() {
repaint();
ActionListener action = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Color color = new Color(gen.nextInt(256), gen.nextInt(256), gen.nextInt(256));
//Draw color disk
drawColor = color;
DrawPanel.this.repaint();
}
};
Timer t = new Timer(500, action);
t.setRepeats(true);
t.setInitialDelay(0);
t.start();
}
#Override
public void paintComponent(Graphics g) {
//Overwriting of old picture
super.paintComponent(g);
//Draw boundary of circle
g.setColor(drawColor);
g.drawArc(x, y, width, height, 0, 360);
}
public static void main(String[] args) {
final JFrame frame = new JFrame();
frame.setSize(300, 300);
final DrawPanel panel = new DrawPanel();
panel.setOpaque(true);
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Graphics objects are only valid for that one draw
It would be better to instead to tell the JPanel to change it's current color (with a variable) and then tell it to repaint
Add variable discColor to your JPanel
Change your drawing code to not use timers and instead make it simple, just draw the disc based off of discColor
With a timer, update the discColor variable and then call the panel's repaint() method

Java window doesn't repaint properly until I resize the window manually

I am using a quite basic setup with a class extending JPanel, which I add to a JFrame.
import java.awt.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.event.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.*;
import java.io.*;
import javax.imageio.ImageIO;
public class PinTestMCVE extends JPanel implements ActionListener{
BufferedImage loadedImage;
JButton calcButton;
public static void main(String[] args) {
new PinTestMCVE();
}
public PinTestMCVE() {
loadedImage = getTestImage();
JPanel toolbarPanel = new JPanel();
calcButton = new JButton("calcButton...");
toolbarPanel.add(calcButton);
calcButton.addActionListener(this);
JFrame jf = new JFrame();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.getContentPane().setLayout(new BorderLayout());
jf.getContentPane().add(toolbarPanel, BorderLayout.NORTH);
jf.getContentPane().add(this, BorderLayout.CENTER);
jf.setSize(1250, 950);
jf.setVisible(true);
}
public void paintComponent(Graphics g) {
g.drawImage(loadedImage, 0, 0, this);
}
public void actionPerformed(ActionEvent e) {
System.out.println("ActionEvent " + e.getActionCommand());
if(e.getSource().equals(calcButton)){
this.repaint();
}
}
//Please ignore the inner workings of this
public static BufferedImage getTestImage(){
BufferedImage image = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
g2d.setPaint(Color.GRAY);
g2d.fillRect ( 0, 0, image.getWidth(), image.getHeight() );
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(Color.gray);
int x = 5;
int y = 7;
GradientPaint redtowhite = new GradientPaint(x, y, Color.red, 200, y, Color.blue);
g2d.setPaint(redtowhite);
g2d.fill(new RoundRectangle2D.Double(x, y, 200, 200, 10, 10));
return image;
}
}
What happens is that INITIALLY the window is painted properly, but once paintComponent is called, a strip of the old image (with the same height as the toolbar panel) is visible below the newly painted images - similar to playing card sticking out from a deck. But then, if I manually resize the window by for instance dragging the border, the background is grayed out as it should.
What is going on and how do I fix this?
As outlined here, you need to pack() the frame before calling setVisible(). You can override getPreferredSize() to specify a suitable initial Dimension. Also consider using a Border. See also Initial Threads.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.*;
public class PinTestMCVE extends JPanel implements ActionListener{
private static final int SIZE = 200;
BufferedImage loadedImage;
JButton calcButton;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new PinTestMCVE();
}
});
}
public PinTestMCVE() {
loadedImage = getTestImage();
JPanel toolbarPanel = new JPanel();
calcButton = new JButton("calcButton...");
toolbarPanel.add(calcButton);
calcButton.addActionListener(this);
JFrame jf = new JFrame();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(toolbarPanel, BorderLayout.NORTH);
jf.add(this, BorderLayout.CENTER);
jf.pack();
jf.setLocationRelativeTo(null);
jf.setVisible(true);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(SIZE, SIZE);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(loadedImage, 0, 0, this);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("ActionEvent " + e.getActionCommand());
if(e.getSource().equals(calcButton)){
this.repaint();
}
}
//Please ignore the inner workings of this
public static BufferedImage getTestImage(){
BufferedImage image = new BufferedImage(SIZE, SIZE, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
g2d.setPaint(Color.GRAY);
g2d.fillRect ( 0, 0, image.getWidth(), image.getHeight() );
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(Color.gray);
GradientPaint redtowhite = new GradientPaint(5, 5, Color.red, SIZE, 5, Color.blue);
g2d.setPaint(redtowhite);
g2d.fill(new RoundRectangle2D.Double(5, 5, SIZE - 10, SIZE - 10, 10, 10));
return image;
}
}

How to add real-time date and time into a JFrame component e.g. "status bar"?

Like the one we add into the corner of presentation slides.
I already have SwingX library added and working, in case that could help with something.
Basically, you want to use a JLabel for displaying the date/time, a javax.swing.Timer set to a regular interval to update the label and a DateFormat instance to format the date value...
public class PlaySchoolClock {
public static void main(String[] args) {
new PlaySchoolClock();
}
public PlaySchoolClock() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new ClockPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ClockPane extends JPanel {
private JLabel clock;
public ClockPane() {
setLayout(new BorderLayout());
clock = new JLabel();
clock.setHorizontalAlignment(JLabel.CENTER);
clock.setFont(UIManager.getFont("Label.font").deriveFont(Font.BOLD, 48f));
tickTock();
add(clock);
Timer timer = new Timer(500, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
tickTock();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.setInitialDelay(0);
timer.start();
}
public void tickTock() {
clock.setText(DateFormat.getDateTimeInstance().format(new Date()));
}
}
}
This example uses a time interval of half a second. The main reason for this is I don't go to the trouble of trying to calculate how far we are away from the next second when we set up the initial delay. This ensures that we are always up-to-date
The next question is to ask "why?" This kind of setup is relatively expensive, with the timer firing every half second (to catch any edge cases) and updating the screen, when most OS's actually have a date/time already on the screen...IMHO
I created a JStatusBar from many nested JPanels. I was surprised at how many JPanels it took to create a status bar.
JPanels. JPanels everywhere.
Here's the test GUI.
And here's the JStatusBar class. The status bar has a leftmost status update area. On the right, you can add as many status areas as you want, with a separator bar. The only limit is the width of the status bar.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JPanel;
public class JStatusBar extends JPanel {
private static final long serialVersionUID = 1L;
protected JPanel leftPanel;
protected JPanel rightPanel;
public JStatusBar() {
createPartControl();
}
protected void createPartControl() {
setLayout(new BorderLayout());
setPreferredSize(new Dimension(getWidth(), 23));
leftPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 5, 3));
leftPanel.setOpaque(false);
add(leftPanel, BorderLayout.WEST);
rightPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING, 5, 3));
rightPanel.setOpaque(false);
add(rightPanel, BorderLayout.EAST);
}
public void setLeftComponent(JComponent component) {
leftPanel.add(component);
}
public void addRightComponent(JComponent component) {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEADING, 5, 0));
panel.add(new SeparatorPanel(Color.GRAY, Color.WHITE));
panel.add(component);
rightPanel.add(panel);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int y = 0;
g.setColor(new Color(156, 154, 140));
g.drawLine(0, y, getWidth(), y);
y++;
g.setColor(new Color(196, 194, 183));
g.drawLine(0, y, getWidth(), y);
y++;
g.setColor(new Color(218, 215, 201));
g.drawLine(0, y, getWidth(), y);
y++;
g.setColor(new Color(233, 231, 217));
g.drawLine(0, y, getWidth(), y);
y = getHeight() - 3;
g.setColor(new Color(233, 232, 218));
g.drawLine(0, y, getWidth(), y);
y++;
g.setColor(new Color(233, 231, 216));
g.drawLine(0, y, getWidth(), y);
y++;
g.setColor(new Color(221, 221, 220));
g.drawLine(0, y, getWidth(), y);
}
}
The separator bar is yet another JPanel.
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class SeparatorPanel extends JPanel {
private static final long serialVersionUID = 1L;
protected Color leftColor;
protected Color rightColor;
public SeparatorPanel(Color leftColor, Color rightColor) {
this.leftColor = leftColor;
this.rightColor = rightColor;
setOpaque(false);
}
#Override
protected void paintComponent(Graphics g) {
g.setColor(leftColor);
g.drawLine(0, 0, 0, getHeight());
g.setColor(rightColor);
g.drawLine(1, 0, 1, getHeight());
}
}
And finally, the simulator class that shows you how to use the JStatusBar.
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class StatusBarSimulator implements Runnable {
protected TimerThread timerThread;
#Override
public void run() {
JFrame frame = new JFrame();
frame.setBounds(100, 200, 400, 200);
frame.setTitle("Status Bar Simulator");
Container contentPane = frame.getContentPane();
contentPane.setLayout(new BorderLayout());
JStatusBar statusBar = new JStatusBar();
JLabel leftLabel = new JLabel("Your application is running.");
statusBar.setLeftComponent(leftLabel);
final JLabel dateLabel = new JLabel();
dateLabel.setHorizontalAlignment(JLabel.CENTER);
statusBar.addRightComponent(dateLabel);
final JLabel timeLabel = new JLabel();
timeLabel.setHorizontalAlignment(JLabel.CENTER);
statusBar.addRightComponent(timeLabel);
contentPane.add(statusBar, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent event) {
exitProcedure();
}
});
timerThread = new TimerThread(dateLabel, timeLabel);
timerThread.start();
frame.setVisible(true);
}
public void exitProcedure() {
timerThread.setRunning(false);
System.exit(0);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new StatusBarSimulator());
}
public class TimerThread extends Thread {
protected boolean isRunning;
protected JLabel dateLabel;
protected JLabel timeLabel;
protected SimpleDateFormat dateFormat =
new SimpleDateFormat("EEE, d MMM yyyy");
protected SimpleDateFormat timeFormat =
new SimpleDateFormat("h:mm a");
public TimerThread(JLabel dateLabel, JLabel timeLabel) {
this.dateLabel = dateLabel;
this.timeLabel = timeLabel;
this.isRunning = true;
}
#Override
public void run() {
while (isRunning) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Calendar currentCalendar = Calendar.getInstance();
Date currentTime = currentCalendar.getTime();
dateLabel.setText(dateFormat.format(currentTime));
timeLabel.setText(timeFormat.format(currentTime));
}
});
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
}
}
}
public void setRunning(boolean isRunning) {
this.isRunning = isRunning;
}
}
}
Add a label component at the appropriate place in your JFrame's component hirerarchy (maybe a JToolBar?).
Then create a timer that fires once per second, and add an ActionListener to it that updates the text of the label with the current time.
See the accepted answer at Using SwingWorker and Timer to display time on a label?
Create a SimpleDateFormat object that will help you format the current date. Add a JLabel to your JFrame. In a separate thread, create a loop that keeps reading the current date, format it to a String and pass it to the JLabel in the EDT. Make the separate thread sleep for one second or less before updating the label again.

Translucent JPopupMenu inside a Translucent Window - alternative?

I'm not sure if this is possible, but is there a way to safely allow popups to be translucent even when the parent container is also translucent?
If not, what would be wise alternative to use or extend instead of JPopupMenu?
Note: Translucent refers to a component not 'having a background', similar to the effect of setOpaque(false);. Thanks.
From a forum answer by user camickr in 2009:
I don't know if transparency painting has changed in 1.6.0_10. Prior
to that I believe transparency can only be achieved in lightweight
components (ie. Swing does all the painting). JFrame, JWindow and
JDialog are not lightweight because they use OS components.
In the case of a popup, it is lightweight when entirely contained
within its parent frame. But a lightweight popup can not be painted
outside the bounds of the frame so a JWindow (I believe) is used as
the popup, which can't be transparent.
SSCCE: Showing translucent JWindow over the top of translucent JFrame
import com.sun.awt.AWTUtilities;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class OpaqueWindowSSCCE {
private int countdown = 5;
public static void main(String[] args) {
new OpaqueWindowSSCCE();
}
public OpaqueWindowSSCCE() {
final JFrame frame = new JFrame("OpaqueWindowSSCCE");
final JWindow window = new JWindow();
new Timer(1000, new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
if(--countdown == 0){
frame.dispose();
window.dispose();
System.exit(0);
} else {
frame.repaint();
}
}
}).start();
frame.setContentPane(new JPanel() {
#Override
public void paintComponent(Graphics paramGraphics) {
super.paintComponent(paramGraphics);
Graphics2D g = (Graphics2D) paramGraphics.create();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(new Color(50, 50, 50));
g.fillRoundRect(0, 0, getWidth(), getHeight(), 10, 10);
g.setColor(new Color(180, 180, 180));
g.drawString("Closing in " + countdown + " seconds", 20, 25);
}
});
window.setContentPane(new JPanel() {
#Override
public void paintComponent(Graphics paramGraphics) {
super.paintComponent(paramGraphics);
Graphics2D g = (Graphics2D) paramGraphics.create();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(new Color(180, 180, 180));
g.fillRoundRect(0, 0, getWidth(), getHeight(), 10, 10);
}
});
frame.setUndecorated(true);
((JComponent) frame.getContentPane()).setOpaque(false);
((JComponent) window.getContentPane()).setOpaque(false);
AWTUtilities.setWindowOpaque(frame, false);
AWTUtilities.setWindowOpaque(window, false);
window.setAlwaysOnTop(true);
frame.setBounds(200,200,500,500);
window.setBounds(600,600,200,200);
frame.setVisible(true);
window.setVisible(true);
}
}
Try this code part, I had used JWindow though
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class WindowExample
{
private JWindow window;
private JLabel updateLabel;
private int count = 5;
private Timer timer;
private int x;
private int y;
private ActionListener timerAction = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
updateLabel.setText("Closing Window in " + count + " seconds...");
count--;
if (count == 0)
{
timer.stop();
window.setVisible(false);
window.dispose();
}
}
};
private void createAndDisplayGUI()
{
final JFrame frame = new JFrame("Window Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);
frame.setOpacity(0.5f);
frame.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent me)
{
x = me.getX();
y = me.getY();
window = new JWindow();
JPanel contentPane = new JPanel();
JLabel positionLabel = new JLabel(
"X : " + me.getX() + " Y : " + me.getY());
updateLabel = new JLabel("TImer");
contentPane.setLayout(new BorderLayout(5, 5));
contentPane.add(updateLabel, BorderLayout.CENTER);
contentPane.add(positionLabel, BorderLayout.PAGE_END);
window.setContentPane(contentPane);
window.setOpacity(0.5f);
window.setSize(200, 100);
window.setLocation(x + window.getWidth(), y + window.getHeight());
window.setVisible(true);
count = 5;
timer = new Timer(1000, timerAction);
timer.start();
}
});
frame.setSize(500, 500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new WindowExample().createAndDisplayGUI();
}
});
}
}
And here is the output :
WARNING I AM GETTING
C:\Mine\JAVA\J2SE>javac -d classes src\OpaqueWindowSSCCE.java
src\OpaqueWindowSSCCE.java:1: warning: AWTUtilities is internal proprietary API and may be removed i
n a future release
import com.sun.awt.AWTUtilities;
^
src\OpaqueWindowSSCCE.java:68: warning: AWTUtilities is internal proprietary API and may be removed
in a future release
AWTUtilities.setWindowOpaque(frame, false);
^
src\OpaqueWindowSSCCE.java:69: warning: AWTUtilities is internal proprietary API and may be removed
in a future release
AWTUtilities.setWindowOpaque(window, false);
^
3 warnings

Categories