A transparent JFrame that is always on top, but allows clicking underneath - java

So, i'm making a program that currently just accepts a file that'd been dragged and dropped into it. I'm using a JFrame for the container at the moment, but I dont think that's really important.
I want the window to always be on top when running, so that if you drag any file to the bottom right corner of the screen, the program will handle it. But, at the same time, i want the program to be able to be invisible, and click-through-able, meaning that you can click on anything underneath the jframe, while it's invisible, but still be able to drag a file into the program without having to do anything special.
I've never heard of something like this, but I'm sure it must be possible. How would I do this?

I made a Splash screen the other day that was click-through-able. You might want to make a completely transparent image using Photoshop or something else. Here is the code:
private BufferedImage splash;
/**
* Create the frame.
*/
public Splash() {
this.setUndecorated(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(500, 500);
setLocationRelativeTo(null);
try {
splash = ImageIO.read(getClass().getResource("/images/transparent.png"));
} catch (Exception e) {
e.printStackTrace();
}
// Apply a transparent color to the background
// This is REALLY important, without this, it won't work!
setBackground(new Color(0, 255, 0, 0));
getContentPane().setBackground(Color.BLACK);
add(new JLabel(new ImageIcon(splash)));
setVisible(true);
}

Related

Is it possible to make JWindow which is transparent and is clickable through?

I have JWindow which is semi transparent so you can see whatever is on desktop. Then I have it set to be always on top. That all works fine but what i would like to do next is to be able to click whatever is behind JWindow. I can see what is behind but there is some default listener or something that changes my mouse and not being able to click through it. If anyone has suggestion on how to achieve that i would be glad to hear it.
public Class extends JWindow {
setAlwaysOnTop(true);
setSize(100, 100);
setBackground(new Color(255, 0, 0, 10));
setVisible(true);
}

Display a grid of JPanels in a JFrame?

I'm very new to Java but have some experience with C++. This is a homework assignment so I'm really just looking for someone to point me in the right direction.
The assignment requires a JFrame with JPanel objects displaying every card in a deck in a 13x4 grid. The Professor has supplied us with some code to get us started:
import javax.swing.*;
import java.awt.*;
public class Main
public static void main(String[] args)
{
//load the card image from the gif file.
final ImageIcon cardIcon = new ImageIcon("cardImages/tenClubs.gif");
//create a panel displaying the card image
JPanel panel = new JPanel()
{
//paintComponent is called automatically by the JRE whenever
//the panel needs to be drawn or redrawn
public void paintComponent(Graphics g) {
super.paintComponent(g);
cardIcon.paintIcon(this, g, 20, 20);
}
};
//create & make visible a JFrame to contain the panel
JFrame window = new JFrame("Title goes here");
window.add(panel);
window.setPreferredSize(new Dimension(200,200));
window.pack();
window.setVisible(true);
}
}
I have tried out a few things, but I can't seem to get multiple panels to display. Should I use a gridLayout() feature? or just create multiple panels and specify each one's location in the frame?
Again if someone can just point me in the right direction that would be awesome.
For displaying elements at the same size, evenly distributed within the container, then yes, GridLayout would be a good choice.
If you need to display the components in the grid at there preferred size (which may be different for each component) then GridBagLayout would be a better choice
If the code was supplied by a your professor, then you need to go back and make them fix it.
Firstly, a JLabel would be easier and provide better support for what you are trying to achieve...
Secondly, because the JPanel doesn't override getPreferredSize, most of the layout managers will set the size of the component to 0x0
There is a way to display multiple JPanels in one JFrame. Unlucky you the way is not so easy. Java has many diffrent LayoutManagers.
For your purpose I would recommend GridBagLayout, it is more complex, but definately the thing you need.
Here is a good tutorial, which helped me to understand it:
GridBagLayout
Hope it is a help.

LWJGL Display.setWidth/Height?

Similar to what you can do with a Java's Canvas class, I am currently trying to write a method to set an LWJGL Display's maximum size. The only problem I have run into is that LWJGL's Display class doesn't have a setWidth or setHeight method, and I can't think of an way I could write my own. My first thought was to somehow get the instance of the JFrame that the window was using, but there's no method for this either so I feel like I am SOL. I also tried using DisplayMode and just resetting the size through that, but it closes the window and reopens it every time it resizes. I am trying to write a method that'd simply resize the window as if the user was dragging it to enlarge it. Does anybody know how I could/should go about doing this? Is it even possible to get this smooth max-size effect I am looking for, considering that the display doesn't even update until you let go after dragging/resizing it manually?
If you need more control over your window, you can try using an AWT Frame as a parent to an LWJGL Canvas. This would allow your code to take advantage of default window methods, including setWidth() and setHeight() found in the Java standard libraries, prevent and control window behavior, and add listeners to run code for certain events.
First, import java.awt.* and then set up code that looks something like this:
Create a Frame and Canvas:
Frame frame = new Frame("LWJGL Game Window");
frame.setLayout(new BorderLayout());
Canvas canvas = new Canvas();
Add the Canvas to the Frame:
frame.add(canvas, BorderLayout.CENTER);
Setup LWJGL and apply it to the Canvas:
try {
Display.setParent(canvas);
frame.setPreferredSize(new Dimension(1024, 786));
frame.setMinimumSize(new Dimension(800, 600));
frame.pack();
frame.setVisible(true);
Display.create();
while(!Display.isCloseRequested() && !closeRequested)
{
// main code or call to code goes here
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
Display.update();
}
Display.destroy();
frame.dispose();
System.exit(0);
} catch (LWJGLException e) {
e.printStackTrace();
}
Not sure how much you know about Java, but from here, you could add an ActionListerner or ComponentListerner that does something if the window is resized.
Also check out the LWJGL wiki for AWT Frames. This should, at least, help to point you in the right direction.

Making a glassPane fit with the dimensions of a JPanel

StackOverflow!
I'm working on a project, in regards to making a navigation system, and we're in the beginning stages, working with drawing the map and navigating it itself.
We have a function, where you should be able to draw a square on top of the current data having been drawn already. I want to avoid having to repaint all of the data for the roads all over again, with each mouseDragged action event. To do this, I found that using a glass pane would be the optimal choice.
The problem recides with the dimensions of the glasspane and the coordinates it reads. When I click on a certain spot on our JPanel (which we use to draw on), it knows how and where to zoom in properly, but when I draw my square, it is being drawn a specific amount of pixels above my mouse's position. This seems to be due to the fact that my glass pane dimension does not correspond to my JPanel dimensions. The glass pane seems to also cover my menubar, whereas the JPanel itself does not read clicks which occur on the menubar.
I want to somehow fit a glasspane to my JPanel, and I've tried a few different things.
One thing I tried, was to draw on a JRootPane instead of a JPanel, but that doesn't seem to be possible. Then I tried to just retrieve the "MyGlassPane" class from my JPanel (which also has its own class), and call it's repaint method, but that's where the issue originated from.
Most lately, I've retrieved the JRootPane which the JPanel itself uses or is part of, and then retrieved the glasspane of this JRootPane, but it seems that my menubar, added to the JFrame, is also part of this JRootPane, meaning that the glasspane covers the menubar as well.
Here is some very simplified code, which covers the issue, but not the mouse-listening nor data-drawing aspects. It does however show off the fact that it's annoying that the rectangle is being drawn on top of the menubar.
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.*;
public class TestForRootPaneStuff {
JFrame frame = new JFrame();
JRootPane root;
JPanel panel = new JPanel();
JLabel label = new JLabel("Hello there!");
public void rootPanePls()
{
frame.add(panel);
panel.add(label);
root = panel.getRootPane();
JMenuBar menubar = new JMenuBar();
JMenu prettyMenu = new JMenu("Pretty");
menubar.add(prettyMenu);
frame.setJMenuBar(menubar);
MyGlassPane gp = new MyGlassPane();
root.setGlassPane(gp);
gp.setVisible(true);
gp.setEnabled(true);
gp.repaint();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(250, 250));
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
TestForRootPaneStuff derp = new TestForRootPaneStuff();
derp.rootPanePls();
}
private class MyGlassPane extends JComponent implements ItemListener
{
//React to change button clicks.
#Override
public void itemStateChanged(ItemEvent e) {
setVisible(e.getStateChange() == ItemEvent.SELECTED);
}
//Draw the square for zoomToSquare
#Override
protected void paintComponent(Graphics g) {
g.setColor(Color.BLUE);
g.drawRect(10, 10, 100, 100);
}
}
}
And this is a corresponding screenshot, as a result of running this code. (I can't post direct images, due to lack of activity on here)
I hope my explaination makes at least a bit of sense. I'm aware that my explaination is perhaps a bit too in-depth as for actually resolving the issue, but I felt like it was necessary to invelop you guys a little bit more into my situation, and my reason for needing a solution for this.
TL;DR:
I need a way to make a glassPane (retrieved/set from somewhere) completely fit the dimensions of a specific JPanel, so that I can receive the same mouse event coordinates for both the JPanel and the glasspane. See code above for visualization of the issue.
Is there a smart way to go about this? Setting the RootPane glasspane was my final idea...
Thanks in advance, if anyone has any insight to bring!
Kirluu~
not an asnwer longer comment, just guessing based on wrong/uncomplete code posted here
use JLabel instead of JComponent, JComponent hasn't any LayoutManager in API, sure JLabel too, but it to be container very simple like as contianer, is transparent, anything in paintComponent can be (semi) transparent
your code is incompleted why is there ItemListener, don't put JComponents to JComponent as contianer, use JPanel instead, or mentioned opaque JLabel is easiests of ways for GlassPane, 1st code line should be super.paintComponent in paintComponent, dispose() all custom painting for anything placed/laid in GlassPane
JLabel can has easilly to copy the coordinates from JPanel, use ComponentListener added to JPanel, with delaing (350-600) events from ComponentListener (one event per one pixel) by using Swing Timer, EDIT if resize continue call timer.restart() </EDIT, if resize ended then Swing Action/ActionListener will fire setBounds for JLabel (whatever) placed in GlassPane
search for simple RepaintManager (just by covering JLabels bounds in GlassPane) for animation in GlassPane

How to change the color of my buttons on Mac OS?

I'm having a problem changing the color of my button background, I'm just starting to learn how to do the GUI and I have the following code which works perfectly on Windows, but I use Mac OS.
Can you please help me with this?
I already added the buttons and then changed the color but when running it, it pop-ups the window with the 9 buttons but all of them are in color white and the background is red, as you see I set them up on color blue.
b1.setBackground(Color.BLUE);
b2.setBackground(Color.BLUE);
b3.setBackground(Color.BLUE);
b4.setBackground(Color.BLUE);
b5.setBackground(Color.BLUE);
b6.setBackground(Color.BLUE);
b7.setBackground(Color.BLUE);
b8.setBackground(Color.BLUE);
b9.setBackground(Color.BLUE);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
this.getContentPane().setBackground(Color.RED);
this.setBackground(Color.BLACK);
this.setVisible(true);
this.setBounds(100, 100, 800, 500);
The default way to paint buttons on OSX and Windows seems to be different.
Since your question is broad, I'm not quite sure what the expected behavior is, so here are some solutions to your problem:
I just tested on my Mac, and what you need to do is to specify that the buttons should be opaque:
b1.setOpaque(true);
Depending on what you're trying to accomplish, it might be required for you to specify that the border shouldn't be painted either:
b1.setBorderPainted(false);
If you don't specify that the border shouldn't be painted, you're going to get a square with a blue background and a button with the default color in the middle.
If you want something that looks the same on both operating systems, you should use the following line in your JFrame:
try {
UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName() );
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
This last way will make you lose the OSX / Windows look and feel, though, but the buttons will probably look more like what you're expecting.

Categories