Currently i'm trying to make an image slowly slide using Java fx from one coordinate to another. For this construction i'm using a pane and have added a shaft imageview and a elevator image to it. I've been succesfull in changing the coordinates of the image but I want the image to slowly slide over to that position. As a result I added a loop that with a thread.sleep method to slow down the looping speed. Unforunately this does not give the desired effect.
Hopefully one of you has a good suggestion I could use for this.
My loop:
Button een = new Button("1");
een.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent event) {
if(elevator.getY()>300){
while(elevator.getY()!=300){
elevator.setY(elevator.getY()-1);
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(LayoutSample.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
});
Yours truly
No loops, no sleep, TranslateTransition, linked javadoc includes a sample.
Thank you in advance for any attempts at trying to help me figure this one out. I've searched all over stack and google and haven't been able to find anything similar to the problem I am having.
I am designing a small program using NetBeans that switches between multiple frames
login screen > settings screen > main screen
My program can take a while in-between frames to load the next one due to a large amount of frame initialization code. To prevent it from looking like the program is unresponsive. I wrote code which displays an intermediary splash screen JWindow which performs all the initialization for the next frame. I realize that there is a splash screen class, but I could not get it to work as desired, this custom implementation of mine does almost everything I need except when I attempt to display the splash screen a second time, during a single program run, the image does not show up on the JWindow.
So run program > splash screen (works) > login > splash screen (image does not load) > settings.
Here is a sample clip of code which displays the splash screen JWindow:
public class Splash extends JPanel {
private static Calendar date;
private static long startTime;
private static final long MAX_TIME = 3000l;
public static final int LOAD_LOGIN = 0;
public static final int LOAD_SETTINGS = 1;
public static JWindow win;
private final ImageIcon img;
public Splash() {
date = Calendar.getInstance(TimeZone.getTimeZone("EST"), Locale.ENGLISH);
img = new ImageIcon("loader.gif");
startTime = date.getTimeInMillis();
this.setSize(300, 300);
win = new JWindow();
win.setSize(300, 300);
win.getContentPane().add(this);
Login.centerWindow(win); // method from login class that centers window
win.setVisible(true);
}
public void runSplash(int flag) {
if (flag == LOAD_LOGIN)
firstRunCheck();
else {
initSettings();
}
long currTime = date.getTimeInMillis();
// holds splash display for at least 3 secs
while ((currTime - startTime) < MAX_TIME) {
currTime = System.currentTimeMillis();
}
win.dispose(); // has been replaced with win.setVisible(false) before,
// same problem
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponents(g);
Graphics2D g2 = (Graphics2D) g;
//I have read several other questions and sample codes on stack and google
but using this method is the only way for me to get the animated gif image to
load correctly
g2.drawImage(img.getImage(), null, this);
}
}
In order to display this splash screen I instantiate it using new Splash().runSplash(value); where value runs the method that loads the following frames required values.
When I first begin run the program everything works perfectly. When I attempt to move from the login screen to the settings screen the JWindow loads but it just displays as a blank frame.
The program works fine still, the settings frame eventually loads, but the image never shows up and the window just closes. I am unsure as to what the problem is the class is instantiated the exact same way as the first time.
I suspect perhaps I may be incorrectly disposing of resources, but win.dispose() appears to be the correct method according to some of the other problems I have read.
Any help is appreciated thank you.
UPDATE: I am still attempting to resolve this problem. I have used a variety of different implementations to display the splash screen. I have used implementations which use a JLabel instead of JPanel, and use setIcon instead of overriding paintComponent. But the same result is observed whenever the implemented splash screen class is called a second time the image does not appear. Since different implementations are also not working I can only assume that that perhaps I have too many events in the event queue or something. To clarify.
My main method is in the Splash class detailed above. I call the class in the main method using new Splash.runSplash(value). This call works perfectly. I then call the login JFrame using:
if (value == LOAD_LOGIN) //RUN_LOGIN is a final variable int
{
java.awt.EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
/* I have also tried this without the invokeLater
command and simply using new Login().setVisible(true).
The program still runs fine, but the image still
does not display */
new Login().setVisible(true);
}
});
}
This call is made at the end of the runSplash(value) method. After the user inputs the correct login information they are taken to the splash screen again using new Splash().runSplash(value) on this call however I cannot get the image to show up on the JWindow.
dispose() method releases the resource. to be able to use it again you have to use setVisible(false) and when you be sure that your code will not use this window again then only use dispose().In your case after first splash just use setVisible(False) and dispose after the second time when setting frame loads if you really want it so.
I want to create a splash screen for my Java application. I managed to do this using the NetBeans default tool that allows me to put some image in. But i want to have something "live" there, such as a progress bar showing the status of application load, some dynamic text, etc.
How do I do this? What are the things I need to know to start doing something like this?
Here is the Java tutorial walking you through exactly what you want to do. You can set the image on the command line so that it shows immediately, then you can manipulate it once the JVM is initialized to add text, progress bars, etc.
http://download.oracle.com/javase/tutorial/uiswing/misc/splashscreen.html
The trick is to create a splash screen using swing and then invoke using Java reflection the method, which is in another .java file, that loades the application. When done loading, dispose your splash screen.
After checking the code, you will understand how it works and now customize it your own way.
Here is some code:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JDialog;
/**
*
* #author martijn
*/
public class Splash {
public static void splash() {
try {
final BufferedImage img = ImageIO.read(Splash.class.getResourceAsStream("/path/to/your/splash/image/splash.png"));
JDialog dialog = new JDialog() {
#Override
public void paint(Graphics g) {
g.drawImage(img, 0, 0, null);
}
};
// use the same size as your image
dialog.setPreferredSize(new Dimension(450, 300));
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.setUndecorated(true);
dialog.pack();
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
dialog.repaint();
try {
// Now, we are going to init the look and feel:
Class uim = Class.forName("javax.swing.UIManager");
uim.getDeclaredMethod("setLookAndFeel", String.class).invoke(null, (String) uim.getDeclaredMethod("getSystemLookAndFeelClassName").invoke(null));
// And now, we are going to invoke our loader method:
Class clazz = Class.forName("yourpackage.YourClass");
dialog.dispose();
// suppose your method is called init and is static
clazz.getDeclaredMethod("init").invoke(null);
} catch (Exception ex) {
ex.printStackTrace();
}
dialog.dispose();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
After long investigations and reading this question I still didn't get a "good" solution for my problem.
I have a Gef editor and I want to let the users drag and drop figures (== model objects) form this editor to an other custom view available in my perspective.
Adding a DragSource with my own drag transfer on my GEF editor figure canvas allows that. But as a side effect, and I don't want this side effect, this disable the possibility to move the figures INSIDE the editor using drag and drop.
After investigations I found this post on eclipse forums, but the solution is not acceptable for me. Thus I investigated deeper and came to the following pure SWT snippet that shows that MouseMove events (the ones used by gef to support dragging INSIDE the editor) are no more fired once a drag source has been added:
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class SwtTest {
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.addMouseListener(new MouseListener() {
public void mouseUp(MouseEvent e) {
System.out.println("mouseUp");
}
public void mouseDown(MouseEvent e) {
System.out.println("mouseDown");
}
public void mouseDoubleClick(MouseEvent e) {
System.out.println("mouseDoubleClick");
}
});
shell.addMouseMoveListener(new MouseMoveListener() {
#Override
public void mouseMove(MouseEvent e) {
System.out.println("Mouse move");
}
});
DragSourceListener dragListener = new DragSourceListener() {
public void dragFinished(DragSourceEvent event) {
System.out.println("dragFinished");
}
public void dragSetData(DragSourceEvent event) {
System.out.println("dragSetData");
}
public void dragStart(DragSourceEvent event) {
System.out.println("dragStart");
}
};
DragSource dragSource = new DragSource(shell, DND.DROP_COPY | DND.DROP_MOVE);
dragSource.addDragListener(dragListener);
dragSource.setTransfer(new Transfer[] { FileTransfer.getInstance() });
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
I guess this is the normal behavior fro man SWT point of view. Do you confirm ?
Moreover, I am really looking for a solution to this issue other that the one proposed on Eclipse forum consisting in activating my DragSource only if a given condition is met such as Shift is pressed (this is done in a DragSourceListener.dragStart method by setting event.doit to false)
Any help, suggestions and comments are welcome.
Thanks in advance,
Manu
Most likely you want to extend normal GEF drag and drop to contain also Image drag support.
When you drag items inside GEF editor you can drag them as Figures (actually it is bit more complex, it is using Request-Command pattern). But when your drag goes over the editor borders you need to be able to provide ie. Image out of this data.
SWT Provides support for multiple different Drag Data Transfers like this:
dragSource.setTransfer(new Transfer[] { FileTransfer.getInstance(), ImageTransfer.getInstance() });
So I believe that you want to find a way in GEF DragTracker to also include this ImageTransfer to the OS Drag. DragTrackers are GEF way of handling drag, and are returned in EditPart's function getDragTracker()
I am not totally sure how that can be done, but extending own DragTracker that is also able to provide also OS level Image should do the trick.
Case is quite similar to copy pasting, and in basic GMF editor it is possible to copy paste items as images outside the editor to any tool that is accepting images.
I need to implement a class, using Swing, which can obtain the mouse coordinates when the user clicks anywhere on the screen. if I wanted to obtain the mouse coordinates inside my own window, I'd use a MouseListener, but I want it to work even when the user clicks outside my program.
I want my class to behave just like KColorChooser: the user clicks on the drop button and he can click anywhere on the screen to obtain the color of that spot. but I don't know if that's possible using pure Java.
It is possible though limited:
Add an AWTEventListener for focus events. As long as your app has focus before the button is clicked you'll receive a focus lost event. Then query for the pointer position.
The limitation is that, of course, your app loses focus. So depending on what you are ultimately trying to achieve this might not be useful.
If you don't want to lose focus then you will have to temporarily take a screenshot of the whole screen and display that in a screen filling window which listens for a mouse click as usual.
Proof of first method:
import java.awt.AWTEvent;
import java.awt.MouseInfo;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import javax.swing.JFrame;
public class Application1 {
public static void main(String[] args) {
Toolkit.getDefaultToolkit().addAWTEventListener(
new Listener(), AWTEvent.MOUSE_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static class Listener implements AWTEventListener {
public void eventDispatched(AWTEvent event) {
System.out.print(MouseInfo.getPointerInfo().getLocation() + " | ");
System.out.println(event);
}
}
}
Clicking outside of the app produced:
java.awt.Point[x=198,y=59] | java.awt.event.MouseEvent[MOUSE_EXITED, ...
java.awt.Point[x=976,y=503] | java.awt.FocusEvent[FOCUS_LOST, ...
The second point is outside of the app.
Forget about GlassPane, there's another 100% native Java way to do it that works both on OS X and on Windows.
Java has always supported translucency for its windows on OS X and Java now supports translucency for its windows on Windows too (since Java 1.6.0_10 or so, needs to be checked).
So the trick is: upon clicking on the "pick a color" tool, you create a nearly transparent borderless Java window covering the entire screen. You set its alpha to 10 (alpha goes from 0 to 255). That alpha is so low the user won't notice that there's a very thin "nearly transparent but only very very very translucent" borderless window covering the entire screen.
Now when the user clicks on your "alpha set to 10 translucent borderless window" covering the entire screen, you get your (x,y).
Discard the borderless Java window.
Use Robot's getRgb(x,y) and you're done.
Why set the alpha to 10 and not 0? Because otherwise clicks aren't intercepted by Java but go directly to the OS (at least that's how it works for a fact on OS X). There's a treshold and I know it's not set at '1', nor '2', it's around 10 or so.
EDIT I just realized you know need to pick several colors, this is trickier but can still be done using 100% Java. Either you can live with "slightly off" colors (affected by the "nearly transparent" 'invisible' layer) or upon getting a click you must remove the layer, get the correct pixel color, and put again a "nearly transparent" layer. Now of course that is one heck of a hack but it can be done in 100% Java.
Use
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
PointerInfo inf = MouseInfo.getPointerInfo();
Point p = inf.getLocation();
p.x and p.y will give you co-ordinates outside your window.
I don't know if that's possible using
pure Java.
Its not possible using pure Java, since Java is only aware of MouseEvents on Windows belonging to Java.
These events are directed to the window which has the focus, from all events on the desktop you can only get the mouse position.
As already shown by Keilly it's only possible to get the mouse postion.
You need to include a native lib
I haven't tried this myself, but maybe you could create a full-screen, transparent panel/frame/etc, and add a MouseListener to that.
It is possible with a little trick. Should be 100% cross-platform (tested on Linux & Windows). Basically, you create a small JWindow, make it "alwaysOnTop" and move it around with the mouse using a timer.
For details, see my answer here.
The location (x,y) and the time interval
(d) between each click is supplied thru command line arguments. Here is the
program
import java.awt.* ;
import java.util.* ;
public final class ClickMouse extends TimerTask {
public static int x, y, d ;
public static void main(String[] args) {
TimerTask clikMouse = new ClickMouse();
Timer t = new Timer();
/*
x = Integer.parseInt(args[0]) ;
y = Integer.parseInt(args[1]) ;
d = Integer.parseInt(ares[2]) ;
*/
x = 500;
y = 200;
d = 5;
t.schedule(clikMouse,1000,d*1000);
}
public void run() {
try
{
Robot bot = new Robot();
bot.mouseMove(x,y);
bot.mousePress(java.awt.event.InputEvent.BUTTON1_MASK );
bot.mouseRelease(java.awt.event.InputEvent.BUTTON1_MASK);
}
catch (Exception e)
{
System.out.println("Exception occured :" + e.getMessage());
}
}
}
https://github.com/kwhat/jnativehook JNativeHook: Global keyboard and mouse listeners for Java.
I don't have enough rep yet to leave comments, but here are my comments on the other techniques:
Use a native lib: will work, but has obvious distribution limitations
Use GlassPane to fill entire screen: GlassPanes must be contained within a Window.
Create a Window containing a picture of the desktop and fill the entire screen: Will work, but it will suddenly make the desktop static. The cursor will no longer change, any animations or video in other windows or desktop will become eerily static.
Alternative solution:
A refinement of the screen filling window, if you are using Java 6u10 or later is to make the window completely transparent. Put this window in front of all others and listen for mouse clicks. It still has shortcomings, such as no cursor changes, but it depends on what you want to do.
Based on SyntaxT3rr0r's answer I created a sample color picker in groovy which shows how it can work.
import java.awt.*
import java.awt.datatransfer.*
//import com.sun.awt.AWTUtilities;
import javax.swing.WindowConstants as WC;
import javax.swing.SwingConstants as SWC
import groovy.swing.SwingBuilder
class ColorPicker {
SwingBuilder swb = new SwingBuilder()
def window;
def overlayWindow
def mainPanel;
def mainLabel;
def menu;
def transparent = new Color(0, 0, 0, 0);
def nearlyTransparent = new Color(0, 0, 0, 26);
Color color = new Color(150, 150, 255);
def colorHex = { col ->
col = col?: color;
"#"+Integer.toHexString(col.getRGB())[2..-1]
}
def getTextColor = { baseColor ->
baseColor = baseColor?: color;
(baseColor.red*1.5 + baseColor.green*1.5 + baseColor.blue > 400) ? Color.BLACK : Color.WHITE;
}
def setDisplayColor = {newColor ->
mainPanel.background = newColor
mainLabel.foreground = getTextColor(newColor)
mainLabel.text = colorHex(newColor)
}
def show(){
menu = swb.popupMenu { // invoker: mainPanel
menuItem(text: "Pick Color", actionPerformed: capturePixelColor)
menuItem(text: "Copy to Clipboard", actionPerformed: {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(new StringSelection(colorHex()), null);
})
separator()
menuItem(text: "Close", actionPerformed: {dispose()})
}
window = swb.frame(
title: "Color Picker",
location:[50,50],
size:[60, 60],
resizable: false,
undecorated: true,
alwaysOnTop: true,
defaultCloseOperation:WC.EXIT_ON_CLOSE
){
def textColor = getTextColor()
mainPanel = panel( constraints: BorderLayout.CENTER,
border: lineBorder(color: Color.BLACK),
componentPopupMenu: menu){
borderLayout()
mainLabel = label(text: "--",
constraints: BorderLayout.CENTER,
horizontalAlignment: SWC.CENTER)
}
}
setDisplayColor(color);
window.show();
}
def capturePixelColor = {
def screenSize = Toolkit.getDefaultToolkit().screenSize
overlayWindow = swb.frame(
location:[0,0],
size: screenSize,
resizable: false,
undecorated: true,
alwaysOnTop: true,
defaultCloseOperation:WC.DISPOSE_ON_CLOSE,
show: true,
background: nearlyTransparent, // AWTUtilities.setWindowOpacity(overlayWindow, 0.1f);
cursor: Cursor.CROSSHAIR_CURSOR,
mouseClicked: {event ->
int x = event.getXOnScreen() // or maybe getX() is enough
int y = event.getYOnScreen()
overlayWindow.dispose()
overlayWindow = null
color = new Robot().getPixelColor(x, y)
setDisplayColor(color)
}
)
}
public static void main(String...args){
println "Welcome to ColorPicker"
def picker = new ColorPicker()
picker.show()
}
}
Look, I understand I am 7 years late...
This is a re-make of Keilly's answer, which allows to get when the mouse button is clicked, anywhere. The main problem is that fullscreen games are always unfocused, and it becomes annoying to handle.
Here is the code:
import java.awt.AWTEvent;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import javax.swing.JFrame;
public class Main {
public static JFrame frame = new JFrame();
public static void main(String[] args) {
Toolkit.getDefaultToolkit().addAWTEventListener(
new Listener(), AWTEvent.MOUSE_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setAlwaysOnTop(true);
frame.setLocation(1, 1);
}
private static class Listener implements AWTEventListener {
public void eventDispatched(AWTEvent event) {
// We do not want the event to show twice,
// as it shows for focusing and unfocusing
if(event.getID() == 1004) {
Point p = MouseInfo.getPointerInfo().getLocation();
System.out.println("Mouse Clicked at " + p.x + ", " + p.y);
}
// The frame was just unfocused! To make
// sure we get the next mouse click, we
// need to focus it again!
frame.setVisible(true);
}
}
}