// Your imports here import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.IOException; import java.util.*; import java.util.List; import java.util.Timer; public class Pingtool { private JFrame frame; private JPanel mainPanel; private JPanel scanPanel; private JButton addButton; private JButton removeButton; private List scanTypes = new ArrayList<>(); private Map scanComponents = new HashMap<>(); private Map scanStatusPanels = new HashMap<>(); private Map scanLabels = new HashMap<>(); private Map customNames = new HashMap<>(); private Timer timer; public Pingtool() { initializeUI(); startMonitoring(); } private void initializeUI() { frame = new JFrame("Ping Tool"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(600, 400); mainPanel = new JPanel(new BorderLayout()); scanPanel = new JPanel(); scanPanel.setLayout(new BoxLayout(scanPanel, BoxLayout.Y_AXIS)); JScrollPane scrollPane = new JScrollPane(scanPanel); mainPanel.add(scrollPane, BorderLayout.CENTER); JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); addButton = new JButton("Add Scan"); removeButton = new JButton("Remove Scan"); buttonPanel.add(addButton); buttonPanel.add(removeButton); mainPanel.add(buttonPanel, BorderLayout.SOUTH); addButton.addActionListener(e -> showAddOrEditScanDialog(null)); removeButton.addActionListener(e -> showRemoveScanDialog()); frame.setContentPane(mainPanel); frame.setVisible(true); } private void showAddOrEditScanDialog(ScanType scanToEdit) { boolean isEdit = scanToEdit != null; JDialog dialog = new JDialog(frame, isEdit ? "Edit Scan" : "Add New Scan", true); dialog.setLayout(new BorderLayout()); JPanel inputPanel = new JPanel(new GridLayout(4, 2)); JComboBox typeComboBox = new JComboBox<>(new String[]{ "HTTP GET", "HTTP HEAD", "Ping", "Port Connect" }); JTextField accessStringField = new JTextField(); JTextField customNameField = new JTextField(); if (isEdit) { typeComboBox.setSelectedItem(ScanMaker.getDisplayLabel(scanToEdit.getClass().getSimpleName())); accessStringField.setText(scanToEdit.getAccessString()); customNameField.setText(customNames.getOrDefault(scanToEdit, "").trim()); } inputPanel.add(new JLabel("Scan Type:")); inputPanel.add(typeComboBox); inputPanel.add(new JLabel("Access String:")); inputPanel.add(accessStringField); inputPanel.add(new JLabel("Custom Name (Optional):")); inputPanel.add(customNameField); JButton okButton = new JButton("OK"); okButton.addActionListener(e -> { String label = (String) typeComboBox.getSelectedItem(); String accessString = accessStringField.getText().trim(); final String[] customName = {customNameField.getText().trim()}; ScanMaker.validateAndCreate(label, accessString).ifPresentOrElse(newScan -> { if (customName[0].isEmpty()) { customName[0] = newScan.getClass().getSimpleName() + ": " + accessString; } if (isEdit) removeScanType(scanToEdit); addScanType(newScan, customName[0]); dialog.dispose(); }, () -> JOptionPane.showMessageDialog(dialog, "Invalid access string for selected scan type.", "Validation Error", JOptionPane.ERROR_MESSAGE)); }); JButton cancelButton = new JButton("Cancel"); cancelButton.addActionListener(e -> dialog.dispose()); JPanel buttonPanel = new JPanel(); buttonPanel.add(okButton); buttonPanel.add(cancelButton); dialog.add(inputPanel, BorderLayout.CENTER); dialog.add(buttonPanel, BorderLayout.SOUTH); dialog.pack(); dialog.setLocationRelativeTo(frame); dialog.setVisible(true); } private void showRemoveScanDialog() { if (scanTypes.isEmpty()) { JOptionPane.showMessageDialog(frame, "No scans to remove.", "Information", JOptionPane.INFORMATION_MESSAGE); return; } String[] descriptions = scanTypes.stream() .map(scan -> customNames.getOrDefault(scan, scan.getClass().getSimpleName() + ": " + scan.getAccessString())) .toArray(String[]::new); String selected = (String) JOptionPane.showInputDialog(frame, "Select scan to remove:", "Remove Scan", JOptionPane.QUESTION_MESSAGE, null, descriptions, descriptions[0]); if (selected != null) { scanTypes.stream().filter(scan -> selected.equals(customNames.getOrDefault(scan, scan.getClass().getSimpleName() + ": " + scan.getAccessString()))) .findFirst() .ifPresent(this::removeScanType); } } private void addScanType(ScanType scanType, String displayName) { scanTypes.add(scanType); customNames.put(scanType, displayName); JPanel scanComponent = new JPanel(new BorderLayout()); scanComponent.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1), BorderFactory.createEmptyBorder(2, 4, 2, 4))); scanComponent.setMaximumSize(new Dimension(Integer.MAX_VALUE, 30)); JLabel nameLabel = new JLabel(displayName); nameLabel.setFont(new Font("SansSerif", Font.PLAIN, 12)); nameLabel.setBorder(BorderFactory.createEmptyBorder(2, 4, 2, 4)); JPanel statusPanel = new JPanel(); statusPanel.setPreferredSize(new Dimension(14, 14)); statusPanel.setBackground(Color.GRAY); statusPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK)); scanComponent.add(nameLabel, BorderLayout.CENTER); scanComponent.add(statusPanel, BorderLayout.EAST); scanComponent.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { showAddOrEditScanDialog(scanType); } }); scanComponents.put(scanType, scanComponent); scanStatusPanels.put(scanType, statusPanel); scanLabels.put(scanType, nameLabel); scanPanel.add(scanComponent); scanPanel.revalidate(); scanPanel.repaint(); saveScansToStorage(); } private void removeScanType(ScanType scanType) { JPanel component = scanComponents.get(scanType); if (component != null) { scanPanel.remove(component); scanComponents.remove(scanType); scanStatusPanels.remove(scanType); scanLabels.remove(scanType); customNames.remove(scanType); scanTypes.remove(scanType); scanPanel.revalidate(); scanPanel.repaint(); } saveScansToStorage(); } private void startMonitoring() { try { List stored = Storage.loadScans(); for (Storage.StoredScan s : stored) { ScanMaker.createScan(s.type, s.accessString).ifPresent(scan -> { String name = s.customName.isEmpty() ? scan.getClass().getSimpleName() + ": " + s.accessString : s.customName; addScanType(scan, name); }); } } catch (Exception e) { e.printStackTrace(); } timer = new Timer(); timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { updateScanStatuses(); } }, 0, 1000); } private void updateScanStatuses() { List currentScans; synchronized (scanTypes) { currentScans = new ArrayList<>(scanTypes); } for (ScanType scanType : currentScans) { JPanel statusPanel = scanStatusPanels.get(scanType); if (statusPanel != null) { try { boolean result = scanType.execute(); SwingUtilities.invokeLater(() -> statusPanel.setBackground(result ? Color.GREEN : Color.RED)); } catch (Exception e) { SwingUtilities.invokeLater(() -> statusPanel.setBackground(Color.RED)); } } } } private void saveScansToStorage() { List stored = new ArrayList<>(); for (ScanType scan : scanTypes) { String type = ScanMaker.getTypeName(scan); String accessString = scan.getAccessString(); String customName = customNames.getOrDefault(scan, ""); stored.add(new Storage.StoredScan(type, accessString, customName)); } try { Storage.saveScans(stored); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { SwingUtilities.invokeLater(Pingtool::new); } }