1

ここのどこかにバグがあります。何らかの理由で、メッセージをサーバーに送信すると、すべてのメッセージが 1 回のキーストロークで 2 回受信されます。たとえば、「a」と入力すると、サーバーは「INSERT 0 1 a」「INSERT 0 1 a」を受け取ります。なぜ2回起こるのかわかりませんか?

package client;

import javax.swing.*;

import java.io.BufferedReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.*;

import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

public class JTextAreaListen extends JFrame implements KeyListener,
        CaretListener {

    private static final long serialVersionUID = 6950001634065526391L;

    private JTextArea textArea;

    protected final PrintWriter out;
    protected final int id;

    protected final BufferedReader in;
    protected static int caretPos;
    private static int cMark;
    protected static boolean text_selected;

    /*
     * Connecting to server. (1337 is the port we are going to use).
     * 
     * socket = new Socket(InetAddress.getByName("127.0.0.1"), 1337);
     * 
     * (Open a new outStream, you can save this instead of opening on every time
     * you want to send a message. If the connection is lost your should to
     * out.close();
     * 
     * out = new PrintWriter(socket.getOutputStream(), true);
     * 
     * out.print("message"); to send something to the server.
     */

    public JTextAreaListen(PrintWriter out, BufferedReader in, int id) {
        super("JTextAreaListen");
        this.id = id;
        this.out = out;
        this.in = in;

        TextEditor.document.addCaretListener(this);
        TextEditor.document.addKeyListener(this);

    }

    // Listener methods

    public void changedUpdate(DocumentEvent ev) {
    }

    public void removeUpdate(DocumentEvent ev) {

    }

    public void insertUpdate(DocumentEvent ev) {
    }

    @Override
    public void keyPressed(KeyEvent arg0) {
        System.out.print("KeyPressedd");

    }

    @Override
    public void keyReleased(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyTyped(KeyEvent ev) {
        System.out.println(ev.KEY_PRESSED);
        System.out.println("Sth happening!");
        System.out.println(ev.getKeyCode());
        int evID = ev.getID();
        String keyString;
        int keyCode;
        if (evID == KeyEvent.KEY_TYPED) {
            if (ev.getKeyChar() == KeyEvent.CHAR_UNDEFINED) {
                keyCode = ev.getKeyCode();
                if (keyCode == 8) {
                    if (text_selected) {
                        if (caretPos > cMark) {
                            for (int i = caretPos; i >= cMark; i--) {
                                System.out.println("sm1");
                                sendMessage("DELETE" + " " + String.valueOf(id)
                                        + " " + String.valueOf(cMark + 1));
                            }
                        } else if (caretPos < cMark) {
                            for (int i = caretPos; i >= cMark; i++) {
                                System.out.println("sm2");
                                sendMessage("DELETE" + " " + String.valueOf(id)
                                        + " " + String.valueOf(cMark + 1));
                            }
                        }
                    } else {
                        System.out.println("sm3");
                        sendMessage("DELETE" + " " + String.valueOf(id) + " "
                                + String.valueOf(caretPos + 1));
                    }
                }
            } else {
                char c = ev.getKeyChar();
                boolean capital = ev.isShiftDown();
                String charString = String.valueOf(c);
                if (capital) {
                    charString.toUpperCase();
                }
                if (text_selected) {
                    if (caretPos > cMark) {
                        for (int i = caretPos; i >= cMark; i--) {
                            System.out.println("sm4");
                            sendMessage("DELETE" + " " + String.valueOf(id)
                                    + " " + String.valueOf(cMark + 1));
                        }
                        System.out.println("sm5");
                        sendMessage("INSERT" + " " + String.valueOf(id) + " "
                                + String.valueOf(cMark) + " " + charString);
                    } else if (caretPos < cMark) {
                        for (int i = caretPos; i >= cMark; i++) {
                            System.out.println("sm6");
                            sendMessage("DELETE" + " " + String.valueOf(id)
                                    + " " + String.valueOf(caretPos + 1));
                        }
                        System.out.println("sm7");
                        sendMessage("INSERT" + " " + String.valueOf(id) + " "
                                + String.valueOf(caretPos) + " " + charString);
                    }
                } else {
                    System.out.println("sm8");
                    sendMessage("INSERT" + " " + String.valueOf(id) + " "
                            + String.valueOf(caretPos) + " " + charString);
                }
            }

        }

    }

    public void sendMessage(String s) {
        System.out.println("smReal");
        out.println(s);
    }

    @Override
    public void caretUpdate(CaretEvent cev) {
        int dot = cev.getDot();
        int mark = cev.getMark();
        caretPos = dot;
        cMark = mark;
        if (dot == mark) {
            text_selected = false;
        } else if ((dot < mark) | (dot > mark)) {
            text_selected = true;
        }
    }

}

このリスナーを呼び出す TextArea を含むクライアントのコードを次に示します。

package client;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.text.DefaultEditorKit;

public class TextEditor extends JFrame {

    private static final long serialVersionUID = 5991470239888613993L;
    protected static JTextArea document = new JTextArea(20, 120);
    private JFileChooser dialog = new JFileChooser(
            System.getProperty("user.dir"));
    private String currentFile = "Untitled";
    private boolean changed = false;
    private int id;
    private final BufferedReader in;
    private final PrintWriter out;

    public TextEditor(final PrintWriter out, final BufferedReader in, int id) {
        this.out = out;
        this.in = in;
        this.id = id;
        document.setFont(new Font("Monospaced", Font.PLAIN, 12));

        JScrollPane scroll = new JScrollPane(document,
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        this.add(scroll, BorderLayout.CENTER);

        JMenuBar JMB = new JMenuBar();
        this.setJMenuBar(JMB);
        JMenu file = new JMenu("File");
        JMenu edit = new JMenu("Edit");

        JMB.add(file);
        JMB.add(edit);

        file.add(Open);
        file.add(Save);
        file.add(Quit);
        file.add(SaveAs);
        file.addSeparator();
        for (int i = 0; i < 4; i++)
            file.getItem(i).setIcon(null);

        edit.add("Cut");
        edit.add("Copy");
        edit.add("Paste");
        edit.getItem(0).setText("Cut");
        edit.getItem(1).setText("Copy");
        edit.getItem(2).setText("Paste");

        JToolBar tool = new JToolBar();
        this.add(tool, BorderLayout.NORTH);
        tool.add(Open);
        tool.add(Save);
        tool.addSeparator();

        JButton cut = tool.add(Cut), copy = tool.add(Copy), paste = tool
                .add(Paste);
        cut.setText(null);
        cut.setIcon(new ImageIcon("cut.png"));
        copy.setText(null);
        copy.setIcon(new ImageIcon("copy.png"));
        paste.setText(null);
        paste.setIcon(new ImageIcon("paste.png"));

        Save.setEnabled(false);
        SaveAs.setEnabled(false);

        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.pack();
        document.addKeyListener(new JTextAreaListen(out, in, id));

        setTitle(currentFile);
        setVisible(true);
        final int id2 = id;
        Thread t = new Thread(new Runnable() {
            public void run() {
                out.println("GET " + id2);
                while (true) {
                    out.println("GET " + id2);
                    String line = null;
                    do {
                        try {
                            line = in.readLine();
                        } catch (IOException e) {
                            JOptionPane.showMessageDialog(null,
                                    "Connection Lost", "Error",
                                    JOptionPane.ERROR_MESSAGE);
                            System.exit(-1);
                        }
                    } while (line == null);
                    int temp = JTextAreaListen.caretPos;
                    document.setText(line);
                    document.setCaretPosition(temp);
                }
            }
        });
        t.start();
    }

    private KeyListener keyPressed = new KeyAdapter() {

        public void keyPressed(KeyEvent e) {
            changed = true;
            Save.setEnabled(true);
            SaveAs.setEnabled(true);
        }
    };
    Action Open = new AbstractAction("Open", new ImageIcon("open.png")) {
        private static final long serialVersionUID = -474289105133169886L;

        public void actionPerformed(ActionEvent e) {
            saveOld();
            if (dialog.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
                readInFile(dialog.getSelectedFile().getAbsolutePath());
            }
            SaveAs.setEnabled(true);
        }
    };
    Action Save = new AbstractAction("Save", new ImageIcon("save.png")) {
        private static final long serialVersionUID = 2064233284536910855L;

        public void actionPerformed(ActionEvent e) {
            if (!currentFile.equals("Untitled"))
                saveFile(currentFile);
            else
                saveFileAs();
        }
    };
    Action SaveAs = new AbstractAction("Save as...") {
        private static final long serialVersionUID = -5473532525926088880L;

        public void actionPerformed(ActionEvent e) {
            saveFileAs();
        }
    };
    Action Quit = new AbstractAction("Quit") {
        private static final long serialVersionUID = -5339245808869817726L;

        public void actionPerformed(ActionEvent e) {
            saveOld();
            System.exit(0);
        }
    };
    ActionMap m = document.getActionMap();
    Action Cut = m.get(DefaultEditorKit.cutAction);
    Action Copy = m.get(DefaultEditorKit.copyAction);
    Action Paste = m.get(DefaultEditorKit.pasteAction);

    private void saveFileAs() {
        if (dialog.showSaveDialog(null) == JFileChooser.APPROVE_OPTION)
            saveFile(dialog.getSelectedFile().getAbsolutePath());
    }

    private void saveOld() {
        if (changed) {
            if (JOptionPane.showConfirmDialog(this, "Save " + currentFile
                    + " ?", "Save", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
                saveFile(currentFile);
        }
    }

    private void readInFile(String fileName) {
        try {
            FileReader r = new FileReader(fileName);
            document.read(r, null);
            r.close();
            currentFile = fileName;
            setTitle(currentFile);
            changed = false;
        } catch (IOException e) {
            Toolkit.getDefaultToolkit().beep();
            JOptionPane.showMessageDialog(this, "Could not find " + fileName);
        }
    }

    private void saveFile(String fileName) {
        try {
            FileWriter w = new FileWriter(fileName);
            document.write(w);
            w.close();
            currentFile = fileName;
            setTitle(currentFile);
            changed = false;
            Save.setEnabled(false);
        } catch (IOException e) {
            JOptionPane
                    .showMessageDialog(this,
                            "An error has occurred. Your document may not have been saved");
        }
    }
}
4

0 に答える 0