Writing a program to retrieve people’s Minecraft skins, in JavaFX

After seeing JavaFX in action at JavaOne I decided I’d try to keep up to date with it. And in order to stay up to date I need to keep myself familiar with it all, so I decided to make a small application to download the Skins of Minecraft players.

For those who don’t know what JavaFX is, (shame on you) it’s an API for making very slick looking GUIs and comes as standard in Java 7. It’s something that Oracle are pushing very hard and is shaping up to be a suitable replacement for Swing.

Not very pretty as of right now…

As you can see from the screenshot; it is capable of downloading any Minecraft users skin and displaying it within the window.

This is possible because all Minecraft skins are stored in the same place online and publicly accessible so you don’t even need a program to download them, for instance to download my skin you would navigate to http://s3.amazonaws.com/MinecraftSkins/LyndonArmitage.png and then be prompted to download it.

Onto the code!

To start we need to make a new JavaFX project, if your using NetBeans it will add the basic hello world program to your project immediately, you can delete all the stuff to do with the button so you just have the bare basics of a JavaFX project:

    @Override
    public void start(Stage primaryStage) {
	primaryStage.show();
    }

Next we are going to want to set the title of the stage and make sure it isn’t resizeable:

        primaryStage.setTitle("Minecraft Skin Downloader - By Lyndon Armitage");
	primaryStage.setResizable(false);

What we now need is something to hold and arrange all our nodes in; I choose a GridPane and decided to have it aligned to top middle of the window with 10 pixel padding between the sides of it and each cell:

	GridPane grid = new GridPane();
	grid.setAlignment(Pos.TOP_CENTER);
	grid.setHgap(10);
	grid.setVgap(10);
	grid.setPadding(new Insets(10, 10, 10, 10));

Next I added a few nodes as normal, adding them to the grid at appropriate points:

	Text txtTitle = new Text("Minecraft Skin Downloader");
	txtTitle.setFont(Font.font("Tahoma", FontWeight.BOLD, 13));
	grid.add(txtTitle, 0, 0);

	Label lblUsername = new Label("Username of Skin Owner:");
	grid.add(lblUsername, 0, 1);

However I then added a text field which I declared as one of my class variables so it could be referenced by other methods and proceeded to add a button with an EventHandler for when it was pressed  using the knowledge on downloading skins I mentioned earlier:

	grid.add(inUsername, 1, 1);

	Button btnGet = new Button("Get Skin");
	grid.add(btnGet, 0, 2);
	Label lblImage = new Label("Skin:");
	grid.add(lblImage, 0, 3);

	btnGet.setOnAction(new EventHandler() {

	    @Override
	    public void handle(ActionEvent event) {
		//System.out.println("getting skin for: " + inUsername.getText());
		String url = "http://s3.amazonaws.com/MinecraftSkins/" + inUsername.getText() + ".png";
		skin = new Image(url);
		if(!skin.isError()) {
		    showSkin.setImage(skin);
		    txtError.setText("");
		    btnDownload.setDisable(false);
		}
		else {
		    txtError.setText("Skin not found.");
		    showSkin.setImage(null);
		    btnDownload.setDisable(true);
		}
	    }
	});

Now you may notice references to a few nodes I haven’t spoken of yet so I will explain them:

  • The node skin is a JavaFX Image which is where we store our downloaded image.
  • showSkin is an ImageView which is the JavaFX object for showing an image inside a window.
  • txtError is just an empty Text node at the same location as showSkin and is used to display an error message for when a skin can’t be found.

And finally btnDownload is a button for saving the image from memory to your hard drive which needs some explanation since it involves another EventHandler:

	btnDownload.setOnAction(new EventHandler() {

	    @Override
	    public void handle(ActionEvent event) {
		if(!skin.isError()) {

		    // set up the file chooser
		    FileChooser fc = new FileChooser();
		    FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("PNG files (*.png)", "*.png");
		    fc.getExtensionFilters().add(extFilter);
		    fc.setInitialDirectory(targetDirectory);
		    fc.setTitle("Save skin to...");

		    // show the dialog
		    File file = fc.showSaveDialog(primaryStage.getOwner());

		    // if the file is null they clicked cancel
		    if(file == null) {
			return;
		    }

		    // set the target directory to the one they just saved in.
		    targetDirectory = file.getParentFile();

		    // ensure it has the correct extension
		    if(!file.getName().toLowerCase().endsWith(".png")) {
			file = new File(file.getAbsolutePath() + ".png");
		    }

		    try {
			ImageIO.write( SwingFXUtils.fromFXImage(skin, null), "PNG", file);

		    } catch (IOException ex) {
			Logger.getLogger(MinecraftSkinStealer.class.getName()).log(Level.SEVERE, null, ex);
		    }
		}
	    }
	});

Now that’s a lot of code, hopefully its pretty easy to follow;

  • First, after making sure there isn’t anything wrong with the image (there shouldn’t be) we create a new FileChooser object and set up it’s default directory and valid extensions.
  • Next we show the user the file chooser box and wait for their input.
  • Assuming they choose a file we first store the location for later use so when they next choose to download a skin they are taken to the same directory.
  • We then make sure the file they choose has the right extension and if it doesn’t we add it.
  • Then we write it out!

See simple! Now all we need to do is remember to create the Scene all this is going to be placed within and show it:

	Scene scene = new Scene(grid, WIDTH, HEIGHT);
	primaryStage.setScene(scene);
        primaryStage.show();

And that’s it! A working, JavaFX based, Minecraft skin downloader!

For the full source code go here, or to download a working jar file go here.

I hope this has been informative and helped you learn JavaFX! Feel free to comment and ask any questions you have below, and as always

Happy Coding!

3 Comments

  1. […] Lyndon Armitage has created a JavaFX application to download Minecraft player skins. […]

  2. […] Lyndon Armitage has created a JavaFX application to download Minecraft player skins. […]

  3. […] my previous blog post I explained how to make a skin getter/stealer for Minecraft in Java using JavaFX. Turns out that […]

Leave a Reply