Why getClass() used in the piece of code? - java-me

I am trying to access the audio file from the jar,for doing that i wrote a code,like
...
try {
InputStream is =
getClass().getResourceAsStream("audio.wav");
Player player = Manager.createPlayer(is, "audio/X-wav");
p.start();
}
catch(IOException ioe) {
}
catch(MediaException me) {
}
...
but here in this snippet,what is the use of getClass()?

It allows you to get the class of the current object, so in turn you can access resources. getResourceAsStream loads resources from the class loader associated with the class. See the documentation for Object.getClass and Class.getResourceAsStream.

Related

Writing my own image importer, pictures are not recognized as pictures after import

i am writing my own image import for my product catalog. I want to read the images from the local filesystem and store them in the configured assets folder. The import is very simple for now. Its one controller in the admin project and i trigger it by calling an url.
It is creating the files along with the folder structure and the files seem to have the same filesize, but somehow they get messed up along the way and they are not readable as images anymore (picture viewers wont open them). Any ideas why its being messed up ?
here the code:
#Controller("blImageImportController")
#RequestMapping("/imageimport")
public class ImageImportController extends AdminAbstractController {
#Value("${image.import.folder.location}")
private String importFolderLocation;
#Resource(name = "blStaticAssetService")
protected StaticAssetService staticAssetService;
#Resource(name = "blStaticAssetStorageService")
protected StaticAssetStorageService staticAssetStorageService;
#RequestMapping(method = {RequestMethod.GET})
public String chooseMediaForMapKey(HttpServletRequest request,
HttpServletResponse response,
Model model
) throws Exception {
File imageImportFolder = new File(importFolderLocation);
if (imageImportFolder.isDirectory()) {
Arrays.stream(imageImportFolder.listFiles()).forEach(directory ->
{
if (directory.isDirectory()) {
Arrays.stream(directory.listFiles()).forEach(this::processFile);
}
});
}
return "";
}
private void processFile(File file) {
FileInputStream fis = null;
try {
HashMap properties = new HashMap();
properties.put("entityType", "product");
properties.put("entityId", file.getParentFile().getName());
fis = new FileInputStream(file);
StaticAsset staticAsset = this.staticAssetService.createStaticAsset(fis, file.getName(), file.length(), properties);
this.staticAssetStorageService.createStaticAssetStorage(fis, staticAsset);
fis.close();
} catch (Exception e) {
} finally {
try {
if (fis != null)
fis.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
There is a check in the StaticAssetService to try to detect this as an image (see https://github.com/BroadleafCommerce/BroadleafCommerce/blob/b55848f/admin/broadleaf-contentmanagement-module/src/main/java/org/broadleafcommerce/cms/file/service/StaticAssetServiceImpl.java#L217-L220). If it detected this correctly, you should get back an ImageStaticAssetImpl in the result to that call.
The flipside of this is the controller that actually reads the file (the StaticAssetViewController that renders a StaticAssetView). One of the things that the StaticAssetView does is set a response header for mimeType which the browser uses to render. This is set by this piece in the StaticAssetStorageService: https://github.com/BroadleafCommerce/BroadleafCommerce/blob/b55848f837f26022a620f0c2c143eed7902ba3f1/admin/broadleaf-contentmanagement-module/src/main/java/org/broadleafcommerce/cms/file/service/StaticAssetStorageServiceImpl.java#L213. I suspect that is the root of your problem.
Also just a note, sending those properties is not necessary when you are uploading the file yourself. That is mainly used in the admin when you are uploading an image for a specific entity (like a product or a category).

How to load properties file in a JSF application? [duplicate]

This question already has answers here:
Where to place and how to read configuration resource files in servlet based application?
(6 answers)
Closed 7 years ago.
I'm trying to load a properties file in a JSF application I'm working on, though I can't manage to reference the file.
package com.nivis.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PropHandler {
String result = "";
InputStream inputStream;
public void loadProp() {
try {
inputStream = this.getClass().getResourceAsStream("prop.properties");
if (inputStream == null) {
System.err.println("===== Did not load =====");
} else {
System.err.println("===== Loaded =====");
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public static void main(String[] args) {
PropHandler ph = new PropHandler();
ph.loadProp();
}
}
The file is located in the same package and in the different examples I've found when searching for this, that should work. I've also tried to put the file in every conceivable place in the application and reference it to the best of my knowledge, but it does not work.
(only some of the folders that I've tested to put the file)
What am I doing wrong?
Optimally I'd like to have it in the same folder that I use for the msg.properties file.
As this answer elaborates, com/nivis/prop.properties should be the right way to reference the file nested in your resources folder.
But because you're not using ClassLoader classloader = Thread.currentThread().getContextClassLoader(); to locate the Classloader you have to use an absolute path starting with "/" resulting in /com/nivis/prop.properties.
try something like this
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
InputStream is = classloader.getResourceAsStream("prop.properties");

Downloads with JavaFX WebView

my web application offers a download. Javascript creats at the click the url (it depends on the user input) and the browser should open it, so that the page isn't reloaded.
For that, I think I have to alternatives:
// Alt1:
window.open(pathToFile);
// Alt2:
var downloadFrame = document.getElementById('downloads');
if (downloadFrame === null) {
downloadFrame = document.createElement('iframe');
downloadFrame.id = 'downloads';
downloadFrame.style.display = 'none';
document.body.appendChild(downloadFrame);
}
downloadFrame.src = pathToFile;
Both works under Firefox. Problem with open new window method: If the creation of the file at the server needs more time, the new empty tab will be closed late.
Problem with iframe: If there is an error at the server, no feedback is given.
I think at firefox the iframe is the better solution. But the web application must run with an JavaFX WebView, too. JavaFX haven't a download feature, I have to write it. One possible way is to listen on the location property:
final WebView webView = new WebView();
webView.getEngine().locationProperty().addListener(new ChangeListener<String>() {
#Override public void changed(ObservableValue<? extends String> observableValue, String oldLoc, String newLoc) {
if (newLoc.cotains("/download")) {
FileChooser chooser = new FileChooser();
chooser.setTitle("Save " + newLoc);
File saveFile = chooser.showSaveDialog(webView.getEngine().getScene().getWindow());
if (saveFile != null) {
BufferedInputStream is = null;
BufferedOutputStream os = null;
try {
is = new BufferedInputStream(new URL(newLoc).openStream());
os = new BufferedOutputStream(new FileOutputStream(saveFile));
while ((readBytes = is.read()) != -1) {
os.write(b);
}
} finally {
try { if (is != null) is.close(); } catch (IOException e) {}
try { if (os != null) os.close(); } catch (IOException e) {}
}
}
}
}
}
There are some problems:
The download start depends on a part of the url, because JafaFX supports no access to the http headers (that is bearable)
If the user starts the download with the same url two times, only the first download works (the change event only fires, if the url is new). I can crate unique urls (with #1, #2 and so on at the end). But this is ugly.
Only the "window.open(pathToFile);" method works. Loading an iframe don't fire the change location event of the website. That is expectable but I haven't found the right Listener.
Can someone help me to solve 2. or 3.?
Thank you!
PS: Sorry for my bad english.
edit:
For 2. I found a way. I don't know if it is a good one, if it is performant, if the new webview is deleted or is in the cache after download, ....
And the user don't get an feedback, when some a problem is raised:
webView.getEngine().setCreatePopupHandler(new Callback<PopupFeatures, WebEngine>() {
#Override public WebEngine call(PopupFeatures config) {
final WebView downloader = new WebView();
downloader.getEngine().locationProperty().addListener(/* The Listener from above */);
return downloader.getEngine();
}
}
I think you may just need to use copyURLtoFile to get the file...call that when the location changes or just call that using a registered java class. Something like this:
org.apache.commons.io.FileUtils.copyURLToFile(new URL(newLoc), new File(System.getProperty("user.home")+filename));
Using copyURLToFile the current page doesn't have to serve the file. I think registering the class is probably the easiest way to go... something like this:
PHP Code:
Download $filename
Java (in-line class in your javafx class/window... in this case my javafx window is inside of a jframe):
public class JavaApp {
JFrame cloudFrameREF;
JavaApp(JFrame cloudFrameREF)
{
this.cloudFrameREF = cloudFrameREF;
}
public void getfile(String filename) {
String newLoc = "http://your_web_site.com/send_file.php?filename=" + filename;
org.apache.commons.io.FileUtils.copyURLToFile(new URL(newLoc), new File(System.getProperty("user.home")+filename));
}
}
This part would go in the main javafx class:
Platform.runLater(new Runnable() {
#Override
public void run() {
browser2 = new WebView();
webEngine = browser2.getEngine();
appREF = new JavaApp(cloudFrame);
webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener<State>() {
#Override public void changed(ObservableValue ov, State oldState, State newState) {
if (newState == Worker.State.SUCCEEDED) {
JSObject win
= (JSObject) webEngine.executeScript("window");
// this next line registers the JavaApp class with the page... you can then call it from javascript using "app.method_name".
win.setMember("app", appREF);
}
}
});
You may not need the frame reference... I was hacking some of my own code to test this out and the ref was useful for other things...

Unity3D : Retry Menu (Scene Management)

I'm making a simple 2D game for Android using the Unity3D game engine. I created all the levels and everything but I'm stuck at making the game over/retry menu. So far I've been using new scenes as a game over menu. I used this simple script:
#pragma strict
var level = Application.LoadLevel;
function OnCollisionEnter(Collision : Collision)
{
if(Collision.collider.tag == "Player")
{
Application.LoadLevel("GameOver");
}
}
And this as a 'menu':
#pragma strict
var myGUISkin : GUISkin;
var btnTexture : Texture;
function OnGUI() {
GUI.skin = myGUISkin;
if (GUI.Button(Rect(Screen.width/2-60,Screen.height/2+30,100,40),"Retry"))
Application.LoadLevel("Easy1");
if (GUI.Button(Rect(Screen.width/2-90,Screen.height/2+100,170,40),"Main Menu"))
Application.LoadLevel("MainMenu");
}
The problem stands at the part where I have to create over 200 game over scenes, obstacles (the objects that kill the player) and recreate the same script over 200 times for each level. Is there any other way to make this faster and less painful?
Edit : If possible,please when you suggest your ideas,use javascript only,I don't understand C#,not even a little bit.I know Im asking too much but it realy confuses me.
Thank you.
There are several different solutions, but I would recommend using PlayerPrefs. This has the extra benefit of persisting even when the application is closed and then re-opened.
In your Awake() function of your Main Menu class, you can get the current level and store it in a static string of your Main Menu class. If it is the player's 1st time, use the name for level 1.
Something like this:
static string currentLevelName;
void Awake()
{
currentLevelName = PlayerPrefs.GetString("CurrentLevel");
if (currentLevelName == defaultValue)
{
currentLevelName = "Level1"
}
}
Then, modify your button to do this instead:
if (GUI.Button(Rect(Screen.width/2-60,Screen.height/2+30,100,40),"Retry"))
Application.LoadLevel(currentLevelName);
Whenever the player advances to the next level, set the string in PlayerPrefs to the new level name:
PlayerPrefs.SetString("CurrentLevel", Application.loadedLevelName);
You can create a class with static properties. For example (in c#)
public class GameOverInput
{
public static string name;
public static string retryLevel;
//all the info you need
}
Then you can easily read the input in your game over scene (only one is needed)
public class GameOverMenu : MonoBehavior
{
void Start()
{
Debug.Log("You were killed by " + GameOverInput.name);
Application.LoadLevel(GameOverInput.retryLevel);
}
}
And you set this info just before loading the game over scene
if (Collision.collider.tag == "Player")
{
GameOverInput.name = "Baddie";
Application.LoadLevel("GameOver");
}
Another option would be to make something like a singleton LevelManager MonoBehavior and add it to an object named "Level Manager". Use the DontDestroyOnLoad function to make the object persist even when you load another level.
class LevelManager : MonoBehavior
{
static LevelManager _instance;
public string currentLevelName;
public string killedBy;
function Awake ()
{
if (_instance == null)
{
_instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject); // Make sure we never have more than 1 Level Manager.
}
}
LevelManager Instance
{
get
{
if (_instance == null)
{
GameObject levelManagerObject = GameObject.Find("Level Manager");
_instance = levelManagerObject.GetComponent<LevelManager>();
}
return _instance
}
}
}
Then, from the main menu class, you can always access the Level Manager like so:
Debug.Log("Killed by " + LevelManager.Instance.killedBy);
or
LevelManager.Instance.currentLevelName = Application.loadedLevelName;

media metadata observable map is null in java fx media

Hi guys I tried to play a song and print its metadata using java fx 2.1 api using the following code
Media media = new Media(UIandControls.class.getResource("/assets/testData/mom.mp3").toExternalForm());
MediaPlayer mediaPlayer = new MediaPlayer(media);
ObservableMap list=media.getMetadata();
System.out.print(list);
mediaPlayer.play();
for some reason getMetadata() is empty observable Map.
Output looks like this
{}
plz help me.. Thank you.
Need to call mediaPlayer.play() before retrieving metadata.
I had troubles with this at first but I found that using this worked.
mediaPlayer.getMedia().getMetadata().addListener(new MapChangeListener<String, Object>(){
#Override
public void onChanged(Change<? extends String, ?> change) {
if(change.wasAdded()){
if(change.getKey().equals("artist"))
setArtist(change.getValueAdded().toString());
else if(change.getKey().equals("title"))
setTitle(change.getValueAdded().toString());
else if(change.getKey().equals("year"))
setYear(change.getValueAdded().toString());
}
}
});
Also I read that the media data won't always be there right after initialization, therefore calling the mediaPlayer.setOnReady() method can make sure that the data is there.
Example:
mediaPlayer.setOnReady(new Runnable(){
#Override
public void run() {
setTrackLength(mediaPlayer.getMedia().getDuration().toMinutes());
mediaPlayer.currentTimeProperty().addListener(progressChangeListener);
}
});

Resources