Skip to content
Snippets Groups Projects
Forked from an inaccessible project.
ChatWindow.java 15.01 KiB
package chat;

import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

import org.alicebot.ab.AIMLProcessor;
import org.alicebot.ab.Bot;
import org.alicebot.ab.Chat;
import org.alicebot.ab.Graphmaster;
import org.alicebot.ab.MagicBooleans;
import org.alicebot.ab.MagicStrings;
import org.alicebot.ab.PCAIMLProcessorExtension;

import com.google.code.chatterbotapi.ChatterBot;
import com.google.code.chatterbotapi.ChatterBotFactory;
import com.google.code.chatterbotapi.ChatterBotSession;
import com.google.code.chatterbotapi.ChatterBotType;

import cse332.misc.WordReader;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebView;
import p2.wordcorrector.SpellingCorrector;
import p2.wordsuggestor.WordSuggestor;

public class ChatWindow {
    private JFrame frame;
    private JTextField myMessage;
    private WebView chatMessages;
    private JFXPanel chatMessagesPanel;
    private JButton[] suggestions;
    private final StringBuilder content;
    public String theirUsername;
    public Chat esession;
    public ChatterBotSession csession;
    private final WordSuggestor[] markov;
    private final UMessageServerConnection connection;
    private final SpellingCorrector checker;
    public String undo;

    /**
     * Create the application.
     */
    public ChatWindow(String username, WordSuggestor[] markov,
            UMessageServerConnection connection) {
        this.theirUsername = username;
        this.markov = markov;
        this.connection = connection;
        this.checker = new SpellingCorrector();

        this.content = new StringBuilder();
        initialize();
        refreshSuggestions();
        this.frame.setTitle("Chat: " + username);
        this.frame.setVisible(true);

        if (this.theirUsername.equals("eliza")) {
            MagicStrings.setRootPath();
            AIMLProcessor.extension = new PCAIMLProcessorExtension();
            MagicBooleans.jp_tokenize = false;
            MagicBooleans.trace_mode = false;
            Graphmaster.enableShortCuts = true;
            Bot bot = new Bot("alice2", MagicStrings.root_path, "chat"); //

            this.esession = new Chat(bot);
        }
        else if (this.theirUsername.equals("cleverbot")) {
            ChatterBotFactory factory = new ChatterBotFactory();
            ChatterBot bot1;
            try {
                bot1 = factory.create(ChatterBotType.CLEVERBOT);
                this.csession = bot1.createSession();
            } catch (Exception e) {
            }
        }
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() { 
        this.frame = new JFrame();
        this.frame.setBounds(100, 100, 290, 390);
        this.frame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
        GridBagLayout gridBagLayout = new GridBagLayout();
        gridBagLayout.columnWidths = new int[] { 446, 0 };
        gridBagLayout.rowHeights = new int[] { 200, 20, 0, 20, 0, 0 };
        gridBagLayout.columnWeights = new double[] { 1.0, Double.MIN_VALUE };
        gridBagLayout.rowWeights = new double[] { 1.0, 0.0, 0.0, 0.0, 0.0,
                Double.MIN_VALUE };
        this.frame.getContentPane().setLayout(gridBagLayout);

        GridBagConstraints gbc_msgScrollPane = new GridBagConstraints();
        gbc_msgScrollPane.weighty = 5.0;
        gbc_msgScrollPane.weightx = 5.0;
        gbc_msgScrollPane.fill = GridBagConstraints.BOTH;
        gbc_msgScrollPane.insets = new Insets(0, 0, 5, 0);
        gbc_msgScrollPane.gridx = 0;
        gbc_msgScrollPane.gridy = 0;

        show();

        (new Thread() {
            public void run() {
                try {
                    String path = new java.io.File(".").getCanonicalPath();
                    content.append("<link rel='stylesheet' type='text/css' href='file:///"
                            + path + "/chat.css'>");
                    content.append("<head>");
                    content.append(
                            "   <script language=\"javascript\" type=\"text/javascript\">");
                    content.append("       function toBottom(){");
                    content
                            .append("           window.scrollTo(0, document.body.scrollHeight);");
                    content.append("       }");
                    content.append("   </script>");
                    content.append("</head>");
                    content.append("<body onload='toBottom()'>");
                } catch (IOException e1) {
                }
            }
        }).start();

        JPanel suggestionsPanel = new JPanel();
        GridBagConstraints gbc_suggestionsPanel = new GridBagConstraints();
        gbc_suggestionsPanel.insets = new Insets(0, 0, 5, 0);
        gbc_suggestionsPanel.fill = GridBagConstraints.BOTH;
        gbc_suggestionsPanel.gridx = 0;
        gbc_suggestionsPanel.gridy = 1;
        this.frame.getContentPane().add(suggestionsPanel, gbc_suggestionsPanel);
        FlowLayout fl_suggestionsPanel = new FlowLayout(FlowLayout.CENTER, 5, 0);
        suggestionsPanel.setLayout(fl_suggestionsPanel);

        JPanel myMessagePanel = new JPanel();
        GridBagConstraints gbc_myMessagePanel = new GridBagConstraints();
        gbc_myMessagePanel.insets = new Insets(0, 0, 5, 0);
        gbc_myMessagePanel.fill = GridBagConstraints.BOTH;
        gbc_myMessagePanel.gridx = 0;
        gbc_myMessagePanel.gridy = 3;
        this.frame.getContentPane().add(myMessagePanel, gbc_myMessagePanel);
        myMessagePanel.setLayout(new BoxLayout(myMessagePanel, BoxLayout.X_AXIS));

        Component leftSpacer = Box.createHorizontalStrut(5);
        myMessagePanel.add(leftSpacer);

        this.myMessage = new HintTextField("Send a message");
        this.myMessage.addActionListener(e -> {
            String msg = ChatWindow.this.myMessage.getText();
            if (msg.isEmpty()) {
                return;
            }
            ChatWindow.this.myMessage.setText("");
            updateChat(msg, true);
            sendMessage(msg);
        });

        this.myMessage.addKeyListener(new KeyListener() {
            @Override
            public void keyReleased(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_SPACE) {
                    ChatWindow.this.undo = null;
                    autocorrect();
                    refreshSuggestions();
                }
                else if (((e.getKeyCode() == KeyEvent.VK_BACK_SPACE)
                        || (e.getKeyCode() == KeyEvent.VK_DELETE))
                        && ChatWindow.this.undo != null) {
                    ChatWindow.this.myMessage.setText(ChatWindow.this.undo);
                    ChatWindow.this.undo = null;
                }
                else if (e.getKeyCode() >= KeyEvent.VK_A
                        && e.getKeyCode() <= KeyEvent.VK_Z) {
                    if (!autocomplete()) {
                        ChatWindow.this.undo = null;
                    }
                }
                else {
                    ChatWindow.this.undo = null;
                }
            }

            @Override
            public void keyPressed(KeyEvent e) {
            }

            @Override
            public void keyTyped(KeyEvent e) {
            }
        });

        this.myMessage.setAlignmentX(Component.RIGHT_ALIGNMENT);
        this.myMessage.setColumns(1);
        this.myMessage.setBorder(new RoundedCornerBorder());
        myMessagePanel.add(this.myMessage);

        Component rightSpacer = Box.createHorizontalStrut(5);
        myMessagePanel.add(rightSpacer);

        this.suggestions = new JButton[4];
        for (int i = 0; i < this.suggestions.length; i++) {
            this.suggestions[i] = new JButton("SUG " + i);
            suggestionsPanel.add(this.suggestions[i]);
            this.suggestions[i].addActionListener(e -> {
                JButton suggestion = (JButton) e.getSource();
                String text = (ChatWindow.this.myMessage.getText().trim() + " "
                        + suggestion.getText()).trim() + " ";
                ChatWindow.this.myMessage.setText(text);
                refreshSuggestions();
                ChatWindow.this.myMessage.grabFocus();
            });
            this.myMessage.addFocusListener(new FocusListener() {
                @Override
                public void focusGained(FocusEvent fe) {
                    ChatWindow.this.myMessage.setCaretPosition(
                            ChatWindow.this.myMessage.getDocument().getLength());
                }

                @Override
                public void focusLost(FocusEvent fe) {
                }
            });
        }

        KeyListener giveFocus = new KeyListener() {
            @Override
            public void keyTyped(KeyEvent e) {
                ChatWindow.this.myMessage.dispatchEvent(e);
            }

            @Override
            public void keyPressed(KeyEvent e) {
                if (!e.isControlDown() && !e.isMetaDown()) {
                    ChatWindow.this.myMessage.grabFocus();
                    ChatWindow.this.myMessage.dispatchEvent(e);
                }
            }

            @Override
            public void keyReleased(KeyEvent e) {
                ChatWindow.this.myMessage.dispatchEvent(e);
            }
        };
        this.frame.addKeyListener(giveFocus);
        suggestionsPanel.addKeyListener(giveFocus);
        myMessagePanel.addKeyListener(giveFocus);

        (new Thread() {
            public void run() {
                chatMessagesPanel = new JFXPanel();
                chatMessagesPanel.addKeyListener(giveFocus);
                frame.getContentPane().add(chatMessagesPanel, gbc_msgScrollPane);
                Platform.runLater(() -> {
                    ChatWindow.this.chatMessages = new WebView();

                    BorderPane borderPane = new BorderPane();
                    borderPane.setCenter(ChatWindow.this.chatMessages);
                    Scene scene = new Scene(borderPane, 450, 450);
                    ChatWindow.this.chatMessagesPanel.setScene(scene);
                });

            }
        }).start();


        this.frame.pack();
        show();
        this.myMessage.requestFocusInWindow();
    }

    public void show() {
        this.frame.setVisible(true);
    }

    public void refreshSuggestions() {
        List<String> suggs = new ArrayList<String>();

        String text = ("SOL " + this.myMessage.getText()).trim();

        for (int markovIdx = 0; markovIdx < this.markov.length; markovIdx++) {
            String[] newSuggestions = this.markov[markovIdx].getSuggestions(text);
            System.out.println("Trying: " + Arrays.toString(newSuggestions));
        }

        for (int markovIdx = text.equals("SOL") ? this.markov.length - 1
                : 0; markovIdx < this.markov.length; markovIdx++) {
            String[] newSuggestions = this.markov[markovIdx].getSuggestions(text);

            for (String sugg : newSuggestions) {
                if (suggs.size() < this.suggestions.length && sugg != null
                        && !sugg.equals("SOL") && !suggs.contains(sugg)) {
                    suggs.add(sugg);
                }
            }
        }

        for (int i = 0; i < suggs.size(); i++) {
            this.suggestions[i].setVisible(true);
            this.suggestions[i].setText(suggs.get(i));
        }

        for (int i = suggs.size(); i < this.suggestions.length; i++) {
            this.suggestions[i].setVisible(false);
        }

    }

    public boolean autocomplete() {
        String[] words = this.myMessage.getText().split(" ");
        String result = this.checker.getSingleOption(words[words.length - 1]);

        if (result != null) {
            String text = ("SOL " + this.myMessage.getText()).trim();
            int lastSpace = text.lastIndexOf(' ');
            String allButLast = lastSpace > -1 ? text.substring(0, lastSpace) : null;
            if (allButLast != null) {
                this.undo = this.myMessage.getText();
                String newText = (allButLast.replaceAll("SOL", "") + " " + result).trim();
                if (this.myMessage.getText().startsWith(newText)) {
                    return false;
                }
                this.myMessage.setText(newText);
                return true;
            }
        }
        return false;
    }

    public boolean autocorrect() {
        List<String> words = new ArrayList<String>();
        @SuppressWarnings("resource")
        WordReader reader = new WordReader(this.myMessage.getText());
        words.add("SOL");
        while (reader.hasNext()) {
            words.add(reader.next());
        }

        if (words.isEmpty()) {
            return false;
        }

        String last = words.get(words.size() - 1);

        if (this.checker.check(last)) {
            return false;
        }

        String text = ("SOL " + this.myMessage.getText()).trim();
        int lastSpace = text.lastIndexOf(' ');
        String allButLast = lastSpace > -1 ? text.substring(0, lastSpace) : null;

        String best = this.checker.getMostLikely(this.markov, allButLast, last);

        if (best == null || best.equals("SOL")) {
            return false;
        }
        else {
            this.undo = this.myMessage.getText().trim();
            this.myMessage.setText(
                    (allButLast.replaceAll("SOL", "") + " " + best).trim() + " ");
            return true;
        }
    }

    public void sendMessage(String msg) {
        if (this.theirUsername.equals("eliza")) {
            receiveMessage(this.esession.multisentenceRespond(msg));
            return;
        }
        else if (this.theirUsername.equals("cleverbot")) {
            try {
                receiveMessage(this.csession.think(msg));
                return;
            } catch (Exception e) {
            }
        }
        else {
            try {
                this.connection.m_channel(this.theirUsername, msg);
            } catch (IOException e) {
            }
        }
    }

    public void receiveMessage(String msg) {
        updateChat(msg, false);
    }

    public void updateChat(String msg, boolean me) {
        String meStr = me ? "me" : "them";
        String newCol = "<td><div class=\"from-" + meStr + "\">" + msg + "</div></td>";
        if (!me) {
            newCol = newCol + "<td></td>";
        }
        else {
            newCol = "<td></td>" + newCol;
        }

        this.content.append(
                "<table width=\"100%\">" + "<tr>" + newCol + "</tr>" + "</table>");
        Platform.runLater(() -> ChatWindow.this.chatMessages.getEngine()
                .loadContent(ChatWindow.this.content.toString()));
    }
}