Right now I'm working on a GUI project, where I'm trying to take photos, found from the URLs I find from inside the source code of a website, and load them into my JavaFx GUI.
For example, I wish for Java to load the website http://www.imdb.com/movies-in-theaters/?ref_=nv_tp_inth_1, and collect all of the "cover photos"/thumbnails that you see as you scroll down the page (no matter the size of the image), and then load them into the GUI view (into an HBox full as a bunch of ImageViews for example).
More in-depth as well, eventually I would like to get it to the point, that the user could click on the image/imageview, and (again for example) it would show show the trailer for the selected movie. (My thinking, is that the trailer link would be found from website, if you clicked through and went to the next page, found the link, went to youtube, and removed all of the content except for the video player necessarily).
In the web-browser that I use, I have access see the page's HTML elements/design, and look through all of the source coding. After just a few twirls, I can easily find the direct URL to the thumbnail/image I'm looking for, and I've found that in javaFX I can load an image into my GUI as a URL, like so:
Image img = new Image("http://website/websiteSubPage/websiteImage");
ImageView imgView = new ImageView(img);
I've also found that the concept of what I'm looking for is called WebScraping... But all of the modules I've looked into and researched so far aren't helping with what I need. The closest module I've found so far, is HtmlUnit. However, HtmlUnit is all about web automation -- And I couldn't find anything in it's documentation on finding a photo, and loading it as a Java Image object, that is callable into an ImageView.
My best guess at the moment, is to have Java load the website in the background, gather the source code, and then I could create a String Manipulator of sorts, that would essentially just find, trim to, and load the URL of every image it finds, and put it into an HBox full of ImageViews.
Ultimately, I feel like my only solution looks something like this:
public HBox listView(){
HBox temp = new HBox();
// Load the website
// Load the source code into a large string.
for (int i=0; i>=<numberOfPhotosPreCalculatedSomeHow>;i++){
Image img = new Image( /*Manipulated string algorithm to find the next image URL*/);
ImageView imgView = new ImageView(img);
ImageView.setOnAction(e -> { /* load the trailer */ }; } // (Lambda)
temp.getChildren().add(ImageView);
}
return temp;
}
However, doing all of this... Makes me feel like I'm doing something horribly wrong, and I need some help.
Thoughts? Is there a module or plugin built specifically for this? Is this possible, or just dumb?
Found the answer!
There's built-in java methods that can allow me to scan in information from a website, and then decipher it as needed.
In my case, here's the code I used:
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Scanner;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class WebReader extends Application{
// Class variable to hold our found URLs :)
static ArrayList<String> listArray;
public static void main(String[] args) throws IOException {
// Gather page & URL data, and read it
String address = "http://reddit.com";
URL pageLocation = new URL(address);
Scanner in = new Scanner(pageLocation.openStream());
// Initialize an ArrayList to store all of our collected URLs
listArray = new ArrayList<String>();
// Decipher the code line by line
while (in.hasNext()) {
String line = in.next();
if (line.contains("href=\"http://")) {
int from = line.indexOf("\"");
int to = line.lastIndexOf("\"");
System.out.println(line.substring(from + 1, to));
listArray.add(line.substring(from + 1, to));
}
}
// Next, we implement into JavaFx
launch(args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("My loaded photos");
// Create a place to put our content
HBox content = new HBox();
ScrollPane scrollPane = new ScrollPane(content);
scrollPane.setFitToHeight(true);
System.out.println(listArray.size());
for (int i = 0; i <= listArray.size() - 1; i++) {
Image img = new Image(listArray.get(i));
ImageView imgView = new ImageView(img);
content.getChildren().add(imgView);
} // Launch and sail away!! :)
Scene s = new Scene(scrollPane, 800, 600);
primaryStage.setScene(s);
primaryStage.show();
}
}
So this was the solution that I was able to find-- I can't believe it took me so long to find a solution, but I hope this helps anybody who is on the same boat that I am. :)
Related
I am using Vaadin in Java and I am following this tutorial: Vaadin Upload
So I have created a new Class name Uploader. But there is some stuff which doesn't work in my code, I put what is not working in ** text **:
import com.vaadin.server.FileResource;
import com.vaadin.ui.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
/**
* Created by mflamant on 15/05/2017.
*/
public class Uploader {
final Embedded image = new Embedded("Uploaded image");
**image.setVisible(false);**
class Image implements Upload.Receiver, Upload.SucceededListener{
public File file;
public OutputStream receiveUpload(String filename, String mimeType){
FileOutputStream fos = null;
try{
file = new File(filename);
fos = new FileOutputStream(file);
} catch (final java.io.FileNotFoundException e){
e.printStackTrace();
return null;
}
return fos;
}
public void uploadSucceeded(Upload.SucceededEvent event){
image.setVisible(true);
image.setSource(new FileResource(file));
}
};
Image receiver = new Image();
Upload upload = new Upload("Upload image here", receiver);
**upload.setButtonCaption("Start Upload");**
**upload.SucceededListener(receiver);**
Panel panel = new Panel("Image storage");
Layout panelContent = new VerticalLayout();
**panelContent.addComponents(upload, image);**
**panel.setContent;**
}
The error I have is "Can not resolve symbol". Can you explain to me why these lines aren't working?
Upload example doesn't list the whole code of the application. It only includes the code snippets specific to the Upload component itself. These code snippets are not expected to work if you just paste them into your class.
This example is a part of Vaadin Documentation and you're expected to understand the basics at the time you reach this part.
Example code is intended to work as a part of a method that builds a Vaadin component. The particular error is that you can only call methods, like image.setVisible(false) from an executable code block. You can't just paste them in your class declaration, that's not a valid Java code.
Tutorial links to a working code on Github. As you can see it contains all the necessary initialization in place:
public class UploadExample extends CustomComponent implements BookExampleBundle {
private static final long serialVersionUID = -4292553844521293140L;
public void init (String context) {
//... omitted for brevity
basic(layout);
//... omitted for brevity
}
void basic(VerticalLayout layout) {
final Image image = new Image("Uploaded Image");
//the rest of the example code goes here
Please, note that this class alone still doesn't work as a standalone application. This is just one of the components.
So, what you can do now:
Complete Vaadin Tutorial first. This should help you grasp the concepts.
Read the Introduction part of the docs first. This will help you build the working application. Then you can jump to specific components.
Clone Book Examples application from Github and then try to figure out how it works.
I have created the following code for a school project, a "password protector", just for fun, really. However, the problem I have is that the icon image does not appear, but instead the default java "coffee cup".
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class UserInterfaceGUI extends JFrame
{
private static final long serialVersionUID = 1;
private JLabel userNameInfo; // ... more unimportant vars.
public UserInterfaceGUI()
{
this.setLayout(new FlowLayout());
userNameInfo = new JLabel("Enter Username:"); // ... more unimportant var. declartions
this.add(userNameInfo); // ... more unimportant ".add"s
event e = new event();
submit.addActionListener(e);
}
public static void main(String[] args)
{
//This icon has a problem \/
ImageIcon img = new ImageIcon("[File Location hidden for privacy]/icon.ico");
UserInterfaceGUI gui = new UserInterfaceGUI();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setSize(400, 140);
gui.setIconImage(img.getImage());
gui.setTitle("Password Protector");
gui.setVisible(true);
}
}
Can someone tell me why this just shows the java coffee cup at the bottom of the screen and on the bar at the top of the window?
There are two likely problems here:
Java is unlikely to support .ico files. The only types that can be relied on are GIF, PNG & JPEG. For all types supported on any specific JRE, use ImageIO.getReaderFileSuffixes() (but seriously, for app. icons stick to the 3 types with guaranteed support).
The code is trying to load an application resource as a file, when it will likely be (or become) an embedded-resource that should be accessed by URL. See the embedded resource info. page for tips on how to form the URL.
My end goal is to display arbitrary text on a GoogleMap using the GoogleMaps v3 GWT API. I think the way to do that is through KML. If that's not the way to go, I'd love to hear other approaches (other than displaying the text as images). If KML is the way to go, then I wonder what I'm doing wrong:
I'm trying to load this example KML file into a test GoogleMap through GWT: https://developers.google.com/kml/documentation/KML_Samples.kml
The main tag in that file I care about is this one:
<Placemark>
<name>Simple placemark</name>
<description>Attached to the ground. Intelligently places itself at the
height of the underlying terrain.</description>
<Point>
<coordinates>-122.0822035425683,37.42228990140251,0</coordinates>
</Point>
</Placemark>
When I render that KML file on Google Earth, the name (Simple placemark) is displayed directly on the map. Hooray!
However, when I render that KML file on GoogleMaps, the name is not displayed on the map, and only shows up in an InfoWindow when I click on the placemark. Everything else seems to display fine, except no text is rendered directly on the map, which is my entire goal.
I've included the example map code I'm using, and I'm hoping there's a way to tell the GoogleMap to display the name, or really any text, on the map directly.
package com.test.client;
import com.google.gwt.ajaxloader.client.AjaxLoader;
import com.google.gwt.ajaxloader.client.AjaxLoader.AjaxLoaderOptions;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.dom.client.Document;
import com.google.maps.gwt.client.GoogleMap;
import com.google.maps.gwt.client.KmlLayer;
import com.google.maps.gwt.client.LatLng;
import com.google.maps.gwt.client.MapOptions;
import com.google.maps.gwt.client.MapTypeId;
public class GwtTest implements EntryPoint {
#Override
public void onModuleLoad() {
AjaxLoaderOptions options = AjaxLoaderOptions.newInstance();
options.setOtherParms("sensor=false");
Runnable callback = new Runnable() {
public void run() {
createMap();
}
};
AjaxLoader.loadApi("maps", "3", callback, options);
}
public void createMap() {
MapOptions mapOpts = MapOptions.create();
mapOpts.setZoom(4);
mapOpts.setCenter(LatLng.create(37.09024, -95.712891));
mapOpts.setMapTypeId(MapTypeId.TERRAIN);
final GoogleMap map = GoogleMap.create(Document.get().getElementById("map_canvas"), mapOpts);
KmlLayer kmlLayer = KmlLayer.create("https://developers.google.com/kml/documentation/KML_Samples.kml");
kmlLayer.setMap(map);
}
}
If there simply isn't a way to render text on a GoogleMap, is there an "official" place that says so?
For anybody stumbling upon this question, what I eventually ended up doing was using Google's chart API: https://developers.google.com/chart/image/docs/gallery/dynamic_icons
This allows you to dynamically create images using arguments passed into a URL. Then you can just use that URL to create a MarkerImage or GroundOverlay:
MarkerImage mi = MarkerImage.create("http://chart.apis.google.com/chart?chst=d_text_outline&chld=000000|16|h|FFFFFF|_|Example");
MarkerOptions mo = MarkerOptions.create();
mo.setIcon(mi);
mo.setPosition(LatLng.create(37.1918, -95.8892));
Marker m = Marker.create(mo);
m.setMap(map);
The option on the official place for this is to use a Custom Overlay. Their example uses an img element, but change this to a div element and then set the innerHTML or similar to show your text over the map.
You should be able to use the sample javascript code to help you implement this in GWT - extend the OverlayView class from the Google GWT wrapper library etc.
I am trying to display images inside a Browser-widget (SWT). These images can be found inside the a jar file (plug-in development). However: this is not directly possible as the browser-widget expects some kind of URL or URI information.
My idea is to turn SWT-images into data-URI values, which I could induce into the src-attribute of every given img-element. I know, that this is not a good solution from a performance point of view, but I don't mind the speed disadvantage.
I'd like to know how to turn a SWT image into a data-URI value for use in a browser-widget.
My code so far:
package editor.plugin.editors.htmlprevieweditor;
import editor.plugin.Activator;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
public class HtmlPreview extends Composite implements DisposeListener {
private final Browser content;
public HtmlPreview(final Composite parent, final int style) {
super(parent, style);
this.setLayout(new FillLayout());
content = new Browser(this, style);
final ImageData imageData = Activator.getImageDescriptor(Activator.IMAGE_ID + Activator.PREVIEW_SMALL_ID).getImageData();
content.setText("<html><body><img src=\"data:image/png;base64," + imageData + "\"/></body></html>"); // need help on changing imageData to a base64-encoded String of bytes?
this.addDisposeListener(this);
}
#Override
public void widgetDisposed(final DisposeEvent e) {
e.widget.dispose();
}
}
Any help is greatly appreciated :)!
Edit 1: I have read SWT Image to/from String , but unfortunately it does not seem to exactly cover my needs.
Edit 2: I don't know if it matters, but I am trying to load a PNG24-image with per-pixel alpha-transparency.
The question is too general if you only say "Browser in SWT". Mozzila browser supports jar URL protocol, and you can do this:
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
final URL url = ShellSnippet.class.getResource("/icons/full/message_error.gif");
final Browser browser = new Browser(shell, SWT.MOZILLA);
final String html = String.format("<html><head/><body>image: <img src=\"%s\"/></body></html>", url);
browser.setText(html);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
It looks like this:
I used an image from the JFace jar to keep the snippet simple and yet work for most people out of the box. It is GIF, but I expect it to work just as well with PNG files.
If you use Internet Explorer, something I do not recommend because your application depends on OS version, this does not work. It looks like this (after changing in the snippet the style from SWT.MOZILLA to SWT.NONE):
It does however understand the file protocol and you can copy files to the temp folder and create URLs directly to the file using File.toURL(). This should work for any browser.
I cannot test the simple solution on WEBKIT broswer. If anyone can, please post the result in a comment.
I'm very very new to imageJ but know a little Java.
Essentially I want to open a file from an OpenDialog display the image, then blur the image and display the resulting blurred image. My program compiles, however the two images look the same. Can anybody help? How do I make the program display a blurred and unblurred image?
import ij.*;
import ij.io.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import ij.plugin.*;
import java.util.*;
import java.io.*;
public class opens_ implements PlugIn {
ImagePlus imp;
public void run(String arg){
OpenDialog od = new OpenDialog("Open.....", arg);
Opener op = new Opener();
String directory = od.getDirectory();
String filename = od.getFileName();
if (filename==null) return ;
imp = op.openImage(directory, filename);
imp.show();
ImageProcessor improc = imp.getProcessor();
improc.smooth();
ImagePlus alter = new ImagePlus("alter", improc) ;
alter.show();
}
}
Thanks
Bateman
When you call .smooth() on improc, that call alters the image data contained by the ImageProcessor, which is being displayed by the original ImagePlus. Then you create a new ImagePlus based on the same ImageProcessor, so of course it's the blurred image rather than the original. If you don't want the original to be altered, then you can duplicate the ImageProcessor before smoothing, for example by changing the line:
ImageProcessor improc = imp.getProcessor();
... to:
ImageProcessor improc = imp.getProcessor().duplicate();
Update: when I tested your code, I saw both images as blurred. If you still see the original images, try adding the following to the end of your run method:
imp.updateAndDraw()
alter.updateAndDraw()