<commit_before>package net.classicube.launcher.gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

public class PromptScreen extends javax.swing.JDialog {

    public static String show(final String title, final String message, final String placeholder) {
        PromptScreen screen = new PromptScreen(title, message, placeholder);
        screen.setVisible(true);
        return screen.input;
    }

    private String input;

    private PromptScreen(final String title, final String message, final String placeholder) {
        // set title, add border
        super((Frame) null, title, true);

        // set background
        final ImagePanel bgPanel = new ImagePanel(null, true);
        bgPanel.setGradient(true);
        bgPanel.setImage(Resources.getClassiCubeBackground());
        bgPanel.setGradientColor(new Color(124, 104, 141));
        bgPanel.setBorder(new EmptyBorder(8, 8, 8, 8));
        setContentPane(bgPanel);

        initComponents();

        this.tInput.setText(placeholder);
        this.tInput.selectAll();

        // print the message
        if (message.startsWith("<html>")) {
            this.lMessage.setText(message);
        } else {
            this.lMessage.setText("<html><b>" + message);
        }

        // focus & highlight [OK]
        getRootPane().setDefaultButton(bOK);

        // Show GridBagLayout who's boss.
        this.imgErrorIcon.setImage(Resources.getInfoIcon());
        this.imgErrorIcon.setMinimumSize(new Dimension(64, 64));
        this.imgErrorIcon.setPreferredSize(new Dimension(64, 64));
        this.imgErrorIcon.setSize(new Dimension(64, 64));

        // Set windows size, pack, and center
        //this.setPreferredSize(new Dimension(400, 150));
        pack();
        setLocationRelativeTo(null);

        tInput.getDocument().addDocumentListener(new TextChangeListener());
    }

    class TextChangeListener implements DocumentListener {

        @Override
        public void changedUpdate(DocumentEvent e) {
            onTextChange();
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            onTextChange();
        }

        @Override
        public void insertUpdate(DocumentEvent e) {
            onTextChange();
        }
    }

    void onTextChange() {
        this.bOK.setEnabled(!tInput.getText().isEmpty());<commit_msg>Added a contextual Cut/Copy/Paste menu to PromptScreen.<commit_after>package net.classicube.launcher.gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.util.logging.Level;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import net.classicube.launcher.LogUtil;

public class PromptScreen extends javax.swing.JDialog implements ClipboardOwner {

    public static String show(final String title, final String message, final String placeholder) {
        PromptScreen screen = new PromptScreen(title, message, placeholder);
        screen.setVisible(true);
        return screen.input;
    }

    private String input;

    private PromptScreen(final String title, final String message, final String placeholder) {
        // set title, add border
        super((Frame) null, title, true);

        // set background
        final ImagePanel bgPanel = new ImagePanel(null, true);
        bgPanel.setGradient(true);
        bgPanel.setImage(Resources.getClassiCubeBackground());
        bgPanel.setGradientColor(new Color(124, 104, 141));
        bgPanel.setBorder(new EmptyBorder(8, 8, 8, 8));
        setContentPane(bgPanel);

        initComponents();

        this.tInput.setText(placeholder);
        this.tInput.selectAll();

        // print the message
        if (message.startsWith("<html>")) {
            this.lMessage.setText(message);
        } else {
            this.lMessage.setText("<html><b>" + message);
        }

        // focus & highlight [OK]
        getRootPane().setDefaultButton(bOK);

        // Show GridBagLayout who's boss.
        this.imgErrorIcon.setImage(Resources.getInfoIcon());
        this.imgErrorIcon.setMinimumSize(new Dimension(64, 64));
        this.imgErrorIcon.setPreferredSize(new Dimension(64, 64));
        this.imgErrorIcon.setSize(new Dimension(64, 64));

        // Add copy/paste menu to text box
        tInput.addMouseListener(new MessageBoxMouseAdapter());

        // Set windows size, pack, and center
        //this.setPreferredSize(new Dimension(400, 150));
        pack();
        setLocationRelativeTo(null);

        tInput.getDocument().addDocumentListener(new TextChangeListener());
    }

    // Opens the CopyPasteMenu for our text box
    class MessageBoxMouseAdapter extends MouseAdapter {

        @Override
        public void mousePressed(MouseEvent e) {
            if (e.isPopupTrigger()) {
                doPop(e);
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            if (e.isPopupTrigger()) {
                doPop(e);
            }
        }

        private void doPop(MouseEvent e) {
            CopyPasteMenu menu = new CopyPasteMenu();
            menu.show(e.getComponent(), e.getX(), e.getY());
        }
    }

    // Menu that provides [Cut], [Copy], and [Paste] buttons for the text box.
    // Isn't it silly that I have to do this manually in Java?
    class CopyPasteMenu extends JPopupMenu {

        public CopyPasteMenu() {
            JMenuItem cutMenuItem = new JMenuItem("Cut");
            cutMenuItem.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    setClipboardContents(tInput.getSelectedText());
                    int selStart = tInput.getSelectionStart();
                    int selEnd = tInput.getSelectionEnd();
                    String newText = tInput.getText().substring(0, selStart)
                            + tInput.getText().substring(selEnd);
                    tInput.setText(newText);
                    tInput.setSelectionStart(selStart);
                    tInput.setSelectionEnd(tInput.getSelectionStart());
                }
            });
            add(cutMenuItem);
            
            JMenuItem copyMenuItem = new JMenuItem("Copy");
            copyMenuItem.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    setClipboardContents(tInput.getSelectedText());
                }
            });
            add(copyMenuItem);
            
            JMenuItem pasteMenuItem = new JMenuItem("Paste");
            pasteMenuItem.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    int selStart = tInput.getSelectionStart();
                    int selEnd = tInput.getSelectionEnd();
                    String pastedText = getClipboardContents();
                    String newText = tInput.getText().substring(0, selStart)
                            + pastedText
                            + tInput.getText().substring(selEnd);
                    tInput.setText(newText);
                    tInput.setSelectionStart(selStart + pastedText.length());
                    tInput.setSelectionEnd(tInput.getSelectionStart());
                }
            });
            add(pasteMenuItem);
        }
    }

    // Places string to clipboard, and makes PromptScreen the clipboard owner
    public void setClipboardContents(String stringToCopy) {
        StringSelection stringSelection = new StringSelection(stringToCopy);
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        clipboard.setContents(stringSelection, this);
    }

    // Tries to get string from clipboard. Returns empty string if impossible.
    public String getClipboardContents() {
        String result = "";
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        Transferable contents = clipboard.getContents(null);
        boolean hasTransferableText = (contents != null)
                && contents.isDataFlavorSupported(DataFlavor.stringFlavor);
        if (hasTransferableText) {
            try {
                result = (String) contents.getTransferData(DataFlavor.stringFlavor);
            } catch (UnsupportedFlavorException | IOException ex) {
                LogUtil.getLogger().log(Level.WARNING, "Error pasting text from clipboard", ex);
            }
        }
        return result;
    }

    @Override
    public void lostOwnership(Clipboard clipboard, Transferable contents) {
        // Necessary to be a ClipboardOwner
    }

    class TextChangeListener implements DocumentListener {

        @Override
        public void changedUpdate(DocumentEvent e) {
            onTextChange();
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            onTextChange();
        }

        @Override
        public void insertUpdate(DocumentEvent e) {
            onTextChange();
        }
    }

    void onTextChange() {
        this.bOK.setEnabled(!tInput.getText().isEmpty());
{'fraction_non_alphanumeric': 0.09617331443612068, 'fraction_numerical': 0.006479044340959708, 'mean_word_length': 2.3363728470111447, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1694545', 'n_tokens_mistral': 2647, 'n_tokens_neox': 2518, 'n_words': 565}