Animated GIF in Java Application is throwing MalformedURLException - java

I want to show an animated gif in my application. I followed the code found here: Show animated GIF
When I run my code I get the MalformedURLException error and my application will not run. Here is what I have that's not working.
The method that calls createVisuals():
private void defaultGUI() {
frame.setTitle("Class Map");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout(FlowLayout.LEADING, 0, 0));
frame.setBounds(0, 0, frameWidth, frameWidth/2);
frame.getContentPane().setBackground(Color.WHITE);
frame.setUndecorated(true);
try {
Visuals.createVisuals();
} catch (MalformedURLException e) {
e.printStackTrace();
}
frame.pack();
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
}
The method that shows the gif:
public class Visuals {
public static void createVisuals() throws MalformedURLException{
URL cwURL = new URL("src\\images\\classmap_colorwheel-gif.gif");
Icon cwGif = new ImageIcon(cwURL);
JLabel cwIcon = new JLabel(cwGif);
GUI.frame.getContentPane().add(cwIcon);
}
What am I not doing correctly?
EDIT:
laksys pointed out that my URL constuction was wrong and gave a reference to fix it. The problem was that I was not giving the full file location alongside adding File: to the begining of the URL.
URL cwURL = new URL("src\\images\\classmap_colorwheel-gif.gif");
URL cwURL = new URL("File:C:/Users/01526460/Desktop/ClassMap/src/images/classmap_colorwheel-gif.gif");
This caused the exception to disappear, however the gif is not running properly. Only one frame of the gif sequence loads while the others only partially load. The gif is also looping faster than it should.
EDIT 2:
I figured out that the gif was not looping properly because of the way I made it, not because of Java. I used Photoshop CS6 to create a frame animation. When I ran the frame animation at 0 second delay between frames it looked fine in Photoshop. However, when the 0 second delay is interpreted through Java, the gif is actually trying to go 0 seconds between frames. If anyone else encounters this problem make sure the delay between your frames is not set to 0. Java does not automatically control the frame rate of gifs (like many browsers do).

I think your url construction is wrong. It may have protocol, host, port etc., please ref this

Related

Swing Paint Issues On Secondary Monitor?

I recently ran into an issue that I cannot explain. Hopefully someone knows what I can do to resolve my issue. I have a dual monitor machine running Windows 7 64-bit. Both monitors are identical models and settings. The primary monitor is on the right. I am using JRE 1.8.0_131
The issue I am seeing is that recently I discovered I am no longer able to run my Java Swing application on my second monitor. This was working perfectly fine before, as in I could move my application between both monitors, resizing and switching to/from maximized with no problems. Now whenever my application is on my second monitor, all I see is a frame that shows the part of my desktop background that is behind the frame
Below is a small sample program that creates a frame for each monitor. The frame on my primary monitor looks fine. The one on my secondary monitor is messed up like I mentioned. Simply moving the bad frame to my primary monitor does nothing to fix it but if I minimize then restore it looks fine (i.e. if I force the frame to repaint on the primary monitor it looks fine). Similarly, moving the good frame to the secondary monitor and forcing a repaint results in the bad frame
My JRE has not been updated in months so that does not seem like the issue. As an experiment I tried using JDK 1.7.0_17 but it has the same results. My machine got a Windows update yesterday which maybe coincidentally is when I noticed this issue. I am not saying that is the issue, just noting the information I have
Anyhow, any thoughts or suggestions would be greatly appreciated. This issue is annoying since dual monitor support is helpful for having my application and Eclipse visible at the same time, as well as the fact that my application has multiple frames which I placed one per monitor
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
for (final GraphicsDevice device : GraphicsEnvironment
.getLocalGraphicsEnvironment().getScreenDevices())
{
final DisplayMode displayMode = device.getDisplayMode();
LOGGER.debug(
"testSwing: device: {}, ID string: {}, isFullScreenSupported: {}, "
+ "displayModeWidth: {}, displayModeHeight: {}, "
+ "displayModeBitDepth: {}, displayModeRefreshRate: {}", device,
device.getIDstring(), device.isFullScreenSupported(),
displayMode.getWidth(), displayMode.getHeight(), displayMode.getBitDepth(),
displayMode.getRefreshRate());
if (GraphicsDevice.TYPE_RASTER_SCREEN == device.getType())
{
final GraphicsConfiguration configuration =
device.getDefaultConfiguration();
final JFrame frame = new JFrame("Test Frame", configuration);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(
new JLabel(device.getIDstring(), SwingConstants.CENTER));
final Rectangle screenBounds = configuration.getBounds();
frame.setBounds((screenBounds.x + (screenBounds.width / 2)) - 100,
(screenBounds.y + (screenBounds.height / 2)) - 100, 200, 200);
frame.setVisible(true);
}
}
}
});
NOTE: LOGGER is just a SLF4J logger which I added only to see if there was any useful information I could gather. This can be removed when running as it has no effect on the issue described above
Output from running this on my machine:
testSwing: device: Win32GraphicsDevice[screen=0], ID string: \Display0, isFullScreenSupported: true, displayModeWidth: 1920, displayModeHeight: 1200, displayModeBitDepth: 32, displayModeRefreshRate: 59
testSwing: device: Win32GraphicsDevice[screen=1], ID string: \Display1, isFullScreenSupported: true, displayModeWidth: 1920, displayModeHeight: 1200, displayModeBitDepth: 32, displayModeRefreshRate: 59
It is happening because moving your application has contents which is not updating when it is moving to another monitor and still trying to get data from initial monitor.
Try this link. Its about displaying JFrame on multiple monitors. Hope this will help.
how to display JFrame in full screen display mode at a multi-monitor environment?

How to add a seekbar to a video played using vlcj in Java Swing?

I’ve trimmed down the code to only the relevant parts and posted it below. The code works fine. The video plays when you run it but it doesn’t have a seekbar.
public class Screen {
//JFrmae
private JFrame frame;
// Panel which I add the canvas to
private JPanel pVid = new JPanel();
// Canvas
Canvas canvas = new Canvas();
// Embedded Media Player
EmbeddedMediaPlayer emp;
/**
* Create the application.
*/
public Screen() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
//Frame
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
//Adding the panel to the frame
frame.getContentPane().add(pVid);
//Adding the canvas to the panel
pVid.add(canvas);
//Setting canvas size
canvas.setSize(715, 402);
//Loading the VLC native library
NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), "lib");
Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);
//Initializing the media player
MediaPlayerFactory mpf = new MediaPlayerFactory();
//Misc
emp = mpf.newEmbeddedMediaPlayer(new Win32FullScreenStrategy(frame));
emp.setVideoSurface(mpf.newVideoSurface(canvas));
//Video file name and playing
String file = "video.mp4";
emp.prepareMedia(file);
emp.play();
//pack method
frame.pack();
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Screen window = new Screen();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
I’ve looked for an answer online for the last 4 days. Finally I decided to ask here. The official website for vlcj has pictures of a vlcj player they’ve made. There is a seekbar in those pictures. Link to the webpage which has the pics: http://capricasoftware.co.uk/#/projects/vlcj
They have a number of useful tutorials there but they don’t have any instructions for adding the seekbar.
Then I tried downloading their vlcj-player project from their GitHub page. It showed an error because it couldn’t resolve the “com.google.common.collect.ImmutableList” which is supposed to be imported. (At the moment I’m reading about ImmutableList and stuff and see if there’s a way to fix it.) Since I couldn’t figure that out yet, I looked for a class named seekbar or the like in their project. I couldn’t find any.
I also searched elsewhere online for the answer but I just couldn’t find it. I’d really appreciate any help. Thank you.
Edit:
(This edit is in response to the suggestion given to me by #caprica. Read their comment to this question and my reply to that in the comment to understand what I'm talking about here in this edit. I think it'll be useful for others in the future.)
All right, there must have been some problem with my Eclipse or computer. (I’ll type out how I fixed it at the end of this comment.) It’s working now. I’ll type out what I did step by step so that may be it’ll be useful to others in the future to download and install the project.
Download the project.
Import it as a Maven project. (Import > Maven > Existing Maven Project)
Now in Eclipse right click the imported project and select Run As > Maven Install
And that’s it. Now you can just run the project normally. If you don’t know how to run the project, do it like this. Right click the project and select Run As > Java Application and then Select VlcjPlayer – uk.co.caprica.vlcplayer.
Alternatively you can open the class where the main method is and run it. VlcjPlayer class is where the main method is located. The class is in the package uk.co.caprica.vlcplayer.
The problem I faced was that somehow all the necessary files didn’t get downloaded when I ran it as Maven Install. But it worked fine in another computer. Since I knew where the files are downloaded to, I just copied the folder from that PC and put it in the same place in my PC. The folder name is ‘repository’. It’s location is C:\Users\User Name\ .m2. Perhaps Eclipse in this PC has some problem. I’ll reinstall it later to avoid problems in the future.
And this may be useful, the VLC that’s installed in this PC is 64 bit. Not sure if that makes a difference but mentioning it just in case.
Now that the app is working fine I will see the code and see how the seekbar is made. Thanks a lot #caprica for telling me that I should import it as a Maven project. :)
The Basic Controls tutorial shows the essential approach: Add a panel of buttons to the frame and give each button an ActionListener that invokes the relevant media player command. As an example, this notional Rewind button would "skip backwards 10 seconds (-10,000 milliseconds)."
JPanel controlsPane = new JPanel();
JButton rewindButton = new JButton("Rewind");
rewindButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
mediaPlayerComponent.getMediaPlayer().skip(-10000);
}
});
controlsPane.add(rewindButton);
frame.add(controlsPane, BorderLayout.SOUTH);
The software design is up to you, but you should at least be aware of
JToolBar, seen here and here.
Action, seen here and cited here.
Timer, seen here as a way to repeat an Action.
All right, guys. I’ve figured out how to do it. I’m not sure how it was done in the official Vlcj project but I’ve figured out my own simple way by learning from the official project.
It just takes a few lines of code. It’s very simple.
These are the steps you have to follow:
Create a JSlider.
To the JSlider, add a mouseMotionListener (‘mouseDragged’ to be exact).
Inside that put in the code which would update the video position based on
the change in the JSlider.
Create a Timer.
Put the code inside it to set the value of the JSlider based on the position
of the video.
And that’s it!
This is the code. It comes inside the initialize() method which you can see in the code I’ve given in the question. (And of course you'll also have to create the JSlider and add it to the panel. I haven't shown the code since it's simple.)
js.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
if (js.getValue() / 100 < 1) {
emp.setPosition((float) js.getValue() / 100);
}
}
});
Timer timer = new Timer(100, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
js.setValue(Math.round(emp.getPosition() * 100));
}
});
timer.start();
Some explanation.
The value you get when you use emp.getPosition always seems to be in decimals. It’s something like 0.1334344 at the start of the video and it’s something like 0.998988 at the end. But the value of JSlider is in int. From 0 to 100. So in the mouseMotionListener added to the JSlider I’ve converted the int value of the JSlider to float by dividing it by 100.
And in the action listener inside the timer I’ve multiplied the value of the video position by 100 and then rounded it off to make it an int value. So that value can be set in the JSlider to make it move in sync with the video.
I’m sure the code is rudimentary and there could be some best practices which I may not have followed. Sorry about that but I’m just getting into java by learning the stuff which I find interesting. Those who are good at java and have used such code in an actual project can comment below with how it can be improved.

JFrame Icon Resolution

I'm quite new to working with java GUIs. To start me up, I had a look into JFrame. While playing around with it, I used the setIconImage() method to set the logo of my JFrame. However, when I run the file, the logo resolution gets reduced so much that I can barely recognise it. Here's my current code and the dimensions of my image is 1280 x 1280 (I have tried reducing it down to 100 x 100 but it still returned the same results.):
#SuppressWarnings("serial")
public class GUIManager extends JFrame{
public void openGUI(String value){
if(value.equalsIgnoreCase("startMenu")){
GUIManager manager = new GUIManager();
ImageIcon logo = new
ImageIcon(ResourcesLoader.class.getResource("Logo.png"));
manager.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
manager.setVisible(true);
manager.setResizable(false);
manager.setLocationRelativeTo(null);
manager.setSize(300, 500);
manager.setBackground(Color.WHITE);
manager.setTitle("FileLocker");
manager.setIconImage(logo.getImage());
} //value check
} //openGUI
} //GUIManager
The answer is given Before go to following link
Sizes of frame icons used in Swing
Which icon sizes to use with a JFrame's setIconImages() method?

Using a custom cursor

I've searched quite a few threads here but none have helped.
I have a few JFrames and each JFrame should have its own individual cursor, symbolizing which version of the program the user is using.
These files are in /AndroidToolkit/resources. The files are all .cur files, so they're actually proper cursors and not just images.
I've tried a few methods of doing this, but I have succeeded. I've tried using ImageIO, Toolkit, and my last try was:
Cursor cCur = Toolkit.getDefaultToolkit().createCustomCursor(getClass().getResource("../resources/ImpressionCursor.cur").getFile()., null, null);
How can I do this in an easy way, which is easy for other people to understand, without me having to always comment it with 10k lines?
Thanks in advance,
Beats
This is what you need, try this code 100% works for me on Ubuntu 12.04 LTS, it should work for you too:
public static void main(String[] args) {
Toolkit toolKit = Toolkit.getDefaultToolkit();
Image pencil = toolKit.getImage("pencil.gif");
Cursor cursor = toolKit.createCustomCursor(pencil, new Point(0, 0), "Pencil");
JFrame frame = new JFrame("Cursor Test");
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setCursor(cursor);
frame.setVisible(true);
}
this is the link for the gif file click here,
I hope that helps, Salam

Frame Showing Problem

I have made one project which is showing the inventory of the stock of one store.
In that inventory the software should store data of the products with their images.
There is one problem...
Bcz of the lots of stock, the screen on which is image is loading taking a lot of time.
So, i thought i should give the frame in which there will be on label which will show the "Loading Software".
But now when i am setting visible = true for that frame, but bcz of that images screen class loading problem my frame is not showing correctly. I have put screen shot, now my code.
JFrame f;
try{
f = new JFrame("This is a test");
f.setSize(300, 300);
Container content = f.getContentPane();
content.setBackground(Color.white);
content.setLayout(new FlowLayout());
JLabel jl = new JLabel();
jl.setText("Loading Please Wait....");
content.add(jl);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}catch(Exception e){
e.printStackTrace();
}
initComponents();
try {
addInverntory = new AddInventoryScreen();
showstock = new showStock(); // this class will take big time.
mf = new mainForm();
f.setVisible(false);
}catch (Exception ex) {
ex.printStackTrace();
}
How Can show some message that, other class is loading or "Loading Software" kind of thing in this situation.
Just For the know....this class is not screen on which the image will load.
It's hard to answer this because it's not clear what the effects (Swing-wise) are of the calls to new AddInventoryScreen(); and new showStock();. You should only touch the UI that the user sees right at the end (when all the processing is done).
You should really spin off methods that will take a long time into their own Thread (see SwingWorker. There are alternatives for Java 5.0). That way, the UI won't be blocked while it's processing.
Maybe what you want is a Splash Screen?
Try calling validate(); and pack(); methods before calling f.setVisible(true);
Your code can be
validate();
pack();
f.setVisible(false);
I think one big problem in your code (maybe not the only one however) is the fact that you should use a different thread for long operations.
GUI operations (creating swing components, adding them to panels, changing labels...) are to be performed exclusively in the "EDT" and must be short (typically, less than 100ms or even 50ms).
Long operations can be easily done by another thread if you use the SwingWorker API (part of JDK 1.6).

Categories

Resources