JavaFX .setStyle(...) isn't not working when `-fx-background-image` changes - java

What i want to achieve:
I am using a FileChooser and the user selects an appropriate .jpg image file . Then i am copying that image , renaming it background.jpg to a known folder and trying to set it as the background image of the application using .setStyle(...); There is not problem of copying the image [ i am checking it]
The Problem that occurs:
I have a Stage with a BorderPane . The BorderPane has an background Image , i do that using
borderPane.setStyle("-fx-background-image:url('filepath')");
!It works well the first time!
->Then i am deleting that file [background.jpg] and i am replacing it with another file named also [background.jpg] . The background image of the BorderPane isn't changing ....
I have tried also resetting the same style using again :
borderPane.setStyle("-fx-background-image:url('filepath')");
Finally when i am changing the filename , for example to [background-12.jpg] and reseting the style using the above it changes the background image.
Which exactly is the problem ? I mean i am sure that the background.jpg has been created , i am checking it and also when i am changing the name to something other again and again it works .
Is the Java CSS Parser lazy to parse the new style which is the same but has other -fx-background-image resource ?
As for the File path i am sure it is well , i am using the code below :
//Maou is the File URL in appropriate format for CSS
String maou = file.getAbsoluteFile().toURI().toString()
//Here i add the appropriate file separator, if not JavaFX will report error
maou = maou.replaceAll("\\Q\\\\E", "//");
//Print maou
System.out.println("Maou=\n" + maou);
Solution :
I found as best solution using James_D answer , a little bit modified so it covers the whole window:
BackgroundImage bgImg = new BackgroundImage(image, BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT,
new BackgroundSize(window.getWidth(), window.getHeight(), true, true, true, true));

Rather than using an inline style, I would recommend setting the background via the background property directly:
Image img = new Image(file.getAbsoluteFile().toURI().toString());
BackgroundImage bgImg = new BackgroundImage(img,
BackgroundRepeat.NO_REPEAT,
BackgroundRepeat.NO_REPEAT,
BackgroundPosition.DEFAULT,
BackgroundSize.DEFAULT);
borderPane.setBackground(new Background(bgImg));
The Background class provides Java API programmatic access to all the same properties that can be set by CSS.

While I don't know exactly what's going on, presumably it's some form of caching which JavaFX is doing to try to be "helpful". I may look into the source code later.
To be honest, though, setting a background via CSS feels like the wrong approach to me. I always avoid setting any styles explicitly, like:
borderPane.setStyle("something");
and prefer to add and remove style classes:
borderPane.getStyleClass().add("foo");
borderPane.getStyleClass().remove("foo");
I don't think this is possible in your situation, so I would instead use a StackPane
to layer your content over an ImageView.
ImageView img = new ImageView(new Image(new URL("path")));
StackPane stack = new StackPane();
stack.getChildren.addAll(img, /*overlaid content*/);

Related

Implementing an image upload button using Jython & Swing

I'm developing a cross platform desktop application using Jython and Swing, and I found a hitch.
I would like to develop a button that allows me to load an image in its background and to change it when I reclick on the image loaded.
I attach as an example some pictures on how I would like my widget to be.
Upload pane without image
And then, when I load an image:
Upload Pane with image
I tried with the following code:
fd = FileDialog(self, "Scegli un'immagine", FileDialog.LOAD)
fd.setFile(';*.'.join(("*.bmp","jpg","jpeg","wbmp","png","gif")))
fd.setVisible(True)
fileName = fd.getFile()
if fileName != None :
fileAbsPath = os.path.abspath(fileName)
"""'self.bigDict['imgButton']' is the current JButton"""
self.bigDict['imgButton'].setIcon(ImageIcon(fileAbsPath))
When I click on "Open", the image is not inserted into the button. I do not understand why.
I also tried with the following code:
if fileName != None :
fileAbsPath = os.path.abspath(fileName)
img = ImageIO.read(getClass().getResource(fileAbsPath))
self.bigDict['imgButton'].setIcon(img)
In the above example the following error is reported:
img = ImageIO.read(getClass().getResource(fileAbsPath))
TypeError: getClass(): expected 1 args; got 0
I would be curious to know why the button is not updated with the image loaded, and why the above error in java would not happen.
Thanks in advance!
getClass() needs 1 argument: the implicit this argument. You must call the method on an object, or use the MyClass.class notation.
The problem is very simple.
When an image is loaded with FileDialog it is "virtually located" in the FileDialog window, but the image does not exist. I realized this when I tried to copy the image from the absolute path to the destination folder, using shutil.copy2(self.imgAbsPath, destinationPath+'/'+self.imgName), which reported an error message indicating that the image does not exist.
To provide the concrete path of a file, it is necessary to add information about the folder where it is located.
In practice you have to create the relative path, before generating the absolute one:
fd = FileDialog(self, "Scegli un'immagine", FileDialog.LOAD)
fd.setFile(';*.'.join(("*.bmp","jpg","jpeg","wbmp","png","gif")))
fd.setVisible(True)
self.imgName = fd.getFile()
relativePath = fd.getDirectory() + fd.getFile() """Here is the missing piece!"""
if self.imgName != None:
self.imgAbsPath = os.path.abspath(relativePath) """Here the absolute path is correctly obtained!"""
self.bigDict['imgButton'].setIcon(ImageIcon(ImageIcon(self.imgAbsPath).getImage().getScaledInstance(130, 130, Image.SCALE_DEFAULT)))
"""The image, before being inserted into the button, is slightly resized, to avoid graphic bumps!"""
I hope I've been helpful.

Custom ToolBar with Java Swing for Desktop

I have created a GUI with Java Swing and wanting to create a custom toolbar according to my modules. Below are the images am wanting to use:
These images are placed in the same level as the src folder within my application. I am aware that I can perhaps create a jar with these images so that I can easily access them from within my application but do not know how. I have spent hours trying to make this work.
Below is my GUI that I have created ad wanting to beautify with these images for the toolbar else create an array of labels that will act as a navigation but either approach I couldn't get it to work.
The code below was my last attempt on this:
JToolBar toolbar1 = new JToolBar();
ImageIcon client = new ImageIcon("clients.png");
ImageIcon timesheet = new ImageIcon("timesheets.png");
JButton clientTB = new JButton(client);
JButton timesheetTB = new JButton(timesheet);
toolbar1.add(clientTB );
toolbar1.add(timesheetTB);
add(toolbar1, BorderLayout.NORTH);
I even moved these images and placed them within the class that's calling them.
What could I be doing wrong, please help?
You have a look at the JavaDocs for ImageIcon(String), the String value is "a String specifying a filename or path"
This is a problem, because your images aren't actually files, any more, they have been embedded within your application (typically within the resulting jar file) and no longer be treated like "normal files".
Instead, you need to use Class#getResource which searches the application's classpath for the named resource, something like...
// This assumes that the images are in the default package
// (or the root of the src directory)
ImageIcon client = new ImageIcon(getClass().getResource("/clients.png"));
Now, I have a personal dislike for ImageIcon, because it won't tell you when the image is loaded for some reason, like it can't be found or it's the wrong format.
Instead, I'd use ImageIO to read the image
ImageIcon client = new ImageIcon(ImageIO.read(getClass().getResource("/clients.png")));
which will do two things, first, it will throw a IOException if the image can't be loaded for some reason and two, it won't return until the image is fully loaded, which is helpful.
See Reading/Loading an Image for more details

Why is the application not showing upon adding icon to JMenuItem?

I've been running into a problem lately where I try to se a JMenuItems icon which when I define and point to the icon the application it self don't start/show.
I started looking for errors, but there where none; started looking for write occurencies, which typically pretty much does appear when I add the icon and after that as pointed above the application doesn't start/show.
When the icon is set but commented:
Code
mntmMaximize = new JMenuItem();
mntmMaximize.setText("Maximize Window");
mntmMaximize.setActionCommand("maximize");
mntmMaximize.addActionListener(this);
mntmMaximize.setMnemonic(KeyEvent.VK_PLUS);
mntmMaximize.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, ActionEvent.CTRL_MASK));
// mntmMaximize.setIcon(new ImageIcon(Vision.class.getResource("xray/fullscreen16x.png")));
mnWindow.add(mntmMaximize);<br>
Picture:
Screen Shot Of Visible Application
After the icon is set and trying to execute application:
Code:
mntmMaximize = new JMenuItem();
mntmMaximize.setText("Maximize Window");
mntmMaximize.setActionCommand("maximize");
mntmMaximize.addActionListener(this);
mntmMaximize.setMnemonic(KeyEvent.VK_PLUS);
mntmMaximize.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, ActionEvent.CTRL_MASK));
mntmMaximize.setIcon(new ImageIcon(Vision.class.getResource("xray/fullscreen16x.png")));
mnWindow.add(mntmMaximize);<br>
Picture:
The window not created and application terminated
Note that when the window is not created in this picture the application is therefor terminated.
Please try to answer nice, and if you need the whole source file it is possible.
Edit:
Also if needed i can make a video where i show when i start the application when the icon is set but not commented.
getResource uses the relative path with respect to the package (folder), like in
Vision.class.getResource("fullscreen16x.png")
or absolute like in:
Vision.class.getResource("/xray/fullscreen16x.png")

Jdialog box Title bar icon change

I need to change the Jdialog box title bar icon. By default it uses a java coffee image.
I have searched in internet and used many codes
1. Image im = Toolkit.getDefaultToolkit().getImage("/org/qmon/generate/Images/JDialog -2.ico");
dialog.setIconImage(im);
2. Toolkit kit = Toolkit.getDefaultToolkit ();
Image img = kit.getImage ("/org/qmon/generate/Images/Create File Tag-16x16.png");
dialog.setIconImage(img);
nothing works properly.. Kindly help me.. Thanks in Advance
Firtsly, ico is not a support image format for Java.
The likely reason you're having issues with the second approach is that getImage is expecting a file reference and the image you seem to referencing looks like it's embedded (stored within your application)
Try using something more like...
Image img = kit.getImage (getClass().getResource("/org/qmon/generate/Images/Create File Tag-16x16.png"));
Instead.
Personally, I prefer ImageIO.read as it throws a IOException when something goes wrong...
Image img = ImageIO.read(getClass().getResource("/org/qmon/generate/Images/Create File Tag-16x16.png"));
But that's me...
You should also consider taking a look at Convert List<BufferedImage> to Image which demonstrates the use of ico file (from a 3rd party API) and setIconImages method
Image image = ImageIO.read(new URL(
"http://www.gravatar.com/avatar/f1d58f7932b6ae8027c4e1d84f440ffe?s=128&d=identicon&r=PG"));
dialog.setIconImage( image );
dialog.setVisible(true);
I am using this in my application and working fine
java.net.URL url = ClassLoader.getSystemResource("res/java.png");
ImageIcon icon = new ImageIcon(url);
JOptionPane.showMessageDialog(null, jep, "UroSync",JOptionPane.INFORMATION_MESSAGE, icon);
To improve what MadProgrammer has said, I met the problem and I solved it instantiating a JDialog but using the static class Toolkit method getDefaultToolkit().getImage(Image img).
JDialog dialog = new JDialog();
dialog.setIconImage(Toolkit.getDefaultToolkit().getImage(MyMainClass.class.getResource("/myIcon.png")));
To do that you need to add before the image into the build path of the Project.

Programatically getting a screenshot of a Java applet

I have tried to devise a way to get a screenshot of a Java applet running in a browser, but I can't seem to get it working. I managed successfully to use cutycapt to get screenshots fine from "normal" websites, but I soon found out that qtwebkit which it seems to rely on for the rendering does not support java. I also tried IEcapt thinking that it would somehow inherit the Java rendering capabilities of IE on the system, but it does not work. Flash also does not seem to be working in IEcapt, and it has no flags for enabling plugins, so I am assuming the functionality is not there either.
Does anyone have any thoughts on how you could render something like an /index.jsp to an image from a Windows or Linux command line?
Selenium webdriver might be useful here:
http://docs.seleniumhq.org/projects/webdriver/
It is used primarily for test automation but it might be helpful.
It could be used, for example, like this:
import org.openqa.selenium.*;
WebDriver driver = new FirefoxDriver(); // create a Firefox webdriver instance
driver.get("http://www.google.com/"); // navigate to page
File screenshotFile = ((Screenshot)driver).getScreenshotAs(file); // capture screenshot
// and save to a file
// here you can trigger any necessary actions on the website:
Webelement element = driver.findElement(By.name("q")).sendKeys("xxxxx");
element.click();
new WebDriverWait(driver, 10)).until(ExpectedConditions.titleContains("xxxxx"));
// and capture a new screenshot once the content has changed
File xxxScreenshotFile = ((Screenshot)driver).getScreenshotAs(file);
Have you tried using java.awt.Robot?
Rectangle rect = yourGragphicsConfiguration.getBounds();
BufferedImage image = new Robot().createScreenCapture(rect);
If you know the position of your applet you might be able to get it with
BufferedImage dest = image.getSubimage(appletX, appletY, appletHeight, appletWidth);
You can take a screenshot of Swing/AWT component.
This can be done in 2 ways. In both cases the component must be visible.
Without the robot use:
BufferedImage image = new BufferedImage(component.getWidth(),
component.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
component.paint(g);
With the robot use:
In this case the screenshot of area in which this component is situated will be made. That is, if the component overlaps another application window then the screenshot will contain an area of this another window.
Point point = new Point(0, 0);
SwingUtilities.convertPointToScreen(point, component);
Rectangle region = component.getBounds();
region.x = point.x;
region.y = point.y;
BufferedImage image= new Robot().createScreenCapture(region);
This information is taken from the article: Frequently Asked Questions during Java applet development

Categories