Change Value of String Based on Media Metadata - java

I have a simple media player and in one of the classes I need to retrieve the metadata of the media. Thus far, I have successfully extracted the metadata, however when I attempt to use the values, the Strings returned are blank.
String album = "", artist = "", title = "", year = "";
...
public void addListItems(final Pane layout, final Stage stage, final Scene scene) {
String[] sList = s.split("\\\\");
try {
Media media = new Media(new File(s).toURI().toURL().toString());
media.getMetadata().addListener(new MapChangeListener<String, Object>() {
public void onChanged(Change<? extends String, ? extends Object> arg0) {
handleMetadata(arg0.getKey(), arg0.getValueAdded());
}
});
} catch (MalformedURLException e) {
e.printStackTrace();
}
System.out.println(album); //Here, album returns as ""
final Button lab = new Button(album + "--" + sList[sList.length - 1]);
}
...
public void handleMetadata(String key, Object value) {
if (key.equals("album")) {
album = value.toString(); //Here album returns as value.toString() correctly
} else if (key.equals("artist")) {
artist = value.toString();
} else if (key.equals("title")) {
title = value.toString();
} else if (key.equals("year")) {
year = value.toString();
}
}
I have done research on this topic, but the results I viewed did not help my circumstance. I greatly appreciate any assistance.

Related

How to cache search results retrieved from auto-complete API

I've been working on a searching auto-complete feature with Bootstrap-3-Typeahead ,GWT and data comes from http://dawa.aws.dk/dok/api by JsonP request..
The Typahead creation method is below
private Typeahead<Location> createTypeAhead() {
typeAhead = new Typeahead<>(new Dataset<Location>() {
#Override
public void findMatches(final String query, final SuggestionCallback<Location> callback) {
requestCounter--;
startSendingRequest = true;
clear.setIcon(IconType.SPINNER);
clear.setIconSpin(true);
final Set<Suggestion<Location>> suggestions = new HashSet<>();
queryLower = query.toLowerCase();
JsonpRequestBuilder jsonpRequestBuilder;
if (!streetSelected) {
jsonpRequestBuilder = new JsonpRequestBuilder();
jsonpRequestBuilder.requestObject("https://dawa.aws.dk/vejnavne/autocomplete?side=1&per_side=500&noformat=1&q=" + queryLower + "*", new AsyncCallback<MyJsArray<VejAutocomplete>>() {
#Override
public void onFailure(Throwable caught) {
Notify.notify("suggestion matches failed");
}
#Override
public void onSuccess(MyJsArray<VejAutocomplete> result) {
Set<Location> locationSet = new LinkedHashSet<>();
for (VejAutocomplete item : result.getAsList()) {
String lowerCase = item.getTekst().toLowerCase();
if (lowerCase.startsWith(queryLower)) {
locationSet.add(new Location(Location.LocationType.STREET, item.getTekst(), item));
locationArrayList.clear();
locationArrayList.addAll(locationSet);
}
}
}
});
}
for (Location address : locationArrayList) {
String value = address.getValue();
Suggestion<Location> s = Suggestion.create(value, address, this);
if (address.getValue().toLowerCase().startsWith(queryLower)) {
suggestions.add(s);
}
}
callback.execute(suggestions);
if (typeAhead.getValue().length() != 0 && queryLower.length() <= 5 && requestCounter < 5 && requestCounter > 0) {
new Timer() {
#Override
public void run() {
findMatches(queryLower, callback);
}
}.schedule(500);
} else {
clear.setIconSpin(false);
clear.setIcon(IconType.CLOSE);
requestCounter = 5;
}
}
});
return typeAhead;
}
The result is like below:
I used recursion to send 4-5 times of request because it's not showing the suggestion list with the keyword of single letter. And It still won't work with some single letters like "s" or "e". Data successfully retrieved from the API but doesn't show in the suggestion list like below:
I assume that I should cache all search results then recreate the auto-complete from scratch, it becomes complicated in that case.
Any good idea to solve this problem?

How to show coordinates-markers on Android App with Google Maps from XML file

I have an xml file with some places in it and their coordinates. I want to show those places on my android app on Google Maps as markers. I have already load the maps.
How could I do this? Any help would be so much appreciated, even if someone could explain it theoritically, as it seems I cant grasp its concept. Can someone help?
example of xml file(placesp.xml):
<placesp>
<placep>
<place_id>1</place_id>
<name>Place1</name>
<description>Place description 1</description>
<coordinates>;40.430224;21.559570</coordinates>
</placep>
<placep>
<place_id>2</place_id>
<name>Place2</name>
<description>Place description 2</description>
<coordinates>;40.423324;21.062439</coordinates>
</placep>
<placep>
<place_id>3</place_id>
<name>Place3</name>
<description>Place description 3</description>
<coordinates>;40.266952;21.238220</coordinates>
</placep>
</placesp>
Maybe you could use a HashMap to save the data.
You just create a new class like this:
public class Coordinates {
public static final HashMap<String, LatLng> COORDINATES = new HashMap<String, LatLng>();
static {
// Place1
COORDINATES.put("Place1", new LatLng(40.430224;21.559570));
}
}
You can access the data stored by the hashmap like this:
locationLatLng = new LatLng(Coordinates.COORDINATES.get("Place1").latitude,Coordinates.COORDINATES.get("Place1").longitude);
And then using this line in the class where you loaded the map to add the markers:
map.addMarker(new MarkerOptions().position(locationLatLng));
I am not really sure how to access data from the xml file, but in theory the logic is the same. You have to get a LatLng coordinate to tell the addMarker method where to put the marker, and thats actually it. I hope I could help you with this.
First you need to create a model class to hold the information for each place. I provide you a sample bellow: Place.class
public class Place {
private int placeId;
private String placeName;
private String placeDescription;
private double placeLongitude;
private double placeLatitude;
public Place() {
super();
}
public int getPlaceId() {
return placeId;
}
public void setPlaceId(final int placeId) {
this.placeId = placeId;
}
public String getPlaceName() {
return placeName;
}
public void setPlaceName(final String placeName) {
this.placeName = placeName;
}
public String getPlaceDescription() {
return placeDescription;
}
public void setPlaceDescription(final String placeDescription) {
this.placeDescription = placeDescription;
}
public double getPlaceLongitude() {
return placeLongitude;
}
public void setPlaceLongitude(final double placeLongitude) {
this.placeLongitude = placeLongitude;
}
public double getPlaceLatitude() {
return placeLatitude;
}
public void setPlaceLatitude(final double placeLatitude) {
this.placeLatitude = placeLatitude;
}
}
Next you will need a XML parser class to retrieve XML data to Place type list. You can use the following sample: PlaceXmlParser.class
public class PlaceXmlParser {
private static final String TAG = PlaceXmlParser.class.getSimpleName();
private static final String PLACE_ID = "place_id";
private static final String PLACE_NAME = "name";
private static final String PLACE_DESCRIPTION = "description";
private static final String PLACE_COORDINATES = "coordinates";
public PlaceXmlParser() {
super();
}
public List<Place> parsePlacesXml(final InputStream xmlStream) {
Place place = null;
final List<Place> placeList = new ArrayList<>();
try {
final XmlPullParserFactory xmlFactoryObject = XmlPullParserFactory.newInstance();
final XmlPullParser parser = xmlFactoryObject.newPullParser();
parser.setInput(xmlStream, null);
int event = parser.getEventType();
while (event != XmlPullParser.END_DOCUMENT) {
if (event == XmlPullParser.START_TAG) {
final String name = parser.getName();
switch (name) {
case PLACE_ID:
place = new Place();
setPlaceId(parser, place);
break;
case PLACE_NAME:
setPlaceName(parser, place);
break;
case PLACE_DESCRIPTION:
setPlaceDescription(parser, place);
break;
case PLACE_COORDINATES:
setPlaceLatLong(parser, place);
placeList.add(place);
break;
}
}
event = parser.next();
}
} catch (final XmlPullParserException e) {
Log.e(TAG, e.toString());
} catch (final IOException e) {
Log.e(TAG, e.toString());
}
return placeList;
}
private boolean areValidArgs(final XmlPullParser parser, final Place place) {
return null != parser && null != place;
}
private void setPlaceId(final XmlPullParser parser, final Place place) {
if (areValidArgs(parser, place)) {
final String placeId = getTagValue(parser);
place.setPlaceId(Integer.parseInt(placeId));
}
}
private void setPlaceName(final XmlPullParser parser, final Place place) {
if (areValidArgs(parser, place)) {
final String placeName = getTagValue(parser);
place.setPlaceName(placeName);
}
}
private void setPlaceDescription(final XmlPullParser parser, final Place place) {
if (areValidArgs(parser, place)) {
final String placeDescription = getTagValue(parser);
place.setPlaceDescription(placeDescription);
}
}
private void setPlaceLatLong(final XmlPullParser parser, final Place place) {
if (areValidArgs(parser, place)) {
final String[] latLong = getTagValue(parser).split(";");
if (3 == latLong.length) {
place.setPlaceLatitude(Double.parseDouble(latLong[1]));
place.setPlaceLongitude(Double.parseDouble(latLong[2]));
}
}
}
private String getTagValue(final XmlPullParser parser) {
String result = "";
try {
if (parser.next() == XmlPullParser.TEXT) {
result = parser.getText();
parser.nextTag();
}
} catch (final XmlPullParserException e) {
Log.e(TAG, e.toString());
} catch (final IOException e) {
Log.e(TAG, e.toString());
}
return result;
}
}
Finally, in you Google Map's activity, implement OnMapReadyCallback interface, override onMapReady method and add place markers to Google Map: MapActivity.class
public class MapActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
private List<Place> placeList;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
this.placeList = getPlaceList();
}
#Override
public void onMapReady(final GoogleMap googleMap) {
this.mMap = googleMap;
addPlaceListMarkersToGoogleMap();
}
private void addPlaceListMarkersToGoogleMap() {
for (final Place place : this.placeList) {
final LatLong latLong = new LatLong(place.getPlaceLatitude(), place.getPlaceLongitude());
this.mMap.addMarker(new MarkerOptions().position(latLong).title(place.getPlaceName()));
}
}
private List<Place> getPlaceList() {
final String xmlString = "<placesp>" +
"<placep>" +
" <place_id>1</place_id>" +
" <name>Place1</name>" +
" <description>Place description 1</description>" +
" <coordinates>;40.430224;21.559570</coordinates>" +
"</placep>" +
"<placep>" +
" <place_id>2</place_id>" +
" <name>Place2</name>" +
" <description>Place description 2</description>" +
" <coordinates>;40.423324;21.062439</coordinates>" +
"</placep>" +
"<placep>" +
" <place_id>3</place_id>" +
" <name>Place3</name>" +
" <description>Place description 3</description>" +
" <coordinates>;40.266952;21.238220</coordinates>" +
"</placep>" +
"</placesp>";
final InputStream xmlStream = getXmlStream(xmlString);
final PlaceXmlParser parser = new PlaceXmlParser();
return parser.parsePlacesXml(xmlStream);
}
private InputStream getXmlStream(final String xmlString) {
InputStream xmlStream = null;
try {
xmlStream = new ByteArrayInputStream(xmlString.getBytes("UTF-8"));
} catch (final UnsupportedEncodingException e) {
e.printStackTrace();
}
return xmlStream;
}
}
Provided code works well for given XML sample, be aware of possible exceptions and handle it. Hope this help!

Redirecting output to table in Java Swing

Newbie here, I have a problem, redirecting my output to a Jtable. The data is coming from a different class that does the real work which is Scanner.java.
With this said, Scanner.java could print what i want on console but since I added gui which am still learning I have created a new class MainFrame.java and I want search or scan result form Scanner.java to be populated in my JTable but am finding it hard to get the login.
Scanner.java
public void getCompanyProfile(){
Document sourceCode;
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
List<String> allLinks = results();
Document sourceCode;
int counter = 1;
for (String link : allLinks){
System.out.println("Link #:" + counter + " " + link);
sourceCode = PageVisitor.getHtmlSource(link);
Elements profile = sourceCode.select("div.company a.cd");
for (Element links : profile) {
String linkHref = links.attr("href");
System.out.println(linkHref);
setUserData(linkHref);
}
counter++;
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private void setUserData(String url) throws IOException{
Extractor data = new Extractor();
// Scan each page alibaba initial result
data.setProfile(url);
this.companyName = data.getName();
this.country = data.getCountry();
HashSet<String> webites = data.getSellerUrls();
this.webAndEmail = new HashMap<String, HashSet<String>>();
HashSet<String> emails;
for (String webs: webites){
emails = data.emailExtractor(webs);
webAndEmail.put(webs, emails);
for (String anEmail : emails){
//This is the part i want to be displayed in my JTable Component.
System.out.println("Company=" +companyName + ", country=" + country + ", web="
+ webs + ", email=" + anEmail);
}
}
}
public String getProductName(){
return this.product;
}
public String getSource(){
return this.source;
}
public String getCompanyName(){
return this.companyName;
}
public String getCountry(){
return this.country;
}
public Map<String, HashSet<String>> getWebandEmail(){
return this.webAndEmail;
}
Finally, this is my MainFrame.java file below .
![JButton btnStart = new JButton("Start");
btnStart.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
btnStart.setBounds(197, 166, 75, 29);
frame.getContentPane().add(btnStart);
//more statements like the above to establish all col. titles
String\[\] columnNames = {"Company Name", "Email", "Website", "Country", "Product", "Source"};
//Sample data to be printed
Object\[\]\[\] data =
{
{"Code Java Ltd", "bingo#codejava.net", "http://www.codejava.com", "Universe", "Polythecnic", "Ebay - B2B"},
};
DefaultTableModel model = new DefaultTableModel(data, columnNames) {
#Override
public boolean isCellEditable(int row, int column) {
//all cells false
return false;
}
};
resultTable = new JTable(model);
//resultTable.setBounds(37, 259, 553, 143);
resultTable.getColumnModel().getColumn(0).setPreferredWidth(150);
resultTable.getColumnModel().getColumn(1).setPreferredWidth(150);
resultTable.getColumnModel().getColumn(2).setPreferredWidth(150);
resultTable.getColumnModel().getColumn(3).setPreferredWidth(150);
resultTable.getColumnModel().getColumn(4).setPreferredWidth(100);
resultTable.getColumnModel().getColumn(5).setPreferredWidth(100);
resultTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JScrollPane scrollPane = new JScrollPane( resultTable );
scrollPane.setBounds(37, 259, 806, 143);
frame.getContentPane().add( scrollPane );
//frame.add(resultTable);
JButton button = new JButton("Stop");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
button.setBounds(289, 166, 75, 29);
frame.getContentPane().add(button);][1]
This is what am trying to attain.
My other idea is to write the content to CSV from Scanner.java class file and read the file lated to populate the table. But like I said, am a beginner still don't think it would be that easy. So I kindly need someone to point me in the right direction.
Basically, you want to load your data from outside the Event Dispatching Thread, so as not to block the UI and make it "hang".
Next, you need some way for the Scanner to publish information it has generated, there are a number of ways you might do this, but the simplest might to use something like a Produce/Consumer Pattern.
With the Scanner acting as the producer, we need some way to inform the consumer that new content is available. Start with a simple interface...
public interface Consumer {
public void publish(String company, String country, String webLink, String email);
}
Note, I normally prefer to use objects (like a POJO), but I'm trying to keep it simple.
Next, we need to modify the Scannner to work with out Consumer...
public class Scanner {
public void getCompanyProfile(Consumer consumer) {
Document sourceCode;
List<String> allLinks = results();
Document sourceCode;
int counter = 1;
for (String link : allLinks) {
System.out.println("Link #:" + counter + " " + link);
sourceCode = PageVisitor.getHtmlSource(link);
Elements profile = sourceCode.select("div.company a.cd");
for (Element links : profile) {
String linkHref = links.attr("href");
System.out.println(linkHref);
setUserData(linkHref);
}
counter++;
}
}
private void setUserData(String url, Consumer consumer) throws IOException {
Extractor data = new Extractor();
// Scan each page alibaba initial result
data.setProfile(url);
this.companyName = data.getName();
this.country = data.getCountry();
HashSet<String> webites = data.getSellerUrls();
this.webAndEmail = new HashMap<String, HashSet<String>>();
HashSet<String> emails;
for (String webs : webites) {
emails = data.emailExtractor(webs);
webAndEmail.put(webs, emails);
for (String anEmail : emails) {
consumer.publish(companyName, country, webs, anEmail);
}
}
}
public String getProductName() {
return this.product;
}
public String getSource() {
return this.source;
}
public String getCompanyName() {
return this.companyName;
}
public String getCountry() {
return this.country;
}
public Map<String, HashSet<String>> getWebandEmail() {
return this.webAndEmail;
}
}
Now, we need some way to get the Scanner started and producing data, first we create the basic UI and then we start a SwingWorker, passing a reference of the TableModel to it, so it can add the new rows.
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
DefaultTableModel model = new DefaultTableModel(new String[]{"Company Name", "Email", "Website", "Country", "Product", "Source"}, 0);
JTable table = new JTable(model);
// Initialise remainder of the UI...
ScannerWorker worker = new ScannerWorker(model);
worker.execute();
}
});
And the SwingWorker to hold it all together...
public class ScannerWorker extends SwingWorker<Object, String[]> implements Consumer {
private DefaultTableModel tableModel;
public ScannerWorker(DefaultTableModel tableModel) {
this.tableModel = tableModel;
}
#Override
protected Object doInBackground() throws Exception {
Scanner scanner = new Scanner();
scanner.getCompanyProfile(this);
return null;
}
#Override
public void publish(String company, String country, String webLink, String email) {
publish(new String[]{company, email, webLink, country, "", ""});
}
#Override
protected void process(List<String[]> chunks) {
for (String[] rowData : chunks) {
tableModel.addRow(rowData);
}
}
}
Take a closer look at Worker Threads and SwingWorker and How to Use Tables for more details

Why am I getting null as the destination?

When I have the program print out System.out.println(_spaces.get("classroom").toStringLong()); it spits back "classroom: a large lecture hall with a door that goes null to sidewalk." Why does it say a door that goes to null? I think I have to fix my _buildPortals method, but I'm not sure how.
public class ConfigLoader
{
private Ini _ini;
private HashMap<String, Space> _spaces = new HashMap<String, Space>();
private HashMap<String, Portal> _portals = new HashMap<String, Portal>();
private HashMap<String, Agent> _agents = new HashMap<String, Agent>();
public ConfigLoader(File iniFile)
{
_ini = new Ini(iniFile);
}
public Agent buildAll()
{
_buildSpaces();
_buildPortals();
_buildExits();
_buildDestinations();
System.out.println(_spaces.get("classroom").toStringLong());
_buildAgents();
//return _selectStartAgent();
return null;
}
private void _buildSpaces()
{
for(String spaceName : _ini.keys("spaces"))
{
String description = _ini.get("spaces", spaceName);
String image = _ini.get("images", "images");
Space spaceInstance = new Space(spaceName, description, null, image);
_spaces.put(spaceName, spaceInstance);
}
}
private void _buildPortals()
{
for(String portalName : _ini.keys("portals"))
{
String description = _ini.get("portal", portalName);
Portal portalInstance = new Portal(portalName, description, null);
_portals.put(portalName, portalInstance);
}
}
private void _buildExits()
{
for(String spaceName : _ini.keys("exits"))
{
String spaceExit = _ini.get("exits", spaceName);
Space space = _spaces.get(spaceName);
Portal exit = _portals.get(spaceExit);
space.setPortal(exit);
}
}
private void _buildDestinations()
{
for(String portalName : _ini.keys("destinations"))
{
String destination = _ini.get("destinations", portalName);
Space dest = _spaces.get(destination);
Portal portal = _portals.get(portalName);
if(dest == null)
{
System.out.println("Error");
System.exit(1);
}
else
{
portal.setDestination(dest);
}
}
}
private void _buildAgents()
{
for(String agentName : _ini.keys("agents"))
{
String agent = _ini.get("agents", agentName);
Space space = _spaces.get(agent);
if(space == null)
{
System.out.println("Error");
System.exit(1);
}
else
{
Agent a = new Agent(space, agentName);
_agents.put(agentName, a);
}
}
}
private Agent _selectStartAgent()
{
for(String agentName : _ini.keys("start"))
{
String agent = _ini.get("start", agentName);
Agent agentInstance = _agents.get(agent);
if(agent == null)
{
System.out.println("Error");
System.exit(1);
}
else
{
return agentInstance;
}
}
return null;
}
}
Following the other patterns in your code, maybe..
String description = _ini.get("portal", portalName);
needs to be
String description = _ini.get("portals", portalName);
If so, it's usually a good idea to extract something like this to a string constant.
private static final String PORTALS = "portals";
and use that in multiple places.
Your buildSpaces method's second line is wrong. You're getting the image associated with a certain space but you have two strings in your get call and that's not right.

ParseObject as a data to the table/chart

I'm new in coding and I have a problem to understand something. I follow the example form Parse.com Doc and wrote this.
public void getData() {
ParseQuery<ParseObject> query = ParseQuery.getQuery("ParseClass");
query.getInBackground("lxFzCTeOcl", new GetCallback<ParseObject>() {
public void done(ParseObject parseObject, ParseException e) {
if (e == null) {
String object = parseObject.getString("value");
int object_value = Integer.parseInt(obiect);
} else {
Log.d("score", "Error: " + e.getMessage());
}
}
});
}
I understand this like:
I send query to server
get obiect with "lxFzCTeOcl" id
if there is no exception I create String object which takes string
form "value" column.
convert String to int
My question is: How can I use object_value for example to make a chart or put it into a table?
Here we will add the array list to your code and start to store an object inside the array every time we call the getData method in your class.
private ArrayList<Integer> dataArray;
public void getData() {
ParseQuery<ParseObject> query = ParseQuery.getQuery("ParseClass");
query.getInBackground("lxFzCTeOcl", new GetCallback<ParseObject>() {
public void done(ParseObject parseObject, ParseException e) {
if (e == null) {
String object = parseObject.getString("value");
Integer objectValue = Integer.parseInt(obiect);
if(dataArray==null)
dataArray = new ArrayList<Integer>();
dataArray.add(objectValue);
} else {
Log.d("score", "Error: " + e.getMessage());
}
}
});
}
And here I'm just adding a simple example of how to create a simple pie chart using our array list (note that I used the lib AChartEngine http://www.achartengine.org/):
private static int[] COLORS = new int[] { Color.GREEN, Color.BLUE,Color.MAGENTA, Color.CYAN };
private GraphicalView createPieChart(ArrayList<Integer> data){
GraphicalView chartView;
CategorySeries series = new CategorySeries("PIE");
for (int i = 0; i < VALUES.length; i++) {
series.add(i, data.get(i));
SimpleSeriesRenderer renderer = new SimpleSeriesRenderer();
renderer.setColor(COLORS[(series.getItemCount() - 1) % COLORS.length]);
mRenderer.addSeriesRenderer(renderer);
}
chartView = ChartFactory.getPieChartView(this, series, new DefaultRenderer());
chartView.repaint();
return chartView;
}
Now you can add this GraphicalView to your view.
The returned object is much like a map, with key/value pairs. In your example, the key is "value", which makes it a little confusing, but it would be like this if you wanted all fields:
for (Field field : myInstance.getClass().getDeclaredFields()) {
String name = field.getName();
value = field.get(myInstance).toString();
map.put(name, value);
}

Categories