ZatackCoder https://zatackcoder.com Its All About Code Tue, 14 Jul 2020 10:04:28 +0000 en-US hourly 1 https://wordpress.org/?v=5.5.3 https://zatackcoder.com/wp-content/uploads/2015/09/cropped-zatackcoderlogo-32x32.png ZatackCoder https://zatackcoder.com 32 32 176495184 Capture Image From Video and Saving to Server in Javascript https://zatackcoder.com/capture-image-from-video-and-saving-to-server-in-javascript/ https://zatackcoder.com/capture-image-from-video-and-saving-to-server-in-javascript/#respond Tue, 14 Jul 2020 10:02:46 +0000 https://zatackcoder.com/?p=2815 Hello Friends, Hope you are doing well. It’s being long time I haven’t share anything but today I am going to share how to capture image from video and saving to server in Javascript. Actually this requirement came to me because of a client’s mobile app where thumbnail image was required to show in the...

The post Capture Image From Video and Saving to Server in Javascript appeared first on ZatackCoder.

]]>

Hello Friends, Hope you are doing well. It’s being long time I haven’t share anything but today I am going to share how to capture image from video and saving to server in Javascript. Actually this requirement came to me because of a client’s mobile app where thumbnail image was required to show in the list of videos. There is two ajax request made to requests.php one to upload video and another to upload video thumbnail and finally there is submit button to submit the form. On submit of form I have only printed posted data you can use it according to your need i.e you can store it in database for further use.

Let’s Code

index.php

<?php
if (isset($_POST['save'])) {
    echo '<h3>Submitted Data - You Can Process According to Your Need</h3>';
    echo '<pre>'; print_r($_POST); echo '</pre>';
}
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Capture Image From Video</title>
        <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
        <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous">
        <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
        <style>
            #videouploadinput {
                width: 40px;
                height: 40px;
                position: absolute;
                top: -8px;
                right: 21px;
                z-index: -1; 
            }
            #video {
                float: none;
                margin-top: 10px;
                min-height: 150px;
                border: solid thick aliceblue;
            }
        </style>
    </head>   
    <body>   
        <div class="container">
            <div class="panel panel-default" style="margin-top: 5%">
                <form action="" method="post">
                    <div class="panel-body">                                                               
                        <div class="row">
                            <div class="col-md-12">
                                <div class="form-group">
                                    <label for="name" class="control-label">Title *</label>
                                    <input type="text" class="form-control" name="title" id="title" placeholder="Video Title" required />
                                </div>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-md-9">
                                <div class="form-group">
                                    <label>Video (Click on upload icon to upload or link icon to fetch video from link)</label>
                                    <div class="pull-right">
                                        <span id="uploadingspanmsg"></span>
                                        <label class="btn-flat btn btn-sm btn-default" title="Video Link" id="videoaddlink"><i class="fa fa-link"></i></label>
                                        <label class="btn-flat btn btn-sm btn-primary" title="Upload"><i class="fa fa-upload"></i><input id="videouploadinput" type="file" accept="video/*"></label>
                                    </div>                                                
                                    <div class="" id="video" style="text-align: center;">

                                    </div>
                                    <div style="text-align: center">
                                        <a id="capturea" href="javascript:captureThumbnail()" style="display: none;">Capture Thumbnail</a>
                                    </div>
                                </div>
                            </div>
                            <div class="col-md-3">
                                <input type="hidden" name="video_link_type" id="video_link_type"/>
                                <input type="hidden" name="video_link" id="video_link"/>
                                <input type="hidden" name="video_thumbnail" id="video_thumbnail"/>
                                <div class="form-group">
                                    <label class="control-label">Video Thumbnail</label>
                                    <img id="video_thumbnail_img" src="https://placehold.it/320x180" class="img-responsive"/>
                                    <input type="text" class="form-control" name="video_duration" id="video_duration" readonly=""/>
                                </div>
                            </div>
                        </div>

                    </div>
                    <div class="panel-footer">
                        <input type="submit" class="btn btn-success" id="save" name="save" value="Save"/>                                
                    </div>
                </form>
            </div>
        </div>

        <!-- REQUIRED JS SCRIPTS -->
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
        <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
        <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
        <script>
            $("#videouploadinput").change(function (e) {
                e.preventDefault();
                var action = "requests.php?f=upload-video";
                if ($("#videouploadinput").val() === "") {
                    return;
                }
                $("#uploadingspanmsg").html("Uploading...");
                var data = new FormData();
                data.append("video", $('input[type=file]')[0].files[0]);
                $.ajax({
                    type: 'POST',
                    url: action,
                    data: data,
                    /*THIS MUST BE DONE FOR FILE UPLOADING*/
                    contentType: false,
                    processData: false,
                }).done(function (data) {
                    $("#uploadingspanmsg").html(data.msg);
                    if (data.code === '0') {
                        $("#video_link_type").val("UPLOAD");
                        $("#video_link").val(data.file_url);
                        $("#video").html('<video id="uploaded_video" controls><source src="' + data.file_url + '" type="video/mp4"></video>');
                        $("#save").attr("disabled", true);
                        var vid = document.getElementById("uploaded_video");
                        vid.onloadedmetadata = function () {
                            $("#save").attr("disabled", false);
                            var seconds = document.getElementById("uploaded_video").duration;
                            $("#video_duration").val(new Date(seconds * 1000).toISOString().substr(11, 8));
                            $("#capturea").show();
                            captureThumbnail();
                        };
                    }
                }).fail(function (data) {
                    //any message
                });

            });
            $("#videoaddlink").click(function (e) {
                var videolink = window.prompt("Please paste image link here:", "");
                if (videolink !== null && videolink !== "" && (videolink.startsWith("http://") || videolink.startsWith("https://"))) {
                    $("#video_link_type").val("LINK");
                    $("#video_link").val(videolink);
                    $("#video").html('<video id="uploaded_video" controls><source src="' + videolink + '" type="video/mp4"></video>');
                    $("#save").attr("disabled", true);
                    var vid = document.getElementById("uploaded_video");
                    vid.onloadedmetadata = function () {
                        $("#save").attr("disabled", false);
                        var seconds = document.getElementById("uploaded_video").duration;
                        $("#video_duration").val(new Date(seconds * 1000).toISOString().substr(11, 8));
                        $("#capturea").show();
                        captureThumbnail();
                    };
                }
            });

            function captureThumbnail() {
                var canvas = document.createElement('canvas');
                var video = document.getElementById('uploaded_video');
                canvas.width = video.videoWidth;
                canvas.height = video.videoHeight;

                var context = canvas.getContext('2d');
                context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
                var imgsrc = canvas.toDataURL("image/png");
                $("#video_thumbnail_img").attr("src", imgsrc);

                var dataURL = canvas.toDataURL();
                $.ajax({
                    type: "POST",
                    url: "requests.php?f=upload-video-thumbnail-base64",
                    data: {
                        imgBase64: dataURL
                    }
                }).done(function (data) {
                    if (data.code === '0') {
                        $("#video_thumbnail").val(data.file_url);
                    }
                });
            }
        </script>
    </body>
</html>

requests.php

<?php
define('ERROR_RESPOSE_CODE', '1');
define('SUCCESS_RESPOSE_CODE', '0');

if (isset($_REQUEST['f']) && trim($_REQUEST['f']) == 'upload-video') {
    $response = array('code' => ERROR_RESPOSE_CODE, 'msg' => "Error");
    $upload_path = 'uploads/videos/';
    if (!file_exists($upload_path)) {
        mkdir($upload_path, 0777, true);
    }
    $upload_url = $upload_path;

    if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        //checking the required parameters from the request 
        if (isset($_FILES['video']['name'])) {
            $fileinfo = pathinfo($_FILES['video']['name']);
            $extension = $fileinfo['extension'];
            $filename = 'video_' . date('d') . '_' . md5(time());
            $file_url = $upload_url . $filename . '.' . $extension;

            //file path to upload in the server 
            $file_path = $upload_path . $filename . '.' . $extension;
            try {
                //saving the file 
                if (move_uploaded_file($_FILES['video']['tmp_name'], $file_path)) {
                    $response['code'] = SUCCESS_RESPOSE_CODE;
                    $response['file_url'] = $file_url;
                    $response['msg'] = 'Uploaded successfully!';
                    $response['htmlmsg'] = '<div class="alert alert-success">Uploaded successfully!</div>';
                }
            } catch (Exception $e) {
                $response['code'] = ERROR_RESPOSE_CODE;
                $response['msg'] = 'Error!';
                $response['htmlmsg'] = '<div class="alert alert-danger">Error!</div>';
            }
        } else {
            $response['code'] = ERROR_RESPOSE_CODE;
            $response['msg'] = 'Please choose file!';
            $response['htmlmsg'] = '<div class="alert alert-danger">Please choose file!</div>';
        }
    }
    header("Content-Type:application/json");
    echo json_encode($response);
    exit();
}

if (isset($_REQUEST['f']) && trim($_REQUEST['f']) == 'upload-video-thumbnail-base64') {
    $response = array('code' => ERROR_RESPOSE_CODE, 'msg' => "Error");
    $upload_path = 'uploads/video-thumbnails/';
    if (!file_exists($upload_path)) {
        mkdir($upload_path, 0777, true);
    }
    $upload_url =  $upload_path;

    if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        $filename = 'thumbnail_' . date('d') . '_' . md5(time());
        $file_url = $upload_url . $filename . '.png';

        //file path to upload in the server 
        $file_path = $upload_path . $filename . '.png';

        //saving the file 
        $img = $_POST['imgBase64'];
        $img = str_replace('data:image/png;base64,', '', $img);
        $img = str_replace(' ', '+', $img);
        $data = base64_decode($img);
        $success = file_put_contents($file_path, $data);

        if ($success) {
            $response['code'] = SUCCESS_RESPOSE_CODE;
            $response['file_url'] = $file_url;
            $response['msg'] = 'Uploaded successfully!';
            $response['htmlmsg'] = '<div class="alert alert-success">Uploaded successfully!</div>';
        } else {
            $response['code'] = ERROR_RESPOSE_CODE;
            $response['msg'] = 'Error!';
            $response['htmlmsg'] = '<div class="alert alert-danger">Error!</div>';
        }
    }
    header("Content-Type:application/json");
    echo json_encode($response);
    exit();
}
?>

Video

 

NetBeans Project Download

 

Thanks friends
Your queries & suggestions are welcome in comments section
Please don’t forget to share if you find this helpful

The post Capture Image From Video and Saving to Server in Javascript appeared first on ZatackCoder.

]]>
https://zatackcoder.com/capture-image-from-video-and-saving-to-server-in-javascript/feed/ 0 2815
Create Dynamic XML Sitemap Using PHP https://zatackcoder.com/create-dynamic-xml-sitemap-using-php/ Wed, 01 Jul 2020 14:06:49 +0000 https://zatackcoder.com/?p=2820 If you are managing a website that has large numbers of pages, it’s very difficult to add all URLs in sitemap one by one Especially if page creation frequency is high. Either you are an SEO or Developer, I am sure you had to face this problem. So today I am here with the solution....

The post Create Dynamic XML Sitemap Using PHP appeared first on ZatackCoder.

]]>

If you are managing a website that has large numbers of pages, it’s very difficult to add all URLs in sitemap one by one Especially if page creation frequency is high. Either you are an SEO or Developer, I am sure you had to face this problem. So today I am here with the solution. It’s very easy but a little tricky.

The sitemap is used to submit all internal URLs to Search Engines like Google, Yahoo, Bing, etc for indexing.

So, Without wasting time let’s learn how to create  Dynamic XML Sitemap using PHP

Go to the website root folder or anywhere you want to put a sitemap file. For learning, i am using root path public_html & create a file named sitemap.php & add the source code.

Source Code

<?php
 require 'include/db_connection.php'; //Include Database connection File
 //If not created Database connection file the use below line
 $con = mysqli_connect("localhost", "root", "", "testing");
 $querry = "SELECT PropertyID FROM property_list"; //Get Data from SQL Server
 $result = mysqli_query($con, $querry);
 $base_url ="http://www.vinebrookhomes.com/property-details/";//Set Base path if complete URLs are not stored in database
 header("Content-Type: application/xml; charset=utf-8"); //Add Header
 echo '<?xml version="1.0" encoding="UTF-8"?>'.PHP_EOL; // Print XML Version
 echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">' . PHP_EOL;
while($row = mysqli_fetch_array($result)) //Loop for printing all URLs one by one
{
 echo '<url>' . PHP_EOL; // Print url tag
 echo '<loc>'.$base_url. $row["PropertyID"] .'/</loc>' . PHP_EOL; // Print URL's
 echo '<changefreq>daily</changefreq>' . PHP_EOL; // Set indexing Frequency
 echo '</url>' . PHP_EOL; // End URLs
}
echo '</urlset>' . PHP_EOL; // End Sitemap

?>

Output

Wait… It’s not completed yet. Probably you forgot to check the URL. It’s with .php extension. But Google support only .xml sitemap

To solve this problem you need to add this code to the .htaccess file. Its rewrite .php extension to .xml for sitemap.php.

RewriteEngine On 
RewriteRule ^sitemap2\.xml?$ sitemap2.php

If you have any question, Kindly reply in comment section. Please like & share if you want more similar posts

The post Create Dynamic XML Sitemap Using PHP appeared first on ZatackCoder.

]]>
2820
Sending Message to WhatsApp Number in Android https://zatackcoder.com/sending-message-to-whatsapp-number-in-android/ https://zatackcoder.com/sending-message-to-whatsapp-number-in-android/#respond Sun, 07 Jun 2020 16:09:16 +0000 https://zatackcoder.com/?p=2461 Hello Friends, Today we are going see an example of sending message to whatsapp number  in android. WhatsApp Messenger, or simply WhatsApp, is an American freeware, cross-platform messaging and Voice over IP service owned by Facebook, Inc. Actually I have added this feature in one of my office’s android project few days ago. Using this...

The post Sending Message to WhatsApp Number in Android appeared first on ZatackCoder.

]]>

Hello Friends, Today we are going see an example of sending message to whatsapp number  in android. WhatsApp Messenger, or simply WhatsApp, is an American freeware, cross-platform messaging and Voice over IP service owned by Facebook, Inc. Actually I have added this feature in one of my office’s android project few days ago. Using this example we can send message to specific whatsapp number or we can open whatsapp with specific message and later we can select contact in whatsapp or we can send specific message to specific whatsapp number as well. There are two buttons to trigger Whatsapp message, you can use any one you want but WHATSAPP 2 button is better because WHATSAPP 1 button doesn’t allow set specific message but can set specific number. So, lets see the code without wasting any more time…

MainActivity.java

package com.zatackcoder.sendingmessagetowhatsapp;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final EditText countryCodeET = findViewById(R.id.country_code);
        final EditText mobileET = findViewById(R.id.mobile);
        final EditText messageET = findViewById(R.id.message);

        Button button1 = findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String countryCode = countryCodeET.getText().toString().trim();
                String mobile = mobileET.getText().toString().trim();
                String message = messageET.getText().toString();
                try {
                    Intent sendIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:" + countryCode + mobile + "?body=" + message)); // I have appended  message here but it doesn't work use second method to send message as well
                    //sendIntent.putExtra(Intent.EXTRA_TEXT, message);
                    sendIntent.setPackage("com.whatsapp");
                    startActivity(sendIntent);
                } catch (Exception e) {
                    Toast.makeText(getApplicationContext(), "It seems whatsapp not installed on your phone!", Toast.LENGTH_LONG).show();
                }
            }
        });

        Button button2 = findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String countryCode = countryCodeET.getText().toString().trim();
                String mobile = mobileET.getText().toString().trim();
                String message = messageET.getText().toString();
                try {
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse("http://api.whatsapp.com/send?phone=" + countryCode + mobile + "&text=" + message));
                    startActivity(intent);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_gravity="center"
    android:gravity="center"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send Message to WhatsApp"
        android:textSize="18dp"
        android:textColor="#000"
        android:layout_marginBottom="30dp"/>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:background="#FAECEC">

        <EditText
            android:id="@+id/country_code"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ems="5"
            android:text="91"
            android:hint="Country Code"
            android:singleLine="true"
            android:ellipsize="end"/>

        <EditText
            android:id="@+id/mobile"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="Mobile"
            android:inputType="phone"/>

    </LinearLayout>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="91 is country code here change it accordingly\n if sending on non indian mobile number"/>

    <EditText
        android:id="@+id/message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:lines="3"
        android:hint="Message" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center">

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="WhatsApp 1"
            android:layout_marginTop="20dp"/>

        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="WhatsApp 2"
            android:layout_marginTop="20dp"/>

    </LinearLayout>

</LinearLayout>

Screenshot

sending-message-to-whatsapp

Android Studio Project Download

 

Thanks for Stoping by
If you find this helpful then please do share
Any suggestions and queries are welcome in comment section

The post Sending Message to WhatsApp Number in Android appeared first on ZatackCoder.

]]>
https://zatackcoder.com/sending-message-to-whatsapp-number-in-android/feed/ 0 2461
Connect Google App Engine with Google Cloud Storage https://zatackcoder.com/connect-google-app-engine-with-google-cloud-storage/ https://zatackcoder.com/connect-google-app-engine-with-google-cloud-storage/#respond Sat, 06 Jun 2020 11:13:26 +0000 https://zatackcoder.com/?p=2312 Hello Friends, I hope you are doing well. Today we are going to see how to connect Google App Engine with Google Cloud Storage. App Engine is a fully managed, serverless platform for developing and hosting web applications at scale while Cloud Storage is a RESTful file storage service for storing and accessing data on...

The post Connect Google App Engine with Google Cloud Storage appeared first on ZatackCoder.

]]>
Hello Friends, I hope you are doing well. Today we are going to see how to connect Google App Engine with Google Cloud Storage. App Engine is a fully managed, serverless platform for developing and hosting web applications at scale while Cloud Storage is a RESTful file storage service for storing and accessing data on Google Cloud Platform. Google Cloud Storage service can be used to serve website content, store data for archival and disaster recovery or distributing large files to users via direct download. Here we are going to develop a one page app which will give us options to upload file, list files as well as delete files. So, without wasting any time let’s do it by following below steps:-

Step 1: Login to Google Cloud Console and Create a Project

app-engine-with-cloudstorage-create-project

 

Step 2: Go to App Engine and Create Application using below command in Cloud Shell or you can also follow steps by clicking on create application see screenshots below for your reference

gcloud app create --region=asia-south1

OR

app-engine-with-cloudstorage-create-application-step-1 app-engine-with-cloudstorage-create-application-step-3 app-engine-with-cloudstorage-create-application-step-4
Step 1 Step 2 Step 3 Step 4

Step 3: After receiving success open Cloud Shell if not already opened and click on pencil icon to Launch Editor

app-engine-with-cloudstorage-open-editor

Step 4: Download Google Cloud Storage Library using below command

composer require google/cloud-storage

Composer comes pre-installed on Cloud Shell so you need to install it, but still if you need guidance to install composer you check here https://getcomposer.org/.
After executing above command you’ll see vendor directory which contains cloud storage library and two more files called composer.json and composer.lock

Step 5: Now It’s Time to Code

app.yaml

# Use the PHP 7.3 runtime (BETA) by replacing "php72" below with "php73"
runtime: php73

env_variables:
  BUCKET_NAME: "mydemoproject-278919.appspot.com"

We configure our App Engine app’s settings in the app.yaml file. The app.yaml file also contains information about your app’s code, PHP runtime, and entrypoint.

Here we are defining an environment variable named as BUCKET_NAME which we will use in our code, this bucket name you can get from Navigation Menu => Storage Option in GCP Console. Actually, when we create App Engine project a bucket is automatically created by App Engine for the use in your app with named as “yourprojectid.appspot.com”.

config.php

<?php

// load GCS library
require __DIR__ . '/vendor/autoload.php';

use Google\Cloud\Storage\StorageClient;

function uploadFile($bucketName, $fileContent, $cloudPath, $makePublic = false) {
    $storage = new StorageClient();
    
    // set which bucket to work in
    $bucket = $storage->bucket($bucketName);
    
    // upload/replace file 
    $object = $bucket->upload(
            $fileContent,
            ['name' => $cloudPath]
            // if $cloudPath is existed then will be overwrite without confirmation
            // NOTE: 
            // a. do not put prefix '/', '/' is a separate folder name  !!
    );
    
    // is it succeed ?
    if($object != null) {
        if($makePublic) {
            $object->update(['acl' => []], ['predefinedAcl' => 'PUBLICREAD']);
        }
        return true;
    }
    return false;
}

function getFileInfo($bucketName, $cloudPath) {
    $storage = new StorageClient();
    
    // set which bucket to work in
    $bucket = $storage->bucket($bucketName);
    $object = $bucket->object($cloudPath);
    return $object->info();
}

function getFiles($bucketName, $directory = null) {
    $storage = new StorageClient();
    
    // set which bucket to work in
    $bucket = $storage->bucket($bucketName);
    
    if ($directory == null) {
        // list all files
        $objects = $bucket->objects();
    } else {
        // list all files within a directory (sub-directory)
        $options = array('prefix' => $directory);
        $objects = $bucket->objects($options);
    }

    return $objects;
}

function deleteFile($bucketName, $objectName, $options = []) {
    $storage = new StorageClient();
    
    // set which bucket to work in
    $bucket = $storage->bucket($bucketName);
    try {
        $object = $bucket->object($objectName);
        $object->delete();
    } catch (Exception $exc) {
        //exception handling
    }
}

All necessary functions for uploading, listing and deleting files are defined here in this file

index.php

<?php
# [START gae_simple_front_controller]
switch (@parse_url($_SERVER['REQUEST_URI'])['path']) {
    case '/':
        require 'home.php';
        break;
    case '/requests.php':
        require 'requests.php';
        break;
    default:
        http_response_code(404);
        exit('Not Found');
}
?>

User requests routing code which responds according to path i.e opening home page sending ajax request to requests.php showing 404 on invalid path

home.php

<?php
require_once 'config.php';

if (!getenv('BUCKET_NAME')) {
    die('Set BUCKET_NAME environment variables');
}

$bucketName = getenv('BUCKET_NAME');
if (isset($_REQUEST['delete']) && isset($_REQUEST['name'])) {
    $fileName = urldecode($_REQUEST['name']);
    deleteFile($bucketName, $fileName);
    //header("Location: /");
    echo '<script>window.location.href = "/"</script>';
    exit();
}

$objects = getFiles($bucketName);
?>
<html>
    <head>
        <title>Objects in Bucket</title>
    </head>
    <body>
        <h1>Objects in Bucket</h1>
        <form id="fileUploadForm" method="post" enctype="multipart/form-data">
            <input type="file" name="file"/>
            <input type="submit" name="upload" value="Upload"/>
            <span id="uploadingmsg"></span>
            <hr/>
        </form>
        <table border="1" style="width: 100%;">
            <thead>
                <tr>
                    <td>Object</td>
                    <td>Action</td>
                </tr>
            </thead>
            <tbody id="objects">
                <?php foreach ($objects as $o) {
                    $oinfo = $o->info();
                    ?>
                <tr>
                    <td><a href="https://storage.googleapis.com/<?= $oinfo['bucket'] ?>/<?= $oinfo['name'] ?>"><?= $o->name() ?></a></td>
                    <td><a href="/?delete=1&name=<?= urlencode($o->name()) ?>">Delete</a></td>
                </tr>
                <?php } ?>
            </tbody>
        </table>

        <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
        <script>
            $("#fileUploadForm").submit(function (e) {
                e.preventDefault();
                var action = "requests.php?action=upload";
                $("#uploadingmsg").html("Uploading...");
                var data = new FormData(e.target);
                $.ajax({
                    type: 'POST',
                    url: action,
                    data: data, 
                    /*THIS MUST BE DONE FOR FILE UPLOADING*/
                    contentType: false,
                    processData: false,
                }).done(function (response) {
                    $("#uploadingmsg").html(response.msg);
                    //https://storage.googleapis.com/[BUCKET_NAME]/[OBJECT_NAME]
                    if (response.code == '200') {
                        window.location.reload();
                    }
                }).fail(function (data) {
                    //any message
                });
            });
        </script>
    </body>
</html>

Code to list objects of given bucket, uploading and deleting objects (files)

requests.php

<?php

include_once 'config.php';

$action = filter_var(trim($_REQUEST['action']), FILTER_SANITIZE_STRING);
if ($action == 'upload') {
    $response['code'] = "200";
    if ($_FILES['file']['error'] != 4) {
        //set which bucket to work in
        $bucketName = getenv('BUCKET_NAME');
        // get local file for upload testing
        $fileContent = file_get_contents($_FILES["file"]["tmp_name"]);
        // NOTE: if 'folder' or 'tree' is not exist then it will be automatically created !
        $cloudPath = $_FILES["file"]["name"];

        $isSucceed = uploadFile($bucketName, $fileContent, $cloudPath, true);

        if ($isSucceed == true) {
            $response['msg'] = 'SUCCESS: to upload ' . $cloudPath . PHP_EOL;
            // TEST: get object detail (filesize, contentType, updated [date], etc.)
            $response['data'] = getFileInfo($bucketName, $cloudPath);
        } else {
            $response['code'] = "201";
            $response['msg'] = 'FAILED: to upload ' . $cloudPath . PHP_EOL;
        }
    }
    header("Content-Type:application/json");
    echo json_encode($response);
    exit();
}

This file is called through ajax to upload file on google cloud storage and here you can see $cloudPath variable which is used to store file path and if we need to store it in database we can do so and later we can fetch it from our database instead of cloud storage api. We can also use Cloud SQL in our application to make our application fully cloud based if you are not aware how to use Cloud SQL with App Engine then checkout this post Connect Google App Engine with Google Cloud SQL.

Step 6: Go to Editor which we had launched in step 3 and upload all the files created in step 5.

app-engine-with-cloud-storage-upload-files app-engine-with-cloud-storage-files-uploaded

Step 7: Deploy App using below command

gcloud app deploy
OR
gcloud app deploy --version v1

app-engine-with-cloud-storage-deploy-app

Step 8: Access App

app-engine-with-cloud-storage-accessing-app

 

Note: –

We don’t have to create service account and download private key just as we had done in Upload File to Google Cloud Storage using PHP article as this code is running on App Engine and App Engine app by default connected to a service account which have access to Cloud Storage.

Video

NetBeans Project Download

References:-

https://cloud.google.com/appengine/docs/standard/php7/config/appref
https://cloud.google.com/appengine/docs/standard/php7/using-cloud-storage
https://cloud.google.com/storage/docs/uploading-objects#storage-upload-object-code-sample
https://cloud.google.com/storage/docs/access-control/making-data-public#storage-make-object-public-php
https://cloud.google.com/storage/docs/listing-objects#storage-list-objects-php
https://cloud.google.com/storage/docs/deleting-objects#storage-delete-object-php

 

Thank you Friends
Please don’t forget share if you it useful

The post Connect Google App Engine with Google Cloud Storage appeared first on ZatackCoder.

]]>
https://zatackcoder.com/connect-google-app-engine-with-google-cloud-storage/feed/ 0 2312
Get Back 1080p And 720p Video Quality Option Youtube for Mobile & Television https://zatackcoder.com/get-back-1080p-and-720p-video-quality-option-youtube-for-mobile-television/ https://zatackcoder.com/get-back-1080p-and-720p-video-quality-option-youtube-for-mobile-television/#respond Tue, 02 Jun 2020 13:41:09 +0000 https://zatackcoder.com/?p=2739 Hi Friends, Hope you are doing well. Today I am going to share a 100% working trick to play youtube videos at HD Quality 1080P or More. You might be noticed recently Google restricted 780P or above quality videos and allow up to 450p at youtube app for mobiles & TV Youtube said that we’re...

The post Get Back 1080p And 720p Video Quality Option Youtube for Mobile & Television appeared first on ZatackCoder.

]]>

Hi Friends, Hope you are doing well. Today I am going to share a 100% working trick to play youtube videos at HD Quality 1080P or More. You might be noticed recently Google restricted 780P or above quality videos and allow up to 450p at youtube app for mobiles & TV

Youtube said that we’re taking this action globally to do our part to minimize stress on the system. For mobile, it’s not making any changes because display size is around 5 to 6 Inch but what about Android TV where the display size is 42 to 50 Inch. 420P Videos are very blurry for TV.

We have working techniques to solve this issue

Method 1

Step 1. Use any browsers like Chrome, Firefox, Opera, etc. & Open youtube.com

Step 2. Go to Settings & Click on Desktop Site.

Step 3. Then select the preferred video resolution

Method 2

Step 1. Go to the Play store & Search “Free VPN” & Install anyone

Personally I suggest you install Go VPN because I am also using it. Here you can select manually server location with speed. It helps you to select the fastest proxy.

Step 2. Select the United States Proxy

Step 3. Close your youtube app if opened previously & Start Again.

Step 4. Go to any HD video & you will get the option for 720P & 1080P

 

I hope this post is helpful to you. If you are looking for similar articles so please like & share it. You can also suggest your topics.

 

 

 

 

The post Get Back 1080p And 720p Video Quality Option Youtube for Mobile & Television appeared first on ZatackCoder.

]]>
https://zatackcoder.com/get-back-1080p-and-720p-video-quality-option-youtube-for-mobile-television/feed/ 0 2739
Resize Disk of VM Instance on Google Cloud Platform without Stopping VM https://zatackcoder.com/resize-disk-of-vm-instance-on-google-cloud-platform-without-stopping-vm/ https://zatackcoder.com/resize-disk-of-vm-instance-on-google-cloud-platform-without-stopping-vm/#respond Sat, 30 May 2020 11:56:11 +0000 https://zatackcoder.com/?p=2706 Hello friends, today we’ll see how to resize disk of VM instance on Google Cloud Platform without stopping VM. Actually one of my colleague was working on a project which was hosted on GCP Compute Engine VM and while working on the project suddenly he ran out of disk storage then he asked me for...

The post Resize Disk of VM Instance on Google Cloud Platform without Stopping VM appeared first on ZatackCoder.

]]>

Hello friends, today we’ll see how to resize disk of VM instance on Google Cloud Platform without stopping VM. Actually one of my colleague was working on a project which was hosted on GCP Compute Engine VM and while working on the project suddenly he ran out of disk storage then he asked me for help. Then I said ok and after figuring out I found there was only 10 GB of disk space, so I asked him to stop the vm and increase disk space but he hadn’t want to stop the vm. Then I googled and came up with another solution which I am sharing now. This solution applies on most common case which is – “the disk should have single partition”.

Step 1: SSH into your VM

gcp-increase-disk-space-ssh-1
gcp-increase-disk-space-ssh-2

Step 2: Check Available Disk Size using df below command (Optional)

rajesh@instance-1:~$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root       9.6G  1.4G  8.2G  14% /
devtmpfs        1.8G     0  1.8G   0% /dev
tmpfs           1.8G     0  1.8G   0% /dev/shm
tmpfs           369M  912K  368M   1% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           1.8G     0  1.8G   0% /sys/fs/cgroup
/dev/sda15      105M  3.9M  101M   4% /boot/efi
/dev/loop0       28M   28M     0 100% /snap/snapd/7264
/dev/loop1       55M   55M     0 100% /snap/core18/1754
/dev/loop2       70M   70M     0 100% /snap/lxd/15161
/dev/loop3      115M  115M     0 100% /snap/google-cloud-sdk/133
tmpfs           369M     0  369M   0% /run/user/1001

Step 3: Check partition using lsblk command

rajesh@instance-1:~$ sudo lsblk
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
loop0     7:0    0 27.1M  1 loop /snap/snapd/7264
loop1     7:1    0   55M  1 loop /snap/core18/1754
loop2     7:2    0 69.3M  1 loop /snap/lxd/15161
loop3     7:3    0  115M  1 loop /snap/google-cloud-sdk/133
sda       8:0    0   10G  0 disk 
├─sda1    8:1    0  9.9G  0 part /
├─sda14   8:14   0    4M  0 part 
└─sda15   8:15   0  106M  0 part /boot/efi

Step 4: Increase disk size from GCP console or by running below command in cloud shell

gcloud compute disks resize INSTANCE_NAME --zone ZONE --size 30GB --quiet

replace INSTANCE_NAME with your instance name and ZONE with your zone name

OR

gcp-increase-disk-space-increase-disk-1 gcp-increase-disk-space-increase-disk-2
Go to Disk Section of Compute Engine and click on the name of the disk of which you want to increase space and then click edit then change disk size according to your need and click save

Step 5: Grow Partition using growpart command

for debian and ubuntu

rajesh@instance-1:~$ sudo growpart /dev/sda 1
CHANGED: partition=1 start=227328 old: size=20744159 end=20971487 new: size=62687199 end=62914527

for centos

[rajesh@instance-3 ~]$ sudo growpart /dev/sda 2
CHANGED: partition=2 start=411648 old: size=41529344 end=41940992 new: size=62502879,end=62914527

Note: if you get command not found error then you can use below command to install it

for debian and ubuntu

sudo apt-get install cloud-utils

for centos

sudo yum install cloud-utils-growpart

Step 6: Resize filesytem

for debian and ubuntu

rajesh@instance-1:~$ sudo resize2fs /dev/sda1
resize2fs 1.45.5 (07-Jan-2020)
Filesystem at /dev/sda1 is mounted on /; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 4
The filesystem on /dev/sda1 is now 7835899 (4k) blocks long.

for centos

[rajesh@instance-3 ~]$ sudo mount /dev/sda2 /mnt
[rajesh@instance-3 ~]$ sudo xfs_growfs -d /mnt
meta-data=/dev/sda1              isize=512    agcount=4, agsize=1297792 blks
         =                       sectsz=4096  attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=0
         =                       reflink=1
data     =                       bsize=4096   blocks=5191168, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data size 51200 too small, old size is 5191168

Step 7: Verify using df command

rajesh@instance-1:~$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        29G  1.4G   28G   5% /
devtmpfs        1.8G     0  1.8G   0% /dev
tmpfs           1.8G     0  1.8G   0% /dev/shm
tmpfs           369M  912K  368M   1% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           1.8G     0  1.8G   0% /sys/fs/cgroup
/dev/sda15      105M  3.9M  101M   4% /boot/efi
/dev/loop0       28M   28M     0 100% /snap/snapd/7264
/dev/loop1       55M   55M     0 100% /snap/core18/1754
/dev/loop2       70M   70M     0 100% /snap/lxd/15161
/dev/loop3      115M  115M     0 100% /snap/google-cloud-sdk/133
tmpfs           369M     0  369M   0% /run/user/1001

That’s it

If you find this helpful then please do share
Any suggestions and queries are welcome in comment section

The post Resize Disk of VM Instance on Google Cloud Platform without Stopping VM appeared first on ZatackCoder.

]]>
https://zatackcoder.com/resize-disk-of-vm-instance-on-google-cloud-platform-without-stopping-vm/feed/ 0 2706
SearchView Suggestions over Network in Android https://zatackcoder.com/searchview-suggestions-over-network-in-android/ https://zatackcoder.com/searchview-suggestions-over-network-in-android/#respond Sun, 24 May 2020 06:48:40 +0000 https://zatackcoder.com/?p=2459 Hello Friends, Today we’ll see an example of SearchView Suggestions over Network in Android. And there will be two part of this code one will be server side code in PHP and another one Android app code. Actually I was working on an android app in which I was required to add search suggestion over...

The post SearchView Suggestions over Network in Android appeared first on ZatackCoder.

]]>

Hello Friends, Today we’ll see an example of SearchView Suggestions over Network in Android. And there will be two part of this code one will be server side code in PHP and another one Android app code. Actually I was working on an android app in which I was required to add search suggestion over network feature in that, So now I am sharing this sample code almost same as I have developed for the app just to help others and me in future projects. If you want to know how to use SearchView in toolbar before proceeding with suggestion over network you can checkout this post.

Let’s code now without wasting any time..

Server Side PHP Code

config.php

<?php
date_default_timezone_set("Asia/Kolkata");

define("DATABASE_NAME", "YOUR-DB-NAME");

function getConnection() {
    $servername = "localhost";
    $username = "YOUR-USERNAME";
    $password = "YOUR-PASSWORD";

    // Create connection
    $conn = new mysqli($servername, $username, $password, DATABASE_NAME);
    // Check connection
    if (mysqli_connect_error()) {
        die("Database connection failed: " . mysqli_connect_error());
    } else {
        return $conn;
    }
}

define("KEY", "SECUREKEY");

api.php

<?php
include_once 'config.php';

header("Content-Type:application/json");
if (!isset($_REQUEST['key']) || trim($_REQUEST['key']) != KEY) {
    die("Not authorised");
}
if (!isset($_REQUEST['action'])) {
    echo "Please provide action parameter";
    die();
}
$action = trim($_REQUEST['action']);

if ($action == 'get-search-suggestions') {
    $conn = getConnection();
    //check get parameter or request parameter or post parameter and respond accordingly    
    if (isset($_REQUEST['term'])) {
        $term = filter_var(trim($_REQUEST['term']), FILTER_SANITIZE_STRING);
        $results = $conn->query("SELECT id, name, color, size, price FROM items WHERE name LIKE '%{$term}%' OR color LIKE '%{$term}%' OR size LIKE '%{$term}%' OR price LIKE '%{$term}%' LIMIT 5");
        echo $conn->error;
        $suggestions = array();
        while ($row = $results->fetch_assoc()) {
            $suggestions[] = $row;
        }
        respond("200", "Search Suggestions", $suggestions);
        exit();
    }
}

function respond($status, $status_message, $data) {
    header("HTTP/1.1 $status $status_message");
    $response['status'] = $status;
    $response['status_message'] = $status_message;
    $response['data'] = $data;

    echo json_encode($response);
}

Android App Code

MainActivity.java

package com.zatackcoder.searchviewsuggestionsovernetwork;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.recyclerview.widget.RecyclerView;

import android.app.SearchManager;
import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.BaseColumns;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private SuggestionAdapter suggestionAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.menu_main_activity, menu);

        MenuItem searchItem = menu.findItem(R.id.action_search);

        SearchManager searchManager = (SearchManager) getApplicationContext().getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = null;
        if (searchItem != null) {
            searchView = (SearchView) searchItem.getActionView();
        }
        if (searchView != null) {
            searchView.setSearchableInfo(searchManager.getSearchableInfo(MainActivity.this.getComponentName()));
            searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
                @Override
                public boolean onQueryTextSubmit(String s) {
                    return true;
                }

                @Override
                public boolean onQueryTextChange(String s) {
                    new GetSuggestionsAsyncTask(MainActivity.this, s).execute();
                    return false;
                }
            });
            suggestionAdapter = new SuggestionAdapter(getApplicationContext(), null, false);
            searchView.setSuggestionsAdapter(suggestionAdapter);
        }
        return super.onCreateOptionsMenu(menu);
    }

    static class GetSuggestionsAsyncTask extends AsyncTask<Void, Void, Cursor> {

        private final WeakReference<MainActivity> activityReference;
        final String term;

        GetSuggestionsAsyncTask(MainActivity context, String term) {
            this.activityReference = new WeakReference<>(context);
            this.term = term;
        }

        @Override
        protected Cursor doInBackground(Void... voids) {
            HashMap<String, String> params = new HashMap<>();
            params.put("key", "SECUREKEY");
            params.put("action", "get-search-suggestions");
            params.put("term", term);

            JsonParser jsonParser = new JsonParser();
            JSONObject jsonObject = jsonParser.get("https://zatackcoder.com/demo/searchview-suggestion-over-network/api.php", params);

            MatrixCursor cursor = new MatrixCursor(new String[]{BaseColumns._ID, "name", "color", "size", "price"});

            if (jsonObject != null) {
                try {
                    JSONArray dataJsonArray = jsonObject.getJSONArray("data");
                    int j = 0;
                    for (int i = 0; i < dataJsonArray.length(); i++) {
                        JSONObject tmp = dataJsonArray.getJSONObject(i);
                        String[] row = {Integer.toString(j++), tmp.getString("name"), tmp.getString("color"), tmp.getString("size"), tmp.getString("price")};
                        cursor.addRow(row);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            return cursor;
        }

        @Override
        protected void onPostExecute(Cursor cursor) {
            super.onPostExecute(cursor);
            MainActivity mainActivity = activityReference.get();
            if(mainActivity == null || mainActivity.isFinishing()) {
                return;
            }
            mainActivity.suggestionAdapter.changeCursor(cursor);
        }
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="SearchView Suggestion Over Network Example"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

JsonParser.java

package com.zatackcoder.searchviewsuggestionsovernetwork;


import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;

/**
 * Created by rajesh kumar sahanee on 19/9/17.
 */

public class JsonParser {

    private final String TAG = "JsonParser";
    private HttpURLConnection conn;
    private final StringBuilder result = new StringBuilder();
    private JSONObject jsonObject;

    public JSONObject post(String url, HashMap<String, String> params, HashMap<String, String> files) {

        try {
            conn = (HttpURLConnection) new URL(url).openConnection();
            conn.setDoInput(true);//Allow Inputs
            conn.setDoOutput(true);//Allow Outputs
            conn.setUseCaches(false);//Don't use a cached Copy
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Accept-Charset", "UTF-8");
            conn.setReadTimeout(10000);
            conn.setConnectTimeout(50000);
            String boundary = "*****";
            if (files != null) {
                conn.setRequestProperty("ENCTYPE", "multipart/form-data");
                conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
                for (String key : files.keySet()) {
                    conn.setRequestProperty(key, files.get(key));
                }
            }

            conn.connect();
            DataOutputStream dataOutputStream = new DataOutputStream(conn.getOutputStream());

            //file uploading
            String twoHyphens = "--";
            String lineEnd = "\r\n";
            if (files != null) {
                for (String key : files.keySet()) {
                    int bytesRead, bytesAvailable, bufferSize;
                    byte[] buffer;
                    int maxBufferSize = 1024 * 1024; //1 * 1024 * 1024

                    File selectedFile = new File(files.get(key));
                    if (!selectedFile.isFile()) {
                        break;
                    }

                    dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
                    //writing bytes to data outputstream
                    dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" + key + "\";filename=\"" + files.get(key) + "\"" + lineEnd);

                    dataOutputStream.writeBytes(lineEnd);

                    FileInputStream fileInputStream = new FileInputStream(selectedFile);
                    //returns no. of bytes present in fileInputStream
                    bytesAvailable = fileInputStream.available();
                    //selecting the buffer size as minimum of available bytes or 1 MB
                    bufferSize = Math.min(bytesAvailable, maxBufferSize);
                    //setting the buffer as byte array of size of bufferSize
                    buffer = new byte[bufferSize];

                    //reads bytes from FileInputStream(from 0th index of buffer to buffersize)
                    bytesRead = fileInputStream.read(buffer, 0, bufferSize);

                    //loop repeats till bytesRead = -1, i.e., no bytes are left to read
                    while (bytesRead > 0) {
                        //write the bytes read from inputstream
                        dataOutputStream.write(buffer, 0, bufferSize);
                        bytesAvailable = fileInputStream.available();
                        bufferSize = Math.min(bytesAvailable, maxBufferSize);
                        bytesRead = fileInputStream.read(buffer, 0, bufferSize);
                    }

                    dataOutputStream.writeBytes(lineEnd);
                    dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
                    fileInputStream.close();
                }
            }
            //parameters writing when file uploading
            if (params != null && files != null) {
                for (String key : params.keySet()) {
                    dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
                    dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" + key + "\"" + lineEnd);
                    dataOutputStream.writeBytes(lineEnd);
                    dataOutputStream.writeBytes(params.get(key));
                    dataOutputStream.writeBytes(lineEnd);
                    dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
                }
            }
            //parameters writing when no file uploading
            else if (params != null) {
                StringBuilder psb = new StringBuilder();
                boolean flag = false;
                for (String key : params.keySet()) {
                    try {
                        if (flag) {
                            psb.append("&");
                        }
                        psb.append(key).append("=").append(URLEncoder.encode(params.get(key), "UTF-8"));

                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                    flag = true;
                }
                dataOutputStream.writeBytes(psb.toString());
            }

            Log.d(TAG, "RC: " + conn.getResponseCode() + " RM: " + conn.getResponseMessage());

            dataOutputStream.flush();
            dataOutputStream.close();

        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            //Receive the response from the server
            BufferedReader reader = new BufferedReader(new InputStreamReader(new BufferedInputStream(conn.getInputStream())));

            String line;
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }

            Log.d(TAG, "Result: " + result.toString());

        } catch (IOException e) {
            e.printStackTrace();
        }

        conn.disconnect();

        // try parse the string to a JSON object
        try {
            jsonObject = new JSONObject(result.toString());
        } catch (JSONException e) {
            Log.e(TAG, "Error parsing data " + e.toString());
        }

        // return JSON Object
        return jsonObject;
    }

    public JSONObject get(String url, HashMap<String, String> params) {

        StringBuilder psb = new StringBuilder();
        boolean flag = false;
        for (String key : params.keySet()) {
            if (flag) {
                psb.append("&");
            }
            try {
                psb.append(key).append("=").append(URLEncoder.encode(params.get(key), "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            flag = true;
        }

        if (psb.length() != 0) {
            url += "?" + psb.toString();
            Log.d(TAG, "url: " + url);
        }

        try {
            conn = (HttpURLConnection) new URL(url).openConnection();
            conn.setDoOutput(false);
            conn.setRequestMethod("GET");
            conn.setRequestProperty("Accept-Charset", "UTF-8");
            conn.setConnectTimeout(15000);
            conn.connect();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            //Receive the response from the server
            BufferedReader reader = new BufferedReader(new InputStreamReader(new BufferedInputStream(conn.getInputStream())));

            String line;
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }

            Log.d(TAG, "Result: " + result.toString());

        } catch (IOException e) {
            e.printStackTrace();
        }

        conn.disconnect();

        // try parse the string to a JSON object
        try {
            jsonObject = new JSONObject(result.toString());
        } catch (JSONException e) {
            Log.e(TAG, "Error parsing data " + e.toString());
        }

        // return JSON Object
        return jsonObject;
    }
}

SuggestionAdapter.java

package com.zatackcoder.searchviewsuggestionsovernetwork;

import android.content.Context;
import android.database.Cursor;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.cursoradapter.widget.CursorAdapter;

public class SuggestionAdapter extends CursorAdapter {

    public SuggestionAdapter(Context context, Cursor c, boolean autoRequery) {
        super(context, c, autoRequery);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        return LayoutInflater.from(context).inflate(R.layout.search_view_suggestion, parent, false);
    }

    @Override
    public void bindView(View view, final Context context, Cursor cursor) {
        TextView nameTV = view.findViewById(R.id.nameTV);
        TextView descTV = view.findViewById(R.id.descTV);

        if(cursor.getColumnIndex("name") != -1 && cursor.getString(cursor.getColumnIndex("name")) != null) {
            final String name = cursor.getString(cursor.getColumnIndex("name"));
            String color = cursor.getString(cursor.getColumnIndex("color"));
            String size = cursor.getString(cursor.getColumnIndex("size"));
            String price = cursor.getString(cursor.getColumnIndex("price"));

            nameTV.setText(name);
            descTV.setText(String.format("color:%s size%s price:%s", color, size, price));

            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(context, "You Just Clicked " + name, Toast.LENGTH_LONG).show();
                }
            });
        }
    }
}

search_view_suggestion.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    android:padding="5dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?android:attr/selectableItemBackground"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/imageIV"
            android:layout_width="36dp"
            android:layout_height="36dp"
            android:layout_marginEnd="2dp"
            android:layout_marginRight="2dp"
            app:srcCompat="@android:drawable/ic_menu_search"
            android:src="@android:drawable/ic_menu_search"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:id="@+id/nameTV"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:lines="1"
                android:maxLines="1"
                android:textSize="14sp" />

            <TextView
                android:id="@+id/descTV"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:textAlignment="center"
                android:textSize="12sp" />

        </LinearLayout>

    </LinearLayout>

</RelativeLayout>

menu/menu_main_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_search"
        android:icon="@android:drawable/ic_menu_search"
        android:title="Search"
        app:actionViewClass="androidx.appcompat.widget.SearchView"
        app:showAsAction="always|collapseActionView" />
</menu>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.zatackcoder.searchviewsuggestionsovernetwork">

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Video

 

PHP Script Download

Android Studio Project Download

 

Thanks for Stoping by
If you find this helpful then please do share
Any suggestions and queries are welcome in comment section

The post SearchView Suggestions over Network in Android appeared first on ZatackCoder.

]]>
https://zatackcoder.com/searchview-suggestions-over-network-in-android/feed/ 0 2459
ViewHolder Pattern with BaseAdapter in Android https://zatackcoder.com/viewholder-pattern-with-baseadapter-in-android/ Sun, 17 May 2020 05:00:19 +0000 https://zatackcoder.com/?p=2434 Hello Friends, today we are going see an example of ViewHolder Pattern with BaseAdapter in Android. I am sharing this code example because few weeks ago I was working on a project and after completing code, I have analyzed my code using “Inspect Code…” feature of Android Studio which is available under Analyze menu. And...

The post ViewHolder Pattern with BaseAdapter in Android appeared first on ZatackCoder.

]]>

Hello Friends, today we are going see an example of ViewHolder Pattern with BaseAdapter in Android. I am sharing this code example because few weeks ago I was working on a project and after completing code, I have analyzed my code using “Inspect Code…” feature of Android Studio which is available under Analyze menu. And I found performance issue in my code (see screenshot below). Then I googled and found this solution which I am sharing now.

without-viewholder-pattern
Unconditional layout inflation from view adapter: Should use View Holder pattern (use recycled view passed into this method as the second parameter) for smoother scrolling

Let’s Code Now

MainActivity.java

package com.zatackcoder.viewholderpatternwithbaseadapter;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        List<Item> items = new ArrayList<>();
        Random random = new Random();
        for(int i = 1; i <= 2000; i++) {
            items.add(new Item("Item " + i, random.nextInt(1000)));
        }

        ListView listView = findViewById(R.id.list_view);
        listView.setAdapter(new MyBaseAdapter(this, items));
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

MyBaseAdapter.java

package com.zatackcoder.viewholderpatternwithbaseadapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;

class MyBaseAdapter extends BaseAdapter {
    private final Context context;
    private final List<Item> items;

    public MyBaseAdapter(Context context, List<Item> items) {
        this.context = context;
        this.items = items;
    }

    @Override
    public int getCount() {
        return items.size();
    }

    @Override
    public Object getItem(int position) {
        return items.get(position);
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if(convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);

            viewHolder = new ViewHolder();
            viewHolder.nameTV = convertView.findViewById(R.id.name);
            viewHolder.priceTV = convertView.findViewById(R.id.price);

            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        /*
        convertView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);

        ViewHolder viewHolder = new ViewHolder();
        viewHolder.nameTV = convertView.findViewById(R.id.name);
        viewHolder.priceTV = convertView.findViewById(R.id.price);
        */
        final Item item = items.get(position);

        viewHolder.nameTV.setText(item.getName());
        viewHolder.priceTV.setText(String.valueOf(item.getPrice()));
        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(context, "You Just Clicked " + item.getName(), Toast.LENGTH_LONG).show();
            }
        });
        return convertView;
    }

    static class ViewHolder {
        TextView nameTV;
        TextView priceTV;
    }
}

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:background="#ffffff"
    android:clickable="true"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?android:attr/selectableItemBackground"
        android:orientation="vertical"
        android:padding="5dp">

        <TextView
            android:id="@+id/name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Name"
            android:textFontWeight="bold"
            android:textSize="15dp" />

        <TextView
            android:id="@+id/price"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Price: 100"
            android:textSize="12dp" />

    </LinearLayout>

</LinearLayout>

Item.java

package com.zatackcoder.viewholderpatternwithbaseadapter;

class Item {

    private String name;
    private Integer price;

    public Item(String name, Integer price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }
}

Video

 

AndroidStudio Project Download

 

References

https://www.javacodegeeks.com/2013/09/android-viewholder-pattern-example.html

The post ViewHolder Pattern with BaseAdapter in Android appeared first on ZatackCoder.

]]>
2434
Update of Create Browser using JavaFX https://zatackcoder.com/update-of-create-browser-using-javafx/ https://zatackcoder.com/update-of-create-browser-using-javafx/#respond Mon, 11 May 2020 11:45:37 +0000 https://zatackcoder.com/?p=2658 Hello Friends, today I am going share an update of create Browser using JavaFX. Actually I was working on a JavaFX application which was making use of WebView but while testing I just browsed flipkart.com and suddenly it started showing “Something’s not right!” error then figured out and found that flipkart has CORS policy disabled...

The post Update of Create Browser using JavaFX appeared first on ZatackCoder.

]]>

Hello Friends, today I am going share an update of create Browser using JavaFX. Actually I was working on a JavaFX application which was making use of WebView but while testing I just browsed flipkart.com and suddenly it started showing “Something’s not right!” error then figured out and found that flipkart has CORS policy disabled for a domain to list products but JavaFX has same origin policy enabled by default. Then I googled and found a solution which I am sharing now. But wait story not ends here, after applying this solution I found another problem which was that while browsing flipkart, url was not reflecting in address bar but webpage was updating then again I googled and found that change listener on LocationProperty of webview is the solution for this problem. Finally I thought to share these solutions by creating update of an existing browser which I have developed and shared long time ago.

So, Here is solution

Browser.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ProgressIndicator?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.ToolBar?>
<?import javafx.scene.control.Tooltip?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.web.WebView?>

<BorderPane fx:id="browserBP" minWidth="480.0" prefHeight="396.0" prefWidth="661.0" xmlns="http://javafx.com/javafx/8.0.101" xmlns:fx="http://javafx.com/fxml/1" fx:controller="browser.BrowserController">
   <center>
      <BorderPane prefHeight="248.0" prefWidth="333.0">
         <center>
            <WebView fx:id="browserWV" prefHeight="200.0" prefWidth="200.0" />
         </center>
         <top>
            <ToolBar prefHeight="40.0" prefWidth="200.0" BorderPane.alignment="CENTER">
              <items>
                <Button mnemonicParsing="false" onAction="#browserBackButtonAction">
                     <graphic>
                        <ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
                           <image>
                              <Image url="@../images/back.png" />
                           </image>
                        </ImageView>
                     </graphic>
                     <tooltip>
                        <Tooltip text="Back" />
                     </tooltip>
                  </Button>
                  <Button mnemonicParsing="false" onAction="#browserForwardButtonAction">
                     <graphic>
                        <ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
                           <image>
                              <Image url="@../images/forward.png" />
                           </image>
                        </ImageView>
                     </graphic>
                     <tooltip>
                        <Tooltip text="Forward" />
                     </tooltip>
                  </Button>
                  <Button mnemonicParsing="false" onAction="#browserStopReloadButtonAction">
                     <graphic>
                        <ImageView fx:id="stopReloadIV" fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
                           <image>
                              <Image url="@../images/reload.png" />
                           </image>
                        </ImageView>
                     </graphic>
                  </Button>
                  <Button mnemonicParsing="false" onAction="#browserHomeButtonAction" >
                     <graphic>
                        <ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
                           <image>
                              <Image url="@../images/home.png" />
                           </image>
                        </ImageView>
                     </graphic>
                  </Button>
                  <HBox>
                     <children>
                        <TextField fx:id="addressBarTF" onAction="#browserGoButtonAction" prefHeight="26.0" prefWidth="492.0" />
                        <ProgressIndicator fx:id="progressPI" maxHeight="24.0" maxWidth="24.0" minHeight="16.0" minWidth="16.0" prefHeight="24.0" prefWidth="24.0" visible="false">
                           <HBox.margin>
                              <Insets left="-24.0" />
                           </HBox.margin>
                        </ProgressIndicator>
                     </children>
                  </HBox>
              </items>
            </ToolBar>
         </top>
         <bottom>
            <HBox BorderPane.alignment="CENTER">
               <children>
                  <Label fx:id="statusL" prefHeight="16.0" prefWidth="662.0" text="Status" />
               </children>
               <BorderPane.margin>
                  <Insets />
               </BorderPane.margin>
            </HBox>
         </bottom>
      </BorderPane>
   </center>
</BorderPane>



BrowserController.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package browser;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebView;
import javax.swing.JOptionPane;

/**
 * FXML Controller class
 *
 * @author rajesh
 */
public class BrowserController implements Initializable {

    @FXML
    BorderPane browserBP;
    @FXML
    WebView browserWV;
    @FXML
    ImageView stopReloadIV;
    @FXML
    TextField addressBarTF;
    @FXML
    ProgressIndicator progressPI;
    @FXML
    Label statusL;
    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {                          
        browserWV.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>(){
            @Override
            public void changed(ObservableValue<? extends Worker.State> observable, Worker.State oldValue, Worker.State newValue) {
                statusL.setText("loading... " + browserWV.getEngine().getLocation());                
                stopReloadIV.setImage(new Image(getClass().getResourceAsStream("/images/stoploading.png")));
                progressPI.setVisible(true);
                if(newValue == Worker.State.SUCCEEDED) {
                    addressBarTF.setText(browserWV.getEngine().getLocation());
                    statusL.setText("loaded");
                    progressPI.setVisible(false);
                    stopReloadIV.setImage(new Image(getClass().getResourceAsStream("/images/reload.png")));
                    if(browserBP.getParent() != null) {
                        TabPane tp = (TabPane)browserBP.getParent().getParent();                           
                        for(Tab tab : tp.getTabs()) {
                            if(tab.getContent() == browserBP) {
                                tab.setText(browserWV.getEngine().getTitle());
                                break;
                            }
                        }                                                
                    }
                }
            }
        });  
        browserWV.getEngine().locationProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> ov, String t, String t1) {
                addressBarTF.setText(t1);
            }
        });
    }    
    
    @FXML
    private void browserBackButtonAction(ActionEvent event) {
        if(browserWV.getEngine().getHistory().getCurrentIndex() <= 0) {
            return;
        }
        browserWV.getEngine().getHistory().go(-1);        
    }
    
    @FXML
    private void browserForwardButtonAction(ActionEvent event) {
        if((browserWV.getEngine().getHistory().getCurrentIndex() + 1) >= browserWV.getEngine().getHistory().getEntries().size()) {
            return;
        }
        browserWV.getEngine().getHistory().go(1);
    }
    
    @FXML
    private void browserGoButtonAction(ActionEvent event) {
        String url = addressBarTF.getText().trim();
        if(url.isEmpty()) {
            JOptionPane.showMessageDialog(null, "No url provided");
            return;
        }
        if(!url.startsWith("http://") && !url.startsWith("https://")) {
         url = "http://"+url;   
        }
        browserWV.getEngine().load(url);
        //browserStopReloadIV.setImage(new Image(getClass().getResourceAsStream("/images/stoploading.png")));
        
    }
    
    @FXML
    private void browserStopReloadButtonAction(ActionEvent event) {                
        if(browserWV.getEngine().getLoadWorker().isRunning()) {
            browserWV.getEngine().getLoadWorker().cancel();
            statusL.setText("loaded");
            progressPI.setVisible(false);            
            stopReloadIV.setImage(new Image(getClass().getResourceAsStream("/images/reload.png")));
        } else {            
            browserWV.getEngine().reload();
            stopReloadIV.setImage(new Image(getClass().getResourceAsStream("/images/stoploading.png")));
        }
        
    }
    
    @FXML
    private void browserHomeButtonAction(ActionEvent event) {
        browserWV.getEngine().loadContent("<html><title>New Tab</title></html>");
        addressBarTF.setText("");        
    }
    
}

Main.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package browser;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;

/**
 *
 * @author rajesh
 */
public class Main extends Application {
    
    TabPane root;
            
    @Override
    public void start(Stage stage) throws IOException {                
        Parent browser = FXMLLoader.load(getClass().getResource("Browser.fxml"));
        Tab browserTab = new Tab("New Tab", browser);
        Tab addTab = new Tab("+", null);
        addTab.setClosable(false);        
        addTab.setOnSelectionChanged(new EventHandler<Event>() {
            @Override
            public void handle(Event event) {
                addNewTab();
            }
        });
        root = new TabPane(browserTab, addTab);
        Scene scene = new Scene(root);
        stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
            @Override
            public void handle(WindowEvent t) {
                Platform.exit();
                System.exit(0);
            }
        });
        stage.setScene(scene);
        stage.setTitle("Browser 2.0");
        stage.show();
                
    }

    final void addNewTab() {
        try {
            Parent browser = FXMLLoader.load(getClass().getResource("Browser.fxml"));
            Tab browserTab = new Tab("New Tab", browser);
            root.getTabs().add(root.getTabs().size() - 1, browserTab);
            root.getSelectionModel().select(browserTab);
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
        launch(args);
    }
    
}

Output/Screen Shot

output-before-allowRestrictedHeaders output-before-locationproperty-listener
Before allowRestrictedHeaders Before LocationProperty Listener
output-after-allowRestrictedHeaders output-after-locationproperty-listener
After allowRestrictedHeaders After LocationProperty Listener

Download NetBeans Project

Please don’t forget to share if you find this helpful

The post Update of Create Browser using JavaFX appeared first on ZatackCoder.

]]>
https://zatackcoder.com/update-of-create-browser-using-javafx/feed/ 0 2658
JavaFX HelloWorld with NetBeans and Gradle https://zatackcoder.com/javafx-helloworld-with-netbeans-and-gradle/ https://zatackcoder.com/javafx-helloworld-with-netbeans-and-gradle/#respond Thu, 30 Apr 2020 09:03:58 +0000 https://zatackcoder.com/?p=2603 Hello Friends, Today we are going to see how to create and run JavaFX HelloWorld with NetBeans and Gradle. Actually I had developed ZatackCrawler a data scrapper tool few years ago when I was learning JavaFX. I had also shared this tool in 2017 that you can check here. But few days ago I had...

The post JavaFX HelloWorld with NetBeans and Gradle appeared first on ZatackCoder.

]]>

Hello Friends, Today we are going to see how to create and run JavaFX HelloWorld with NetBeans and Gradle. Actually I had developed ZatackCrawler a data scrapper tool few years ago when I was learning JavaFX. I had also shared this tool in 2017 that you can check here. But few days ago I had to use this tool but surprisingly I was unable to run this tool. Then I have done some research and found that JavaFX is removed from Java 11 but it is still available till Java 10, so this tool should work till Java 10. Because I was using Java 11 that’s why I was not able to run this tool. Then I thought to migrate this tool to Java 11 but I faced few problems while migration to JavaFX so I thought to share this HelloWorld Example. JavaFX is now maintained by gluon. I have used Gradle build tool in this example because it’s easy to put all the depedencies in single gradle file and it downloads the dependencies automatically. You can also use Maven or just add javafx jars in your libraries.

Now, Let’s Code

build.gradle

plugins {
    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.8'
}

javafx {
    version = "11.0.2"
    modules = [ 'javafx.controls', 'javafx.fxml' ]
}

mainClassName = 'com.zatackcoder.Main'

repositories {
    jcenter()
}

dependencies {
    testImplementation     'junit:junit:4.13'
}

Main.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.zatackcoder;

/**
 *
 * @author rajesh
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        MainApp.main(args);
    }
    
}

MainApp.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.zatackcoder;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;

/**
 *
 * @author rajesh
 */
public class MainApp extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("scene.fxml"));
        
        Scene scene = new Scene(root);
        
        stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
            @Override
            public void handle(WindowEvent t) {
                Platform.exit();
                System.exit(0);
            }
        });
        stage.setScene(scene);
        stage.setTitle("Hello JavaFX");
        stage.show();
    }
    
    public static void main(String[] args) {
        launch(args);
    }
    
}



scene.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>


<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.zatackcoder.SceneController">
   <children>
      <Label fx:id="label" layoutX="282.0" layoutY="192.0" text="Label" />
   </children>
</AnchorPane>

SceneController.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.zatackcoder;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;

/**
 * FXML Controller class
 *
 * @author rajesh
 */
public class SceneController implements Initializable {

    @FXML
    private Label label;

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        label.setText("Hello JavaFX 11\nRunning on Java 11");
    }    
    
}

File Structure

javafx-helloworld-file-structure

Output

javafx-helloworld-output-1 javafx-helloworld-output-2
Output using IDE Output from Distributions folder using Terminal

NetBeans Project Download

 

Thanks friends
Your queries & suggestions are welcome in comments section
Please don’t forget to share if you find this helpful

The post JavaFX HelloWorld with NetBeans and Gradle appeared first on ZatackCoder.

]]>
https://zatackcoder.com/javafx-helloworld-with-netbeans-and-gradle/feed/ 0 2603