Pedro B Posted September 25, 2012 at 12:16 AM Report #476440 Posted September 25, 2012 at 12:16 AM Boas pessoal. Estou desesperado por ajuda. Eu estou a tentar criar um teclado virtual, e já vi que o JAVA tem uma classe chamada Robot que consegue simular os keystrokes como se eles viessem do teclado, o problema é que como o dito teclado virtual que estou a tentar criar está dentro de um JInternalFrame, o campo que deveria receber o input perde o focus quando clico nos botões do teclado ou quando o frame que tem o teclado é adicionado no ecrã e portanto o input não vai para o dito campo (JTextField). Resolvi então optar por outra abordagem, usei uma PipedOutputStream que está na frame do teclado para escrever numa PipedInputStream, que está na frame principal e assim recebo directamente os dados (caracteres) correspondentes a cada tecla do teclado na frame principal. Até aqui tudo bem, consigo escrever na PipedOutputStream e ler o conteúdo da PipedInputStream que está na frame principal. A frame com o teclado só aparece quando clico na JTextField em que pretendo escrever, para isto utilizo um EventListener que detecta quando clico nessa JTextField, o problema é que a partir daqui eu preciso que o método que é executado quando clico na TextField espere que o utilizador escreva o texto que pretende que fique na TextField e não faço a minima ideia de como o fazer. Já tentei criar uma flag (campo booleano) na frame do teclado que indica se o utilizador acabou ou não de escrever e usei um loop (while) no método da TextField para verificar essa flag. O problema é que os loops param a execução do programa e ao faze-lo a frame do teclado também nem chega a aparecer... Alguém sabe alguma forma de conseguir resolver isto? Existe alguma forma de saber a aprtir de uma frame se um determinado botão foi clicado, noutra frame? Obrigado desde já, cumprimentos.
Pedro B Posted September 25, 2012 at 04:03 PM Author Report #476486 Posted September 25, 2012 at 04:03 PM Estive a pensar e... se calhar apenas detectar se um determinado botão foi clicado noutra frame talvez não seja aquilo que vá realmente resolver o problema. Existe alguma forma de fazer a primeira form esperar que o utilizador faça o input e depois continuar a execução? Algo do tipo wait() mas que volte executar o programa quando uma determinada variável boolean tiver o valor true? Não sei... os loops não me parecem ser a solução porque, mesmo tendo o código que apresenta a frame no ecrã primeiro que o loop (while) sempre que experimento usar um loop while o programa para a execução e não aparece a frame no ecrã.... Estou perdido e isto é para um software em que estou a trabalhar na empresa onde trabalho... Tentei optar por usar o Teclado no ecrã do Windows através do JAVA com o Runtime.exec() mas aparece uma mensagem de erro a dizer que não é possivel abrir o teclado no ecrã.... Já vi que tem a ver com privilégios e que executar isso através do CMD no JAVA resolvia isso, mas mesmo assim... o problema persiste.... também confesso que ainda não explorei mais soluções para esta possibilidade.... Já ando ás voltas com este teclado virtual há uns dias.... estou a dar em tolo
HappyHippyHippo Posted September 25, 2012 at 04:29 PM Report #476487 Posted September 25, 2012 at 04:29 PM diz-me só uma coisa : afinal o segundo frame (a do teclado) é de uma segunda aplicação ou não ? IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Pedro B Posted September 25, 2012 at 08:40 PM Author Report #476527 Posted September 25, 2012 at 08:40 PM não, faz tudo parte da mesma aplicação
Pedro B Posted September 25, 2012 at 08:58 PM Author Report #476537 Posted September 25, 2012 at 08:58 PM É assim, eu estou a utilizar a plataforma Netbeans para fazer a aplicação (NetBeans Platform Application), e com isto eu tenho acesso a uma class, WindowManager através da qual eu tenho acesso à janela principal da aplicação onde são inseridos todos os frames. Desta forma eu consigo aceder a todos os componentes que foram adicionados nos frames, e assim conseguia, dentro do frame do teclado inserir o input nos componentes que queria, isto até funcionava de início, mas agora com o aumento dos frames e uma vez que há mais frames dentro de outros, torna-se mais dificil de aceder aos campos para fazer input, eu deixo aqui a class que utilizo para inserir o input nos componentes: public class KeyboardComm { //Atributos /** * Nome do TopComponent alvo para o input */ private String topComponent; /** * Indica se o coord_Componente está dentro de uma form ou não */ private Boolean hasForm; /** * Nome da form caso o campo/componente esteja dentro da form */ private String form; /** * Nome do component para o input */ private Point coord_Componente; /** * Tipo do Componente alvo para o input (Enumerador) */ private TipoInputComponent tipoComponente; /** * Texto do input */ private StringBuilder text; /** * Posição da célula na tabela (x - linha, y - coluna) */ private Point cellPosition; //Construtores public KeyboardComm() { this.topComponent = new String(); this.hasForm = false; this.form = new String(); this.coord_Componente = null; this.tipoComponente = TipoInputComponent.CaixaTexto; this.text = new StringBuilder(0); this.cellPosition = new Point(); } public KeyboardComm(KeyboardComm keybComm) { this.coord_Componente = keybComm.getCoord_Componente(); this.form = keybComm.getForm(); this.hasForm = keybComm.hasForm(); this.text = keybComm.getBuilderText(); this.tipoComponente = keybComm.getTipoComponente(); this.topComponent = keybComm.getTopComponent(); this.cellPosition = keybComm.getCellPosition(); } //Métodos dos atributos /** * Devolve o nome do TopComponent alvo para o input * * @return */ private String getTopComponent() { return topComponent; } /** * Define o nome do TopComponent alvo para o input * * @param topComponent */ public void setTopComponent(String topComponent) { this.topComponent = topComponent; } /** * Indica se o component alvo do input está dentro de uma Form * * @return */ private Boolean hasForm() { return hasForm; } /** * Define um valor que indica se o coord_Componente alvo do input está * dentro de uma Form * * @param hasForm */ public void setHasForm(Boolean hasForm) { this.hasForm = hasForm; } /** * Devolve o nome da Form que contem o Component alvo do input (caso este * esteja dentro de uma Form) * * @return */ private String getForm() { return form; } /** * Define o nome da Form onde esté o Component alvo do input (caso este * esteja dentro de uma Form) * * @param form */ public void setForm(String form) { this.form = form; } /** * Devolve o Component alvo do input * * @return */ private Point getCoord_Componente() { return (Point) coord_Componente.clone(); } /** * Define um novo Component avlo do input * * @param coord_Componente */ public void setCoord_Componente(Point coord_Componente) { this.coord_Componente = (Point) coord_Componente.clone(); } /** * Devolve (Enumerador) o tipo do Component alvo do input * * @return */ private TipoInputComponent getTipoComponente() { return tipoComponente; } /** * Define o tipo do Component alvo do input (Enumerador - * TipoInputComponent) * * @param tipoComponente */ public void setTipoComponente(TipoInputComponent tipoComponente) { this.tipoComponente = tipoComponente; } /** * Devolve o texto de input * * @return */ private String getText() { return text.toString(); } private StringBuilder getBuilderText() { return this.text; } /** * Define o novo texto do input * * @param text */ private void setText(StringBuilder text) { this.text = text; } /** * Devolve a posição da célula dentro da tabela * * @return */ private Point getCellPosition() { return cellPosition; } /** * Guarda o valor da posição da célula dentro da tabela. * * @param cellPosition */ public void setCellPosition(Point cellPosition) { this.cellPosition.setLocation(cellPosition); } /** * Cria uma nova instancia da Class KeyboardComm clonada a partir de outra. * * @return */ @Override public KeyboardComm clone() { return new KeyboardComm(this); } /** * Insere o texto(caracter neste caso) no respectivo componente * @param txt */ public void setTextFieldInput(String txt) { //Caso o componente não esteja dentro de uma Form secundária e seja uma caixa de texto if (hasForm() == false && getTipoComponente() == TipoInputComponent.CaixaTexto) { JTextField field; Mode mode; //Procurar qual o TopComponent onde se ncontra o componente mode = WindowManager.getDefault().findMode(WindowManager.getDefault().findTopComponent(this.getTopComponent())); //Aceder à TextField do TopCOmponent para input field = (JTextField) WindowManager.getDefault().getOpenedTopComponents(mode)[0].getComponentAt(this.getCoord_Componente()); //Adicionar a letra da tecla pressionada à TextField this.setText(new StringBuilder(field.getText())); this.getBuilderText().append(txt); field.setText(this.getText()); //Caso o componente não esteja dentro de uma Form secundária mas seja uma tabela } else if (hasForm() == false && getTipoComponente() == TipoInputComponent.Tabela) { JTable table = null; Mode mode; //Procurar qual o TopComponent onde se encontra o componente mode = WindowManager.getDefault().findMode(WindowManager.getDefault().findTopComponent(this.getTopComponent())); //Correr todos os Components existentes no TopComponent encontrado em cima for (Component component : WindowManager.getDefault().getOpenedTopComponents(mode)[0].getComponents()) { //Caso o componente seja um JScrollPane, então em principio trata-se de uma JTable if (component.getClass().toString().contains("JScrollPane") == true) { JScrollPane scrollP = (JScrollPane) component; //Aceder à tabela dentro do JScrollPane JViewport viewport = scrollP.getViewport(); table = (JTable) viewport.getView(); break; } } this.setText(new StringBuilder(table.getValueAt((int) this.getCellPosition().getX(), (int) this.getCellPosition().getY()).toString())); this.getBuilderText().append(txt); table.setValueAt(this.getText(), (int) this.getCellPosition().getX(), (int) this.getCellPosition().getY()); } } /** * Função de BackSpace ou apagar caracter */ public void backSpaceFunction() { //Caso o componente não esteja dentro de uma Form secundária e seja uma caixa de texto if (hasForm() == false && getTipoComponente() == TipoInputComponent.CaixaTexto) { JTextField field; Mode mode; //Procurar qual o TopComponent no qual se encontra o componente mode = WindowManager.getDefault().findMode(WindowManager.getDefault().findTopComponent(this.getTopComponent())); //Aceder à TextField do TopCOmponent para input field = (JTextField) WindowManager.getDefault().getOpenedTopComponents(mode)[0].getComponentAt(this.getCoord_Componente()); //Caso a caixa de texto tenha um comprimento superior a 0 if (field.getText().length() > 0) { this.setText(new StringBuilder(field.getText())); field.setText(this.getText().substring(0, this.getText().length() - 1)); } // Caso o componente não esteja dentro de uma Form secundária mas seja uma JTable }else if (hasForm() == false && getTipoComponente() == TipoInputComponent.Tabela) { JTable table = null; Mode mode; //Procurar o TopComponent onde se encontra o componente mode = WindowManager.getDefault().findMode(WindowManager.getDefault().findTopComponent(this.getTopComponent())); //Correr todos os componentes nesse TopComponent for (Component component : WindowManager.getDefault().getOpenedTopComponents(mode)[0].getComponents()) { //Caso o componente encontrado seja um JScrollPane então em principio é dentro deste que econtramos //a tabela if (component.getClass().toString().contains("JScrollPane") == true) { JScrollPane scrollP = (JScrollPane) component; //Aceder à tabela dentro do JScrollPane JViewport viewport = scrollP.getViewport(); table = (JTable) viewport.getView(); break; } } this.setText(new StringBuilder(table.getValueAt((int) this.getCellPosition().getX(), (int) this.getCellPosition().getY()).toString())); table.setValueAt(this.getText().substring(0, this.getText().length()-1), (int) this.getCellPosition().getX(), (int) this.getCellPosition().getY()); } } } Bom.... em último recurso uso esta class, carece de alguma optimização, mas se não houver outra forma...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now