Jump to content

Esperar por input noutra frame


Recommended Posts

Posted

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.

Posted

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

Posted

É 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...

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.