James Lewis
James Lewis

Reputation: 25

all my methods on button click wait for the thread to complete before actioning

I am new to Java and I am currently trying to build a port scanner for my University course. I have got the majority of it to work although I am having a problem with the UI. I have set my button text to change from "Start Scan" to "Stop Scan" depending on a set of variables. When the "Start Scan" button is pressed it starts the thread that hosts the scanner, however, the button text does not change, to "Stop Scan" until after the thread has finished. I am lost on how to fix this. Any Help would be much appreciated.

This is my Swing class

package com.ui;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.NumberFormat;

import javax.annotation.PostConstruct;
import javax.swing.*;
import javax.xml.bind.ParseConversionEvent;

import com.scanner.PortScanner;


/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
public class MainApp extends javax.swing.JFrame {
    private JTextField txtTargetIP;
    private JLabel lblEndPort;
    private JLabel lblScanning;
    private JList lstMessages;
    private JButton btnScan;
    private JLabel lblPortNumber;
    private JList listListening;
    private JCheckBox chkFullRange;
    private JTextField txtFinalPort;
    private JTextField txtStartPort;
    private JLabel lblStartPort;
    private JLabel lblTarget;
    private DefaultListModel lstMessagesModel;
    private DefaultListModel listListeningModel;
    private PortScanner ps;


    /**
    * Auto-generated main method to display this JFrame
    */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                MainApp inst = new MainApp();
                inst.setLocationRelativeTo(null);
                inst.setVisible(true);
            }
        });
    }

    public MainApp() {
        super();    
        initGUI();
    }

    private void initGUI() {
        try {
            {
                getContentPane().setLayout(null);
                this.setTitle("Port Scanner");
                {
                    txtTargetIP = new JTextField();
                    getContentPane().add(txtTargetIP);
                    txtTargetIP.setText("Enter Target IP Here");
                    txtTargetIP.setBounds(167, 39, 234, 22);
                    //txtTargetIP.setToolTipText("Enter the ip address or Domain name of the target Computer");
                    txtTargetIP.addMouseListener(new MouseAdapter() {
                        public void mousePressed(MouseEvent evt) {
                            txtTargetIPMousePressed(evt);
                        }
                    });
                }
                {
                    lblTarget = new JLabel();
                    getContentPane().add(lblTarget);
                    lblTarget.setText("Target Domain");
                    lblTarget.setBounds(50, 42, 111, 15);

                }
                {
                    lblStartPort = new JLabel();
                    getContentPane().add(lblStartPort);
                    lblStartPort.setText("Start Port");
                    lblStartPort.setBounds(50, 87, 71, 22);
                }
                {
                    txtStartPort = new JTextField();
                    getContentPane().add(txtStartPort);
                    txtStartPort.setText("Start Port");
                    txtStartPort.setBounds(121, 87, 82, 22);
                    txtStartPort.addMouseListener(new MouseAdapter() {
                        public void mousePressed(MouseEvent evt) {
                            txtStartPortMousePressed(evt);
                        }
                    });
                }
                {
                    lblEndPort = new JLabel();
                    getContentPane().add(lblEndPort);
                    lblEndPort.setText("Final Port");
                    lblEndPort.setBounds(246, 87, 73, 22);
                }
                {
                    txtFinalPort = new JFormattedTextField(NumberFormat.INTEGER_FIELD);
                    getContentPane().add(txtFinalPort);
                    txtFinalPort.setText("Final Port");
                    txtFinalPort.setBounds(319, 87, 82, 22);
                    txtFinalPort.addMouseListener(new MouseAdapter() {
                        public void mousePressed(MouseEvent evt) {
                            txtFinalPortMousePressed(evt);
                        }
                    });
                }
                {
                    chkFullRange = new JCheckBox();
                    getContentPane().add(chkFullRange);
                    chkFullRange.setText("Check All Ports");
                    chkFullRange.setBounds(50, 119, 133, 19);
                    chkFullRange.addItemListener(new ItemListener() {
                        public void itemStateChanged(ItemEvent evt) {
                            chkFullRangeItemStateChanged(evt);
                        }
                    });

                }
                {
                    listListeningModel = new DefaultListModel(); 
                    listListening = new JList();
                    getContentPane().add(listListening);
                    listListening.setModel(listListeningModel);
                    listListening.setBounds(248, 204, 153, 133);
                    listListening.setBorder(BorderFactory.createTitledBorder("Listening Ports"));
                    listListening.setEnabled(false);
                }
                {
                    lblScanning = new JLabel();
                    getContentPane().add(lblScanning);
                    lblScanning.setText("Currently Scanning Port: ");
                    lblScanning.setBounds(50, 349, 171, 16);
                }
                {
                    lblPortNumber = new JLabel();
                    getContentPane().add(lblPortNumber);
                    lblPortNumber.setText("Port Number");
                    Font f1 = new Font("italic", Font.ITALIC, 12);
                    lblPortNumber.setFont(f1);
                    lblPortNumber.setBounds(234, 349, 94, 16);
                }
                {
                    btnScan = new JButton();
                    getContentPane().add(btnScan);
                    btnScan.setText("Start Scan");
                    btnScan.setBounds(50, 150, 351, 42);
                    btnScan.addMouseListener(new MouseAdapter() {
                        public void mousePressed(MouseEvent evt) {
                            btnScanMousePressed(evt);
                        }
                    });
                }
                {
                    lstMessagesModel = new DefaultListModel();
                    lstMessages = new JList();
                    getContentPane().add(lstMessages);
                    lstMessages.setModel(lstMessagesModel);
                    lstMessages.setBounds(50, 204, 153, 133);
                    lstMessages.setBorder(BorderFactory.createTitledBorder("Messages"));
                    lstMessages.setEnabled(false);
                }
            }
            this.setSize(448, 411);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void txtTargetIPMousePressed(MouseEvent evt) {
        if (txtTargetIP.getText().equals("Enter Target IP Here") || txtTargetIP.getText().equals("------")){
        txtTargetIP.setText("");
        }
        if (txtStartPort.getText().equals("")){
            txtStartPort.setText("Start Port");
        }
        if(txtFinalPort.getText().equals("")){
            txtFinalPort.setText("Final Port");
        }


    }

    private void txtStartPortMousePressed(MouseEvent evt) {
        if((txtStartPort.getText().equals("Start Port") || txtStartPort.getText().equals("------")) && chkFullRange.isSelected()==false){
            txtStartPort.setText("");   
        }
        if(txtTargetIP.getText().equals("")){
            txtTargetIP.setText("Enter Target IP Here");
        }
        if(txtFinalPort.getText().equals("") && chkFullRange.isSelected()==false){
            txtFinalPort.setText("Final Port");
        }
    }

    private void txtFinalPortMousePressed(MouseEvent evt) {
        if((txtFinalPort.getText().equals("Final Port") || txtFinalPort.getText().equals("------")) && chkFullRange.isSelected()==false){
        txtFinalPort.setText("");
        }
        if(txtTargetIP.getText().equals("")){
            txtTargetIP.setText("Enter Target IP Here");
        }
        if(txtStartPort.getText().equals("") && chkFullRange.isSelected()==false){
            txtStartPort.setText("Start Port");
        }
    }

    //Check All Ports
    private void chkFullRangeItemStateChanged(ItemEvent evt) {

        if(chkFullRange.isSelected()==true){
            txtStartPort.setEnabled(false);
            txtStartPort.setText("0");
            lblStartPort.setForeground(Color.GRAY);

            txtFinalPort.setEnabled(false);
            txtFinalPort.setText("65535");
            lblEndPort.setForeground(Color.GRAY);
            ;
        }
        if (chkFullRange.isSelected()==false){
            txtStartPort.setEnabled(true);
            txtStartPort.setText("Start Port");
            lblStartPort.setForeground(Color.BLACK);
            txtFinalPort.setEnabled(true);
            txtFinalPort.setText("Final Port");
            lblEndPort.setForeground(Color.BLACK);
        }
        if(txtTargetIP.getText().equals("")){
            txtTargetIP.setText("Enter Target IP Here");
        }


    }


    //Start Scan
    private void btnScanMousePressed(MouseEvent evt) {
        lstMessagesModel.clear();

        refresh();

        if (btnScan.getText().equals("Start Scan") && errorCheck()==0){
            listListeningModel.clear();
            btnScan.setText("Stop Scan");
            lstMessagesModel.addElement("Scan Started...");

            int p1 = Integer.parseInt(txtStartPort.getText());
            int p2 = Integer.parseInt(txtFinalPort.getText());
            String target = txtTargetIP.getText();
            ps = new PortScanner(p1, p2, target);

            ps.run();

            listListeningModel.addElement(ps.getListening());       
        }

        else if (btnScan.getText().equals("Stop Scan") || ps.isAlive()==false){
            ps.stopScan();
            btnScan.setText("Start Scan");
            lstMessagesModel.addElement("Scan Stopped");
        }
    }

    //Check input for errors
    public int errorCheck(){
        System.out.println("Running errorCheck");

        int errors=0;

        if (txtTargetIP.getText().equals(null) || txtTargetIP.getText().equals("Enter Target IP Here") || txtTargetIP.getText().equals("------")){
            txtTargetIP.setBackground(Color.RED);
            txtTargetIP.setText("------");
            lstMessagesModel.addElement("No target Specified");
            errors++;
        }else{
            txtTargetIP.setBackground(Color.WHITE);
        }

        if(chkFullRange.isSelected()==false && (txtStartPort.getText().equals(null) || txtStartPort.getText().equals("Start Port") || txtStartPort.getText().equals("------"))){
            txtStartPort.setBackground(Color.RED);
            txtStartPort.setText("------");
            lstMessagesModel.addElement("No Start Port Specified");
            errors++;
        }else{
            txtStartPort.setBackground(Color.WHITE);
        }

        if(chkFullRange.isSelected()==false && (txtFinalPort.getText().equals(null) || txtFinalPort.getText().equals("Final Port") || txtFinalPort.getText().equals("------"))){
            txtFinalPort.setBackground(Color.RED);
            txtFinalPort.setText("------");
            lstMessagesModel.addElement("No Final Port Specified");
            errors++;
        }else{
            txtFinalPort.setBackground(Color.WHITE);
        }
        System.out.println(errors);
        return errors;

    }

    //Refresh Input Areas
    public void refresh(){
        if (txtTargetIP.getText().equals("") || txtTargetIP.getText().equals("------")){
            txtTargetIP.setText("Enter Target IP Here");
        }
        if (txtStartPort.getText().equals("") || txtStartPort.getText().equals("------")){
            txtStartPort.setText("Start Port");
        }
        if (txtFinalPort.getText().equals("") || txtFinalPort.getText().equals("------")){
            txtFinalPort.setText("Final Port");
        }
    }


}

And This is my Scanner Code.

package com.scanner;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadFactory;

public class PortScanner extends Thread implements Runnable{

    private boolean running = true;
    //private int currentPort;
    private List<Integer> listening = new ArrayList<Integer>();
    private int startPort;
    private int finalPort;
    private String targetDomain;

    public PortScanner() {
        // TODO Auto-generated constructor stub
    }

    public PortScanner(int startPort, int finalPort, String targetDomain) {
        super();
        this.startPort = startPort;
        this.finalPort = finalPort;
        this.targetDomain = targetDomain;
    }

    @Override
    public void run() {
        while(running==true){
            for (int currentPort = startPort; currentPort <= finalPort; currentPort++) {
                System.out.println(currentPort + ":" + finalPort);

                try {
                    Socket socket = new Socket();
                    socket.connect(new InetSocketAddress(targetDomain, currentPort),200);
                    listening.add(currentPort);
                    System.out.println("listening: " + listening);
                    socket.close();
                } catch (IOException e) {
                    System.out.println("scanning: " + currentPort);
                }
                if(currentPort!=finalPort+1){
                    running=false;
                }

            }
        }
    }

    //stop Thread
    public void stopScan(){
        running=false;
    }

    /*public int getCurrentPort() {
        return currentPort;
    }

    public void setCurrentPort(int currentPort) {
        this.currentPort = currentPort;
    }*/

    public List<Integer> getListening() {
        return listening;
    }

    public void setListening(List<Integer> listening) {
        this.listening = listening;
    }

    public int getStartPort() {
        return startPort;
    }

    public void setStartPort(int startPort) {
        this.startPort = startPort;
    }

    public int getFinalPort() {
        return finalPort;
    }

    public void setFinalPort(int finalPort) {
        this.finalPort = finalPort;
    }

    public String getTargetDomain() {
        return targetDomain;
    }

    public void setTargetDomain(String targetDomain) {
        this.targetDomain = targetDomain;
    }




}

Sorry if this is an overly excessive amount of code to share, but I am not sure exactly which parts will be relevant to you so I have shared it all.

Any other improvements that you see would also be gratefully received. Thank you in advance for your help.

Kindest Regards

James

Upvotes: 1

Views: 532

Answers (2)

camickr
camickr

Reputation: 324147

You need to execute the long running task in a separate Thread. Read the Swing tutorial on Concurrency for more information. You can use a Swing Worker for the thread and publish results to the GUI when you want to update the labels or any other GUI component.

Upvotes: 2

sanbhat
sanbhat

Reputation: 17622

You should invoke ps.start() to make ps run as a separate thread;

Looks like you have invoked ps.run(), which does not start a separate thread, but runs the code in a sequential manner

Upvotes: 2

Related Questions