Newer
Older
IoTP / src / main / java / info / istlab / IoTP / Editor.java
@motoki miura motoki miura on 31 May 2023 9 KB 検索機能
package info.istlab.IoTP;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.FontUIResource;

import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rtextarea.RTextScrollPane;

public class Editor extends JFrame implements ActionListener, KeyListener {
    static Editor lastOpened;
    File file;
    RSyntaxTextArea textArea;
    JPanel topP;
    JSlider fontSizeJS;
    JButton saveB;
    JButton runB; // for ShellScript
    JButton compileB;
    JButton execB;
    JButton fixIndentB;
    JTextField searchTF;
    // JTextField comlineOption;
    ScriptRunner runner;

    public Editor(File f) {
        file = f;

        textArea = new RSyntaxTextArea(20, 40);
        // textArea.setSyntaxScheme(new SyntaxScheme(true));
        textArea.setFont(new FontUIResource("sansserif", Font.PLAIN, 16));
        getContentPane().add(new RTextScrollPane(textArea));
        textArea.addKeyListener(this);

        textArea.setAutoIndentEnabled(true);
        textArea.setTabSize(2);
        textArea.setTabsEmulated(true);

        try {
            String d = new String(App.workingDir + File.separator);
            if (d.contains("\\")) {
                d = d.replace("\\", "\\\\");
            }
            setTitle(file.getCanonicalPath().replaceAll(d, ""));
        } catch (IOException e) {
            e.printStackTrace();
        }
        setSize(new Dimension(800, 400));// pack();
        if (Launcher.theapp != null) {
            Point launchP = Launcher.theapp.getLocationOnScreen();
            setLocation(launchP.x + Launcher.theapp.getWidth(), launchP.y);
        }
        // setLocationRelativeTo(Launcher.theapp);
        setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
        load();

        topP = new JPanel();
        topP.setLayout(new FlowLayout(FlowLayout.CENTER, 1, 2));
        topP.add(new JLabel("size:"));
        fontSizeJS = new JSlider(10, 50, 16);
        topP.add(fontSizeJS);
        fontSizeJS.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                int size = fontSizeJS.getValue();
                textArea.setFont(new FontUIResource("sansserif", Font.PLAIN, size));
            }
        });
        saveB = new JButton("Save");
        saveB.addActionListener(this);
        saveB.setEnabled(false);
        saveB.setToolTipText("保存 (CTRL+S)");

        // ファイルの拡張子によって、きりかえる
        if (file.getName().endsWith(".ino")) {
            textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_C);
            textArea.setCodeFoldingEnabled(true);
            topP.add(saveB);
        } else if (file.getName().endsWith(".sh")) {
            textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_UNIX_SHELL);
            topP.add(saveB);
        } else if (file.getName().endsWith(".class")) {
            textArea.setEditable(false);
        } else { // txt fileなど
            topP.add(saveB);
        }

        JButton loadB = new JButton("Reload");
        loadB.addActionListener(this);
        topP.add(loadB);
        loadB.setToolTipText("再読み込み");

        // 実行ボタン
        if (textArea.getSyntaxEditingStyle() == SyntaxConstants.SYNTAX_STYLE_UNIX_SHELL) {
            runB = new JButton("Run");
            runB.addActionListener(this);
            topP.add(runB);
            runner = new ScriptRunner(file.getAbsolutePath(), null);
        } else if (textArea.getSyntaxEditingStyle() == SyntaxConstants.SYNTAX_STYLE_C) {
            // compileB = new JButton("Compile");
            execB = new JButton("Upload");
            execB.setToolTipText("コンパイルと書き込み (CTRL+U)");
            // compileB.addActionListener(this);
            execB.addActionListener(this);
            // topP.add(compileB);
            topP.add(execB);
        }
        fixIndentB = new JButton("インデント調整");
        fixIndentB.setToolTipText("ソースコードの自動フォーマット (CTRL+I or CTRL+T)");

        topP.add(fixIndentB);
        fixIndentB.addActionListener(e -> fixIndent());

        // searchTF = new JTextField(10);
        searchTF = new JTextField("search (CTRL+F)", 11);
        searchTF.setToolTipText("ソースコードの検索(CTRL+F) 入力してEnter Escで終了");

        searchTF.setForeground(Color.GRAY);
        searchTF.addFocusListener(new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {
                if (searchTF.getText().equals("search (CTRL+F)")) {
                    searchTF.setText("");
                    searchTF.setForeground(Color.BLACK);
                }
            }

            @Override
            public void focusLost(FocusEvent e) {
                if (searchTF.getText().isEmpty()) {
                    searchTF.setForeground(Color.GRAY);
                    searchTF.setText("search (CTRL+F)");
                }
            }
        });
        SearchTFKeyListener searchAgent = new SearchTFKeyListener(textArea, searchTF);
        searchTF.addActionListener(searchAgent);
        searchTF.addKeyListener(searchAgent);

        topP.add(searchTF);

        getContentPane().add(topP, BorderLayout.NORTH);

        setVisible(true);
        textArea.requestFocus();
        textArea.setCaretPosition(0);

        lastOpened = this;
    }

    // private void searchTFaction(ActionEvent e) {
    // }

    private void fixIndent() {
        int lineNo = textArea.getCaretPosition();
        String src = textArea.getText();
        // System.out.println(src);
        String out = "";
        try {
            out = IndentProgram.indent(src);
        } catch (IOException e) {
            e.printStackTrace();
        }
        textArea.setText(out);
        textArea.setCaretPosition(lineNo);

        saveB.setEnabled(!src.equals(out)); // ソースが変化していたら保存ボタンをEnable
        // System.out.println(out);

    }

    public static String loadFile(File f) {
        InputStream is = null;
        try {
            is = new FileInputStream(f);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        StringBuilder sb = new StringBuilder();
        String line;
        try {
            while ((line = br.readLine()) != null) {
                sb.append(line + "\n");
            }
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        return sb.toString();

    }

    public void load() {
        textArea.setText(loadFile(file));
    }

    public void save() {
        String src = textArea.getText();
        try {
            PrintWriter out = new PrintWriter(file.getAbsolutePath(), "UTF-8");
            out.println(src);
            out.flush();
        } catch (FileNotFoundException | UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        System.out.println("保存しました");
        saveB.setEnabled(false);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("Save")) {
            save();
        } else if (e.getActionCommand().equals("Reload")) {
            load();
        } else if (e.getActionCommand().equals("Run")) {
            runner.startstop();
            // } else if (e.getActionCommand().equals("Compile")) {
            // new ScriptRunner("Upload.sh", execB, file.getName()).startstop();
        } else if (e.getActionCommand().equals("Upload")) {
            save();
            new ScriptRunner("Upload", file.getName()).startstop();

            // new JExecutor(file.getAbsolutePath(), comlineOption.getText());
        }

    }

    @Override
    public void keyTyped(KeyEvent e) {
        saveB.setEnabled(true);
    }

    @Override
    public void keyPressed(KeyEvent e) {
        // System.out.println(e.getKeyCode());

        if (e.isControlDown() || e.isAltDown() || e.isAltGraphDown() || e.isMetaDown()) {
            if (e.getKeyCode() == 83) { // Save
                save();
            }
            if (e.getKeyCode() == 85) { // Upload
                save();
                new ScriptRunner("Upload", file.getName()).startstop();
            }
            if (e.getKeyCode() == 87) { // W (Close)
                setVisible(false);
            }
            if (e.getKeyCode() == KeyEvent.VK_I || e.getKeyCode() == 84) { // F (format:70) or T(84)
                fixIndent();
            }
            if (e.getKeyCode() == KeyEvent.VK_F){
                searchTF.requestFocus();
            }
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }
}