/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package principal.cli; import controlador.Diagrama; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Stroke; import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.ArrayList; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.InputMap; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JPanel; import javax.swing.JViewport; import javax.swing.KeyStroke; import util.DesenhadorDeTexto; /** * * @author ccandido */ public class MasterCli extends JPanel implements KeyListener { public MasterCli() { super(); processador = new CliDiagramaProcessador(this); setBackground(Color.white); setFocusTraversalKeysEnabled(false); setDoubleBuffered(true); setFocusable(true); addKeyListener(this); // <editor-fold defaultstate="collapsed" desc="Teclas"> KeyStroke key_crtl = KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL, InputEvent.CTRL_DOWN_MASK); KeyStroke key_crtl_up = KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL, 0, true); KeyStroke key_shift = KeyStroke.getKeyStroke(KeyEvent.VK_SHIFT, InputEvent.SHIFT_DOWN_MASK); KeyStroke key_shift_up = KeyStroke.getKeyStroke(KeyEvent.VK_SHIFT, 0, true); KeyStroke key_alt = KeyStroke.getKeyStroke(KeyEvent.VK_ALT, InputEvent.ALT_DOWN_MASK); KeyStroke key_alt_up = KeyStroke.getKeyStroke(KeyEvent.VK_ALT, 0, true); KeyStroke key_tab = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0, true); final String ac_crtl = "AC_CRTL"; final String ac_crtl_up = "AC_CRTL_UP"; final String ac_shift = "AC_SHIFT"; final String ac_shift_up = "AC_SHIFT_UP"; final String ac_alt = "AC_ALT"; final String ac_alt_up = "AC_ALT_UP"; final String ac_tab = "TAB"; InputMap inputMap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); inputMap.put(key_crtl, ac_crtl); inputMap.put(key_crtl_up, ac_crtl_up); inputMap.put(key_shift, ac_shift); inputMap.put(key_shift_up, ac_shift_up); inputMap.put(key_alt, ac_alt); inputMap.put(key_alt_up, ac_alt_up); inputMap.put(key_tab, ac_tab); Action al_crtl = new AbstractAction() { @Override public void actionPerformed(ActionEvent actionEvent) { controlDown = true; } }; Action al_crtl_up = new AbstractAction() { @Override public void actionPerformed(ActionEvent actionEvent) { controlDown = false; } }; Action al_shift = new AbstractAction() { @Override public void actionPerformed(ActionEvent actionEvent) { shiftDown = true; } }; Action al_shift_up = new AbstractAction() { @Override public void actionPerformed(ActionEvent actionEvent) { shiftDown = false; } }; Action al_alt = new AbstractAction() { @Override public void actionPerformed(ActionEvent actionEvent) { altDown = true; } }; Action al_alt_up = new AbstractAction() { @Override public void actionPerformed(ActionEvent actionEvent) { if (!altDown) { /////bug do java ao ler o key AltGr do teclado em Windows - swing controlDown = false; } altDown = false; } }; Action al_tab = new AbstractAction() { @Override public void actionPerformed(ActionEvent actionEvent) { AutoComplete(); } }; // Action actionListener = new AbstractAction() { // @Override // public void actionPerformed(ActionEvent actionEvent) { // System.out.println(actionEvent.toString()); // if (isFocusOwner()) return; //ação ocorrerá pelo keylistener. // setControlDown(actionEvent.getModifiers() == ActionEvent.CTRL_MASK); // setShiftDown(actionEvent.getModifiers() == ActionEvent.SHIFT_MASK); // setAltDown(actionEvent.getModifiers() == ActionEvent.ALT_MASK); // } // }; ActionMap actionMap = getActionMap(); actionMap.put(ac_crtl, al_crtl); actionMap.put(ac_crtl_up, al_crtl_up); actionMap.put(ac_shift, al_shift); actionMap.put(ac_shift_up, al_shift_up); actionMap.put(ac_alt, al_alt); actionMap.put(ac_alt_up, al_alt_up); actionMap.put(ac_tab, al_tab); setActionMap(actionMap); // </editor-fold> } //<editor-fold defaultstate="collapsed" desc="Teclas e campos"> @Override public void keyTyped(KeyEvent e) { key = e.getKeyChar(); if (key == (char) 127 || key == '\b' || key == '\n') { e.consume(); return; } if (e.getModifiers() == KeyEvent.CTRL_MASK) { return; } palavra = insertChar(palavra, key); posCursor++; } @Override public void keyPressed(KeyEvent e) { if (isControlDown()) { if (processeAtalhos(e.getKeyCode())) { e.consume(); } } else { switch (e.getKeyCode()) { case KeyEvent.VK_ENTER: doEnter(palavra); e.consume(); break; case KeyEvent.VK_UP: posicioneHistorico(+1); e.consume(); break; case KeyEvent.VK_DOWN: posicioneHistorico(-1); e.consume(); break; case KeyEvent.VK_LEFT: movimenteCursor(-1); e.consume(); break; case KeyEvent.VK_RIGHT: movimenteCursor(+1); e.consume(); break; // case KeyEvent.VK_TAB: // break; case KeyEvent.VK_DELETE: apagarLetra(posCursor); e.consume(); break; case KeyEvent.VK_BACK_SPACE: apagarLetra(posCursor - 1); e.consume(); break; } } repaint(); } @Override public void keyReleased(KeyEvent e) { } // </editor-fold> private char key = '.'; private String prompt = "# "; private final int espaco = 5; private int posCursor = 0; private StringBuilder strs = new StringBuilder(); private Rectangle cliRect = getBounds(); private String palavra = prompt; private final DesenhadorDeTexto dzExecutado = new DesenhadorDeTexto(); private final DesenhadorDeTexto dzCli = new DesenhadorDeTexto(); private int alturaTexto = 0; private ArrayList<String> historico = new ArrayList<>(); public ArrayList<String> getHistorico() { return historico; } public void setHistorico(ArrayList<String> historico) { this.historico = historico; } public String getPrompt() { return prompt; } public void setPrompt(String prompt) { this.prompt = prompt; } //<editor-fold defaultstate="collapsed" desc="Status teclas"> private boolean shiftDown = false; private boolean altDown = false; private boolean controlDown = false; public boolean isShiftDown() { return shiftDown; } public void setShiftDown(boolean shiftDown) { this.shiftDown = shiftDown; } public boolean isAltDown() { return altDown; } public boolean isControlDown() { return controlDown; } public void setControlDown(boolean controlDown) { this.controlDown = controlDown; } // </editor-fold> @Override public void paint(Graphics g) { super.paint(g); Graphics2D g2d = (Graphics2D) g; RenderingHints renderHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); renderHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2d.addRenderingHints(renderHints); g2d.setPaint(Color.BLACK); Stroke stroke = new BasicStroke(2.f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER); g2d.setStroke(stroke); PintarTextos(g2d); } public void Clear() { strs = new StringBuilder(); strs.append(prompt); repaint(); } private void PintarTextos(Graphics2D g) { if (strs.length() > 0) { dzExecutado.PinteTexto(g, Color.BLUE, new Rectangle(espaco, espaco, getWidth() - espaco * 2, getHeight() - espaco), strs.toString()); } int alturaOld = dzExecutado.getMaxHeigth() + 2 * espaco; String txt = insertChar(palavra, '|'); cliRect = new Rectangle(espaco, alturaOld, getWidth() - espaco * 2, getHeight()); dzCli.PinteTexto(g, Color.yellow, cliRect, txt); //apenas para calcular a altura. int recuo = g.getFontMetrics().getDescent(); int alturaCli = dzCli.getMaxHeigth() + 2 * recuo + espaco; cliRect = new Rectangle(espaco, alturaOld, getWidth() - espaco * 2, alturaCli); g.fillRect(cliRect.x, cliRect.y, cliRect.width, cliRect.height); int pos = alturaCli + alturaOld; alturaTexto = pos; dzCli.PinteTexto(g, Color.black, new Rectangle(cliRect.x, cliRect.y + recuo, cliRect.width, cliRect.height - 2 * recuo), txt); AtualizaTamanho(); } private String insertChar(String apalavra, char c) { int tmpTxtPos = posCursor + getPrompt().length(); apalavra = apalavra.substring(0, tmpTxtPos) + c + (apalavra.length() > tmpTxtPos ? apalavra.substring(tmpTxtPos, apalavra.length()) : ""); //prompt return apalavra; } private String insertTexto(String texto, String ainserir) { int tmpTxtPos = posCursor + getPrompt().length(); texto = texto.substring(0, tmpTxtPos) + ainserir + (texto.length() > tmpTxtPos ? texto.substring(tmpTxtPos, texto.length()) : ""); //prompt return texto; } public void AtualizaTamanho() { int pos = alturaTexto; if (pos > getHeight()) { JViewport jvp = ((JViewport) getParent()); setSize(jvp.getExtentSize().width, pos + 2); setPreferredSize(getSize()); if (alturaTexto > jvp.getHeight()) { jvp.setViewPosition(new Point(espaco, getHeight())); } repaint(); } } public boolean doEnter(String apalavra) { appendHistorico(apalavra); strs.append(apalavra).append("\n"); String ret = getProcessador().processeComando(apalavra.substring(getPrompt().length())); if (!ret.isEmpty() && !ret.equals(getProcessador().msgNOTHING)) { strs.append(ret).append("\n"); } if (getProcessador().isJustNewLine()) { palavra = getPrompt(); posCursor = 0; cliRect = getBounds(); } repaint(); return getProcessador().isLastCmdErro(); } private CliDiagramaProcessador processador = new CliDiagramaProcessador(this); public CliDiagramaProcessador getProcessador() { return processador; } public void setProcessador(CliDiagramaProcessador processador) { this.processador = processador; } public void doPaste() { String txt = Diagrama.getClipboardContents(); if (txt.isEmpty()) { return; } donePaste(txt); AtualizaTamanho(); } private void donePaste(String txt) { String tmp = palavra.substring(prompt.length()); if (!tmp.isEmpty()) { txt = insertTexto(palavra, txt).substring(prompt.length()); } String[] comms = txt.replaceAll("\r\n", "\n").split("\n"); for (String str : comms) { posCursor = (prompt + str).length(); if (!doEnter(prompt + str)) { doShowMsg(getProcessador().getErroMsg()); } } } public void doPaste(String txt) { if (txt.isEmpty()) { return; } donePaste(txt); AtualizaTamanho(); } public void doShowMsg(String msg) { strs.append(msg).append("\n"); palavra = getPrompt(); posCursor = 0; cliRect = getBounds(); repaint(cliRect); } public void Cancelar() { doShowMsg(getProcessador().doCancel()); } public boolean processeAtalhos(int keyCode) { boolean res = false; switch (keyCode) { case KeyEvent.VK_V: doPaste(); res = true; break; case KeyEvent.VK_Q: Sair(); res = true; break; case KeyEvent.VK_D: Cancelar(); res = true; break; } return res; } private JDialog janela = null; public JDialog getJanela() { return janela; } public final void setJanela(JDialog janela) { this.janela = janela; } public void Sair() { Cancelar(); getJanela().setVisible(false); } public void setPalavra(String str) { palavra = getPrompt() + str; posCursor = str.length(); repaint(); } private int posHist = -1; public void appendHistorico(String txt) { if (!txt.isEmpty()) { posHist = -1; if (!historico.isEmpty()) { if (historico.get(0).equals(txt)) { return; } } historico.add(0, txt.substring(getPrompt().length())); } } private void posicioneHistorico(int i) { if (historico.isEmpty()) { return; } int tmp = posHist + i; if (tmp < 0 || tmp >= historico.size()) { setPalavra(""); if (tmp < 0) { posHist = -1; } else { posHist = historico.size(); } return; } posHist += i; String res = historico.get(posHist); setPalavra(res); } private void movimenteCursor(int i) { int tmp = posCursor + i; String txt = palavra.substring(prompt.length()); if (tmp < 0 || tmp > txt.length()) { return; } posCursor = tmp; repaint(); } private void AutoComplete() { String ac = getProcessador().DoAutoComplete(palavra.substring(prompt.length()).trim()); if (!ac.isEmpty()) { setPalavra(ac); } } private void apagarLetra(int pos) { String tmp = palavra.substring(prompt.length()); if (tmp.isEmpty() || pos > tmp.length() - 1 || pos < 0) { return; } int tmpTxtPos = pos + getPrompt().length(); palavra = palavra.substring(0, tmpTxtPos) + (palavra.length() > tmpTxtPos + 1 ? palavra.substring(tmpTxtPos + 1, palavra.length()) : ""); //prompt posCursor = pos; repaint(); } }