41bb726c

Dia 14

Windows, ligação em rede e outros petiscos

Laura Lemay


CONTENETS

Aqui está no dia anterior da segunda semana, e termina-se quase com applets e o awt. Com a informação aprenderá hoje que pode criar uma grande variedade de applets e aplicações usando Java. As lições de próxima semana fornecem mais do material promovido de que precisará se começar a fazer o trabalho realmente sério em Java.

Hoje, para terminar nesta semana, cobriremos três tópicos muito diferentes:

Windows, cardápios e caixas de diálogo

Hoje terminará os bits últimos do awt que não se ajustou na lição de ontem. Além de toda a gráfica, eventos, interface de usuário e mecanismos de leiaute que o awt fornece, também fornece janelas, cardápios, e as caixas de diálogo, permitindo-lhe criam aplicações totalmente apresentadas como parte do seu applet ou independentemente para aplicações de Java autônomas.

As Classes de Janela awt

Java awt classes para produzir janelas e diálogos herda de uma classe única: Window. A classe de Window, que ela mesma herda de Container (e por isso é um padrão awt componente), fornece o comportamento genérico para todas as coisas parecidas a uma janela. Geralmente não usa exemplos de Window, contudo; usa exemplos de Frame ou Dialog. A figura 14.1 mostra a hierarquia de classe de Janela simples.

A figura 14.1: A hierarquia de classe de Janela.

A classe de Frame provê uma janela de uma barra de título, caixas fechadas e outras características de janela específicas para a plataforma. As armações também o deixam acrescentar barras de cardápio. Dialog é uma forma mais limitada de Frame que tipicamente não tem um título. FileDialog, subclasse de Dialog, fornece uma caixa de diálogo de colhedor do arquivo padrão (normalmente só usável do interior de aplicações de Java por causa de restrições de segurança em applets).

Quando quiser acrescentar uma nova janela ou diálogo ao seu applet ou aplicação, criará subclasses de classes de Dialog e o Frame.

Armações

As armações são janelas que são independentes de um applet e do browser que o contém - são janelas separadas com os seus próprios títulos, alteram o tamanho de maçanetas, caixas fechadas e barras de cardápio. Pode criar armações do seu próprio applets para produzir janelas, ou pode usar armações em aplicações de Java para manter os conteúdos daquela aplicação.

Uma armação é uma janela específica para a plataforma com um título, uma barra de cardápio, caixas fechadas, altere o tamanho de maçanetas e outras características de janela.

Para criar uma armação, use um dos seguintes construtores:

Como as armações herdam de Window, que herda de Container, que herda de Component, as armações criam-se e usaram muito de mesmo modo que outros componentes awt se criam e se usam. As armações são containeres, como listas são, portanto pode acrescentar-lhes outros componentes tão como ia listas regulares, usando o método de add(). O leiaute à revelia de armações é BorderLayout. Aqui está um exemplo único que cria uma armação, estabelece o seu leiaute e acrescenta dois botões:

win = new Frame("My Cool Window");
win.setl1ayout(new BorderLayout(10, 20));
win.add("North", new Button("Start"));
win.add("Center", new Button("Move"));

Para estabelecer um tamanho da nova armação, use o método de resize() com a largura e a altura da nova armação. Deste modo, por exemplo, esta linha do código altera o tamanho da janela para ser 100 pixéis largos e 200 pixéis altos:

win.resize(100, 200);

Observe que porque os sistemas diferentes têm ideias diferentes do que um pixel é e resoluções diferentes daqueles pixéis, é difícil criar uma janela que é o tamanho "direito" de cada plataforma. Windows que trabalha perfeito para cada um pode ser demasiado grande ou demasiado pequeno para o outro. Um caminho em volta disto é usar o método de pack() em vez de resize(). O método de pack(), que não tem argumentos, cria uma janela do tamanho mais pequeno possível dado os tamanhos atuais de todos os componentes dentro daquela janela e o gerente de leiaute e inserções no uso. Aqui está um exemplo que cria dois botões e os acrescenta a uma janela. Então alterarão o tamanho da janela à janela mais pequena possível que ainda pode manter aqueles botões:

win = new Frame("My Other Cool Window");
win.setl1ayout(new FlowLayout()));
win.add("North", new Button("OK"));
win.add("Center", new Button("Cancel"));
win.pack();

Quando inicialmente cria uma janela, é invisível. Tem de usar o método de show() para fazer a janela aparecer onscreen (pode usar hide() para escondê-lo novamente):

win.show();

Observe que quando surge janelas do interior de applets, o browser pode indicar de algum modo que a janela não é uma janela do navegador normalmente regular com um aviso na própria janela. No Netscape, há uma barra amarela no fundo de cada janela que diz Untrusted Java Window. Este aviso destina-se para deixar os seus usuários saber que a sua janela vem do applet e não do próprio browser (lembre-se de que a classe de armação produz janelas que olham como janelas de sistema normais). O aviso é impedi-lo de criar um applet malicioso que, por exemplo, poderia pedir ao usuário a sua senha. Não há nada que pode fazer para evitar este aviso; está lá para ficar enquanto quer usar janelas com applets.

Listings14.1 e 14,2 exemplos de demonstração de um applet simples com uma armação de janela instantânea (tanto o applet como a janela se mostram na Figura 14.2). O applet tem dois botões: um para mostrar a janela, e um para esconder a janela. A própria armação, criado de uma subclasse que criei chamou BaseFrame, contém uma etiqueta única: This is a Window. usará esta janela básica e applet até o fim desta seção, portanto mais entende o que está acontecendo aqui o mais fácil será depois.

A figura 14.2: Windows.


A listagem 14.1. Uma janela instantânea.
 1:import java.awt.*;
 2:
 3:public class PopupWindow extends java.applet.Applet {
 4:    Frame window;
 5:
 6:    public void init() {
 7:      add(new Button("Open Window"));
 8:      add(new Button("Close Window"));
 9:
10:      window = new BaseFrame("A Popup Window");
11:      window.resize(150,150);
12:      window.show();
13:    }
14:
15:    public boolean action(Event evt, Object arg) {
16:       if (evt.target instanceof Button) {
17:          String label = (String)arg;
18:          if (label.equals("Open Window")) {
19:              if (!window.isShowing())
20:                  window.show();
21:          }
22:          else if (label.equals("Close Window")) {
23:              if (window.isShowing())
24:                  window.hide();
25:          }
26:          return true;
27:       }
28:       else return false;
29:    }
30:}


A listagem 14.2. A classe de BaseFrame .
 1:import java.awt.*;
 2:
 3:class BaseFrame extends Frame {
 4:  String message = "This is a Window";
 5:
 6:  BaseFrame1(String title) {
 7:    super(title);
 8:    setFont(new Font("Helvetica", Font.BOLD, 12));
 9:  }
10:
11:  public void paint(Graphics g) {
12:     g.drawString(message, 20, 20);
13:  }
14:}

Há duas classes que compõem este exemplo: O primeiro, PopupWindow, é a classe applet que cria e controla a janela instantânea. No método de init() daquela classe (linhas 6 para 13), acrescentamos dois botões de controle ao applet para controlar a janela, e logo criado, alterado o tamanho, e mostramos a própria janela.

O controle neste applet ocorre quando um dos botões se aperta. Aqui, o botão Open Window simplesmente mostra a janela se se tenha escondido (linhas 18 para 21) e o esconder se estiver mostrando (linhas 22 para 25).

A própria janela é uma espécie especial da armação chamada BaseFrame. Neste exemplo, a armação é regularmente simples; tudo que faz é pintar uma mensagem de texto perto do topo da armação. Como as armações são componentes, como outros componentes, pode ter acrescentado tão facilmente um gerente de leiaute, botões, campos de texto, e assim por diante, a esta armação.

Windows final

Pode ter notado, se lançou aquela janela instantânea applet para jogar com ele, que a caixa fechada da nova janela não trabalha. Nada acontece quando clica no rato na caixa. Para implementar o comportamento para fechar a janela - para janelas instantâneas como em applets para escondê-los ou sair a aplicação completamente para aplicações-you'll têm de usar um método de handleEvent() na sua classe de Frame para testar para o evento de WINDOW_DESTROY.

No exemplo de janela instantânea, escolhendo a caixa fechada deve esconder-se a janela (chame o método de hide()). Então pode mostrar-lhe novamente a utilização do botão Open Window no applet. Isto é um embaraço muito simples; somente acrescente o seguinte handleEvent() à sua classe de BaseFrame1:

public boolean handleEvent(Event evt) {
   if (evt.id == Event.WINDOW_DESTROY) hide();
   return super.handleEvent(evt);
}

Cardápios

Cada nova janela que cria pode ter a sua própria barra de cardápio ao longo do topo daquela janela. Cada barra de cardápio pode ter um número de cardápios, e cada cardápio, à sua vez, pode ter itens de cardápio. O awt fornece classes para todas estas coisas chamadas, respectivamente, MenuBar, Menu e MenuItem. A figura 14.3 mostra as classes de cardápio.

A figura 14.3: As classes de cardápio awt.

Observe que pode ter barras de cardápio e cardápios individuais em Java só em componentes que têm armações das barras de título em janelas instantâneas do trabalho de applets somente perfeito, como fazem janelas aplicadas de Java, mas não pode mandar anexar uma barra de cardápio a um próprio applet.

Cardápios e barras de cardápio

Para criar uma barra de cardápio de uma janela dada, crie um novo exemplo da classe MenuBar:

MenuBar mbar = new MenuBar();

Para estabelecer esta barra de cardápio como o cardápio à revelia da janela, use o método de setMenuBar() (definido na classe de Frame):

window.setMenuBar(mbar);

Acrescente cardápios individuais (Arquivo, Edite, e assim por diante) à barra de cardápio criando-os e logo acrescentando-os à barra de cardápio usando add():

Menu myMenu = new Menu("File");
mbar.add(myMenu);

Alguns sistemas fornecem um cardápio de ajuda especial, que se desenha no lado direito da barra de cardápio ao contrário de em algum lugar no meio. Pode indicar que um cardápio específico é o cardápio de ajuda com o método de setHelpMenu(). O cardápio dado já deve acrescentar-se ao próprio cardápio antes de fazer-se de um cardápio de ajuda:

Menu helpmenu = new Menu("Help");
mbar.add(helpmenu);
mbar.setHelpMenu(helpmenu);

Se, por alguma razão, quiser impedir um usuário de selecionar um cardápio, pode usar a ordem de disable() naquele cardápio (e a ordem de enable() de pô-la à disposição novamente):

myMenu.disable();

Itens de cardápio

Há quatro espécies de itens que pode acrescentar a cardápios individuais:

Os itens de cardápio regulares acrescentam-se usando a classe de MenuItem. Acrescente-os a um cardápio usando o método de add():

Menu myMenu = new Menu("Tools");
myMenu.add(new MenuItem("Info"));
myMenu.add(new MenuItem("Colors"));

Os subcardápios podem acrescentar-se simplesmente criando um novo exemplo de Menu e acrescentando-o ao primeiro cardápio. Então pode acrescentar itens àquele cardápio:

Menu submenu = new Menu("Sizes");
myMenu.add(submenu);
submenu.add(new MenuItem("Small"));
submenu.add(new MenuItem("Medium"));
submenu.add(new MenuItem("Large"));

A classe de CheckBoxMenuItem cria um item de cardápio com uma caixa de seleção nele, permitindo ao estado de cardápio ser toggled em e de (seleção uma vez faz a caixa de seleção parecer selecionada; a seleção dele novamente não seleciona a caixa de seleção). Crie e acrescente um item de cardápio de caixa de seleção do mesmo caminho cria e acrescenta itens de cardápio regulares:

CheckboxMenuItem coords =
    new CheckboxMenuItem("Show Coordinates");
myMenu.add(coords);

Finalmente, para acrescentar um separador a um cardápio (uma linha costumou separar grupos de itens em um cardápio), crie e acrescente um item de cardápio com uma arremetida única (-) como a etiqueta. Aquele item de cardápio especial vai se desenhar com uma linha de separador. Estas duas seguintes linhas do código de Java criam um item de cardápio de separador e acrescentam-no ao menu myMenu:

MenuItem msep = new MenuItem("-");
myMenu.add(msep);

Qualquer item de cardápio pode ser inválido usando o método de disable() e permitiu novamente usar enable(). Os itens de cardápio fora do serviço não podem selecionar-se:

MenuItem item = new MenuItem("Fill");
myMenu.addItem(item);
item.disable();

Acrescentará uma barra de cardápio e cardápio típica da janela instantânea applet em um bocado; mas primeiro vamos aprender sobre como ativar itens de cardápio quando se selecionam.

Ações de cardápio

O ato de selecionar um item de cardápio faz que a um evento de ação se gere. Pode tratar aquela ação do mesmo caminho trata outros métodos de action - ignorando action(). Tanto os itens de cardápio regulares como os itens de cardápio de caixa de seleção têm ações que geram um extra argumento que representa a etiqueta daquele cardápio. Pode usar aquela etiqueta para decidir que ação tomar. Observe, também, que porque CheckBoxMenuItem é uma subclasse de MenuItem, não tem de tratar aquele item de cardápio como um caso especial. Neste exemplo, o item de menu Show Coordinates é um CheckBoxMenuItem, e Encha-se é um item de cardápio regular:

public boolean action(Event evt, Object arg) {
    if (evt.target instanceof MenuItem) {
        String label = (String)arg;
        if (label.equals("Show Coordinates")) toggleCoords();
        else if (label.equals("Fill")) fillcurrentArea();
        return true;
    }
    else return false;
}

Uma janela instantânea com cardápios

Vamos acrescentar um cardápio à janela instantânea que criou na seção prévia. Há dois passos aqui: criação e soma do cardápio, com todos os seus itens de cardápio, ao leiaute, e logo soma de um método de ação para tratar com as ações. Aqui modificaremos a classe de BaseFrame para incluir ambas estas coisas; a Listagem 14.3 mostra o novo código. A figura 14.4 mostra o cardápio na ação.

A figura 14.4: Um cardápio.

Observar
No código de mostra do CD, criei uma nova classe chamada BaseFrame2 desta parte do exemplo e uma nova classe PopupWindowMenu.java para ser o applet que possui esta janela. Use PopupWindowMenu.html para examiná-lo.


A listagem 14.3. BaseFrame com um cardápio.
 1:import java.awt.*;
 2:
 3:class BaseFrame2 extends Frame {
 4:  String message = "This is a Window";
 5:
 6:  BaseFrame2(String title) {
 7:    super(title);
 8:    setFont(new Font("Helvetica", Font.BOLD, 12));
 9:
10:    MenuBar mb = new MenuBar();
11:    Menu m = new Menu("Colors");
12:    m.add(new MenuItem("Red"));
13:    m.add(new MenuItem("Blue"));
14:    m.add(new MenuItem("Green"));
15:    m.add(new MenuItem("-"));
16:    m.add(new CheckboxMenuItem("Reverse Text"));
17:    mb.add(m);
18:    setMenuBar(mb);
19:  }
20:
21:  public boolean action(Event evt, Object arg) {
22:    String label = (String)arg;
23:    if (evt.target instanceof MenuItem) {
24:      if (label.equals("Red")) setBackground(Color.red);
25:      else if (label.equals("Blue")) setBackground(Color.blue);
26:      else if (label.equals("Green")) setBackground(Color.green);
27:      else if (label.equals("Reverse Text")) {
28:         if (getForeground() == Color.black) {
29:            setForeground(Color.white);
30:         } else setForeground(Color.black);
31:      }
32:      repaint();
33:      return true;
34:    } else return false;
35:  }
36:
37:  public void paint(Graphics g) {
38:     g.drawString(message, 20, 20);
39:  }
40:
41:  public boolean handleEvent(Event evt) {
42:     if (evt.id == Event.WINDOW_DESTROY) hide();
43:      return super.handleEvent(evt);
44:  }
45:}

Este cardápio tem quatro itens: um cada um para as cores vermelhas, azuis, e verdes (que, quando selecionado, modificam o contexto da janela), e um item de cardápio de caixa de seleção para inverter a cor do texto (ao branco). Todos acrescentam-se como parte do construtor a esta classe, em linhas 6 para 19.

Para tratar estes itens de cardápio quando se escolhem, precisa de um método de action(). Dentro de action() testa para ver se a ação veio de um item de cardápio (que inclui um item de cardápio de caixa de seleção), e nesse caso o teste de cada uma das etiquetas de cardápio à sua vez. Para os itens de cardápio vermelhos, azuis, e verdes, tudo que tem de fazer estabelece-se o contexto. Para o pino de madeira de texto Inverso, tem de descobrir primeiro a cor atual do texto, e logo invertê-lo.

Para terminar, chame um repaint() para assegurar-se o contexto e o texto atualizam-se propriamente e devolva o booleano apropriado.

Caixas de diálogo

As caixas de diálogo são funcionalmente semelhantes a armações nisto surgem novas janelas na tela. Contudo, as caixas de diálogo destinam-se para usar-se para janelas por exemplo passageiras, janelas que o avisam sobre avisos, janelas que lhe pedem a informação específica, e assim por diante. Os diálogos não têm normalmente barras de título ou muitas das características mais gerais que as janelas têm (embora possa criar um com uma barra de título), e podem fazer-se nonresizables ou modal (os diálogos modais previnem a entrada a qualquer outra janela na tela até que se despeçam).

Os diálogos são janelas passageiras destinadas para alertar o usuário a algum evento ou introduzir-se do usuário. Diferentemente de armações, os diálogos não têm geralmente uma barra de título ou fecham caixas.

Um diálogo modal previne a entrada a alguma de outras janelas na tela até que aquele diálogo se rejeite. (Não será capaz de trazer outras janelas à frente ou iconify uma janela de diálogo modal; deve rejeitar de fato o diálogo modal antes de ser capaz de fazer algo mais no sistema. Os avisos e os alertas são diálogos tipicamente modais.)

O awt fornece duas espécies de caixas de diálogo: a classe de Dialog, que fornece um diálogo genérico e FileDialog, que produz o diálogo de browser de arquivo específico para a plataforma.

Objetos de Dialog

Os diálogos criam-se e usam-se do modo quase o mesmo como janelas. Para criar um diálogo genérico, use um destes construtores:

A janela de diálogo, como a janela de armação, é uma lista na qual pode expor e desenhar componentes de interface de usuário e executar operações de gráficos, tão como ia qualquer outra lista. Como outras janelas, o diálogo é inicialmente invisível, mas pode mostrá-lo com show() e escondê-lo com hide().

Vamos acrescentar um diálogo àquele mesmo exemplo com a janela instantânea. Aqui modificaremos a classe de BaseFrame mais uma vez para incluir um diálogo e acrescentar uma nova classe, TextDialog, que produz um diálogo de entrada de texto semelhante a um mostrado na Figura 14.5.

A figura 14.5: O diálogo de texto Entrar.

Para acrescentar o diálogo à classe de BaseFrame, as modificações são menores. Primeiro precisará de uma variável de exemplo para manter o diálogo, desde que se estará referindo a ele em todas as partes desta classe:

TextDialog dl;

Depois acrescentará um item de cardápio ao método de construtor de classe de BaseFrame para modificar o texto as exposições de janela instantânea. Este novo item de cardápio vai somente depois do item de texto Inverso:

...
m.add(new CheckboxMenuItem("Reverse Text"));
m.add(new MenuItem("Set Text..."));
...

Naquele mesmo método de construtor, pode criar o diálogo (um exemplo da nova classe TextDialog no qual criará um bocado), destine-o à variável de exemplo de dl e altere o tamanho dele (como mostrado em duas seguintes linhas do código). Não quer mostrá-lo ainda porque só deve aparecer quando o item de cardápio correto se seleciona:

dl = new TextDialog(this, "Enter Text", true);
dl.resize(150,100);

Para conseguir que o diálogo apareça no momento apropriado, acrescentará uma linha ao método de action() para que quando o item de menu Set Text se escolhe, o método de dl.show() se chame. Pode pôr esta ação no mesmo bloco de if-else que o resto das ações:

...
else if (label.equals("Green")) setBackground(Color.green);
else if (label.equals("Set Text...")) dl.show();
else if (label.equals("Reverse Text")) {
...

Isto é o fim do comportamento que tem de acrescentar à janela para criar um diálogo; o resto do comportamento entra na classe de TextDialog, código para o qual se mostra na Listagem 14.4.


A listagem 14.4. A classe de TextDialog .
 1:import java.awt.*;
 2:
 3:class TextDialog extends Dialog {
 4:  TextField tf;
 5:  BaseFrame3 theFrame;
 6:
 7:  TextDialog(Frame parent, String title, boolean modal) {
 8:    super(parent, title, modal);
 9:
10:    theFrame = (BaseFrame3)parent;
11:    setl1ayout(new BorderLayout(10,10));
12:    setBackground(Color.white);
13:    tf = new TextField(theFrame.message,20);
14:    add("Center", tf);
15:    add("South", new Button("OK"));
16:    resize(150,75);
17:  }
18:
19:  public Insets insets() {
20:    return new Insets(30,10,10,10);
21:  }
22:
23:  public boolean action(Event evt, Object arg) {
24:    String label = (String)arg;
25:    if (evt.target instanceof Button) {
26:      if (label == "OK") {
27:         hide();
28:         theFrame.message = tf.getText();
29:         theFrame.repaint();
30:      }
31:    }
32:    else return false;
33:    return true;
34:  }
35:}

De muitos modos esta classe de diálogo é muito quase o mesmo como a classe de BaseFrame. Tem um construtor que funda o leiaute dos componentes e um método de action() para tratar com o seu comportamento. Este também tem um método de insets() de mais informação sobre leiaute, mas isto não é uma diferença significante.

Há algumas coisas a observar sobre este código. Em primeiro lugar, observe que a classe de TextDialog tem uma referência suportam à sua armação de pais. Tem de referir isto assim pode atualizar aquela armação com a nova informação sobre texto. Porque o diálogo precisa de atualizar a armação, em vez da armação compreensão quando precisa da atualização? Como só o diálogo sabe quando se rejeitou. É o diálogo que trata com a modificação quando o usuário pressiona OKAY, não a armação. Portanto o diálogo tem de ser capaz de ressuscitar a armação original. A linha 5 define uma variável de exemplo para manter aquela referência.

O diálogo de texto adquire uma referência para a armação de pais pelo seu construtor. Isto é de fato o construtor padrão de diálogos, portanto nada de novo tem de criar-se aqui. Simplesmente pode chamar super() para inicializar o diálogo, e logo acrescentar-lhe outros bits. O primeiro argumento ao construtor é o argumento de armação. Isto é aquele entrelaçamento à armação. Mas desde que adquire um objeto de armação, e quer um objeto de BaseFrame, terá de lançá-lo antes que possa destiná-lo à variável de exemplo de theFrame. Faça isto na linha 10.

O resto do construtor desta classe de diálogo simplesmente cria o leiaute: um campo de texto e um botão em um leiaute de borda.

O método de action() é o que diz ao diálogo esconder-se. As ações de rato transmitem-se à janela na qual ocorrem; não se filtram através de janelas, que é porque não pode testar para ver se a Tecla OK no diálogo se apertou do interior da classe de BaseFrame. Aqui criará um método de action() para fazer duas coisas quando a Tecla OK se apertar: esconda o diálogo e atualize a mensagem de texto na armação. Aqui está onde aquela referência a armação é importante; na linha 28 extrai o texto que se introduziu no campo de texto do diálogo e colocação dela na variável de exemplo de mensagem da armação. Na próxima vez a armação vai pintar (e di-la a repaint() na linha 29), a mensagem de texto vai se atualizar.

Anexar diálogos a Applets

Os diálogos só podem anexar-se a armações; para criar um diálogo tem de passar um exemplo da classe de Frame a um dos métodos de construtor do diálogo.

Isto conteria que não pode criar caixas de diálogo que se anexam a applets. Como applets não têm armações explícitas, não pode dar à classe de Dialog um argumento de armação. Por um bocado do código furtivo, contudo, pode obter o objeto de armação que contém isto applet (muitas vezes o browser ou própria janela de espectador applet) e logo use aquele objeto como a armação do diálogo.

Este código furtivo utiliza o método de getParent(), definido para todos os componentes awt. O método de getParent() devolve o objeto que contém este objeto. O pai de todas as aplicações awt, então, deve ser uma armação. Applets comportam-se deste mesmo modo; chamando getParent() repetidamente, consequentemente deve ser capaz de obter um exemplo de Frame. Aqui está o código furtivo para fazer isto que pode pôr dentro do seu applet:

Object anchorpoint = getParent()
while (! (anchorpoint instanceof Frame))
   anchorpoint = ((Component)anchorpoint).getParent();

Na primeira linha deste código, cria um anchorpoint variável, chamado local, para manter a armação eventual deste applet. O objeto destinado a anchorpoint pode ser uma de muitas classes, portanto declararemos que o seu tipo seja Object.

Duas segundas linhas deste código são um laço de while que chama getParent() em cada objeto diferente a cadeia até que venha a um objeto de Frame real. Observe aqui que desde que o método de getParent() só se define em objetos que herdam de Component, temos de lançar o valor de anchorpoint a Component cada vez do método de getParent() para trabalhar.

Depois das saídas de laço, o objeto contido na variável de anchorpoint será um exemplo da classe de Frame (ou uma das suas subclasses). Então pode criar um objeto de Dialog anexado àquela armação, lançando o anchorpoint mais uma vez para assegurar-se que tem um objeto de Frame:

TextDialog dl = new TextDialog((Frame)anchorpoint,
   "Enter Text", true);

Objetos de diálogo de arquivo

A classe de FileDialog provê um arquivo básico abrem/salvam a caixa de diálogo que lhe permite acessar o sistema de arquivos. A classe de FileDialog é independente do sistema, mas dependendo da plataforma, o Arquivo Aberto padrão ou Salvam o diálogo de Arquivo sobe-se.

Observar
Para applets, se pode até usar exemplos de FileDialog é dependente do browser (O Netscape simplesmente produz um erro). FileDialog é muito mais útil em aplicações autônomas.

Para criar um diálogo de arquivo, use os seguintes construtores:

Depois de criar um exemplo de FileDialog, use show() para expor-o:

FileDialog fd = new FileDialog(this, "FileDialog");
fd.show();

Quando o leitor escolhe um arquivo no diálogo de Arquivo e o rejeita, então pode acessar o nome de arquivo que escolheram usando métodos de getFile() e o getDirectory(); ambas as cadeias de regresso que indicam os valores o leitor selecionaram. Então pode abrir aquele arquivo usando a corrente e métodos de manejo de arquivo (que aprenderá sobre a próxima semana) e logo leia em ou escreva àquele arquivo.

Cursores

Se usar armações no seu applets ou aplicações, também pode estabelecer o ícone do cursor em momentos dados na execução do seu programa, para sinalizar esperam condições ou outros eventos que acontecem no seu programa.

O getCursorType() e os métodos de setCursor() definem-se na classe de Frame. Se puder alcançar um objeto de Frame, pode estabelecer o cursor (estabelecerá tipicamente cursores de janelas, mas também pode estabelecer cursores de applets utilização do método de getParent() que expliquei na seção "A ligação de Diálogos a Applets"). Ambos destes métodos usam o grupo de tipos de cursor predestinados na classe de Frame. A tabela 14.1 mostra os tipos de cursor que pode usar (e testar para) nas suas janelas.

Observar
Tenha em mente que não todas as plataformas usam os mesmos cursores. Por exemplo, os cursores para alterar o tamanho de janelas não existem em Macintosh.

A tabela 14.1. Tipos de cursor.

Variável de classeCursor
Frame.CROSSHAIR_CURSOR Um transversal cabelo (mais-formado) cursor
Frame.DEFAULT_CURSOR O cursor à revelia (normalmente um ponteiro ou flecha)
Frame.E_RESIZE_CURSOR Alteram o tamanho de um cursor para indicar algo
Frame.HAND_CURSOR Um cursor da forma da mão (para mover um objeto ou o contexto)
Frame.MOVE_CURSOR Um cursor para indicar que algo se está movendo
Frame.N_RESIZE_CURSOR Alteram o tamanho da borda superior de uma janela
Frame.NE_RESIZE_CURSOR Alteram o tamanho da esquina superior e direita de uma janela
Frame.NW_RESIZE_CURSOR Alteram o tamanho da esquina deixada o topo de uma janela
Frame.S_RESIZE_CURSOR Alteram o tamanho da borda inferior de uma janela
Frame.SE_RESIZE_CURSOR Alteram o tamanho da esquina direita ao fundo da janela
Frame.SW_RESIZE_CURSOR Alteram o tamanho da esquina deixada o fundo da janela
Frame.TEXT_CURSOR Um cursor de entrada do texto (às vezes chamava um I-raio)
Frame.W_RESIZE_CURSOR Alteram o tamanho da borda esquerda de uma janela
Frame.WAIT_CURSOR Uma operação longa realiza-se (normalmente um ícone de um relógio ou uma ampulheta)

Eventos de janela

Ontem aprendeu sobre a escrita dos seus próprios métodos de manipulador de eventos, e observou que a classe de Event define muitos eventos padrão para os quais pode testar. Os eventos de janela são parte daquela lista, portanto se usar janelas, estes eventos podem ter interesse para você, (por exemplo, para esconder uma janela quando se fecha, para parar um fio de correr quando a janela é iconified, ou executar alguma operação quando um arquivo se carrega ou se salva).

Pode testar a variável de exemplo de id do objeto de evento no seu método de handleEvent() para ver se algum destes eventos ocorreu:

if (evt.id == Event.WINDOW_DESTROY) hide();

A tabela 14.2. mostra vários eventos de Janela.

A tabela 14.2. Eventos de janela da classe de Event .

WINDOW_DESTROY Gerado quando uma janela se destrói usando a caixa fechada ou o item de menu Close
WINDOW_EXPOSE Gerado quando a janela se apresenta de outras janelas
WINDOW_ICONIFY Gerado quando a janela é iconified
WINDOW_DEICONIFY Gerado quando a janela se restaura de um ícone
WINDOW_MOVED Gerado quando a janela se move

Aplicações awt autônomas

Depois de todo o espaço e tempo dediquei à criação applets até este ponto, pode surpreender-se que pico uma descrição de aplicações de Java gráficas aqui no fim, e em uma seção regularmente pequena nisto. A razão disto consiste em que outro do que algumas linhas simples do código e no ambiente no qual cada um corre, não há muita diferença entre Java applet e uma aplicação de Java gráfica. Tudo que aprendeu até este ponto sobre o awt inclusive os métodos de gráficos, técnicas de animação, eventos, componentes de UI, e janelas e diálogos, pode usar-se o mesmo caminho em aplicações de Java que podem em applets. E as aplicações têm a vantagem de ser "do lado de fora da caixa de areia" - não têm nenhuma das restrições de segurança que applets têm. Pode fazer quase algo que quer com uma aplicação.

Assim, como vai sobre a criação de uma aplicação de Java gráfica? O código para fazê-lo é quase trivial. A sua classe aplicada principal deve herdar de Frame. Se usar fios (para a animação ou outro processamento), também deve implementar Runnable:

class MyawtApplication extends Frame implements Runnable {
...
}

Dentro do método de main() da sua aplicação, cria um novo exemplo da sua classe - porque a sua classe estende Frame, isto lhe dará uma nova janela awt de que então pode alterar o tamanho e mostrar como ia qualquer janela awt. Dentro do método de construtor da sua classe fundará as características awt habituais de uma janela que poderia fazer normalmente em um método de init() de um applet: Estabeleça o título, acrescente um gerente de leiaute, crie e acrescente componentes como uma barra de cardápio ou outros elementos UI, lance um fio, e assim por diante. Aqui está um exemplo simples:

class MyawtApplication extends Frame implements Runnable {

    MyawtApplication(String title) {
       super(title);

       setl1ayout(new FlowLayout());
       add(new Button("OK"));
       add(new Button("Reset"));
       add(new Button("Cancel"));
    }

    public static void main(String args[]) {
      MyawtApplications app = new MyawtApplication("Hi!  I'm an application");
      app.resize(300,300);
      app.show();
   }
}

Em sua maioria, pode usar algum dos métodos aprendeu sobre esta semana a controlar e dirigir a sua aplicação. Os únicos métodos que não pode usar são os específicos para applets (isto é, os definidos em java.applet.Applet, que inclui métodos para recuperar a informação URL e jogar os clipes áudio - veem a documentação API daquela classe de mais detalhes).

Ligação em rede em Java

A ligação em rede é a capacidade de fazer conexões do seu applet ou aplicação a um sistema sobre a rede. A ligação em rede em Java implica classes no pacote de java.net, que fornecem abstrações de transversal plataforma para operações de ligação em rede simples, inclusive a união e recuperar arquivos usando protocolos de Web comuns e criando tomadas parecidas a UNIX básicas. Usado em conjunto com correntes de entrada e saída (que aprenderá muito mais sobre a próxima semana), lendo e escrevendo arquivos sobre a rede fica como fácil como leitura ou escrita a arquivos no disco local.

Há restrições, naturalmente. Java applets normalmente não pode ler ou escrever do disco na máquina onde o browser corre. Java applets não pode unir-se a sistemas outros do que aquele no qual se guardaram originalmente. Mesmo considerando estas restrições, ainda pode realizar muito e aproveitar-se da Web para ler e processar a informação sobre a Rede.

Esta seção descreve três modos que pode comunicar-se com sistemas na Rede:

Criar conexões dentro de Applets

Provavelmente o modo mais fácil de usar a ligação em rede dentro de um applet é dizer ao browser que corre que applet carregar uma nova página. Pode usar isto, por exemplo, para criar mapas de imagem animados que, quando clicado, carregam uma nova página.

Para ligar-se a uma nova página, cria um novo exemplo da classe URL. Viu um pouco disto quando trabalhou com imagens, mas vamos sobre ele um pouco mais completamente aqui.

A classe de URL representa um localizador uniforme de recursos. Para criar um novo URL, pode usar uma de quatro formas diferentes:

Para o último (criando um URL de uma cadeia), tem de pegar uma exceção URL malformada, então rodear o construtor URL de um try...catch:

String url = "http://www.yahoo.com/";
try { theURL = new URL(url); }
catch ( MalformedURLException e) {
    System.out.println("Bad URL: " + theURL);
}

Adquirir um objeto de URL é a parte difícil. Uma vez que tem um, tudo que tem de fazer é passá-lo ao browser. Faça isto usando esta linha única do código, onde theURL é o objeto de URL de ligar-se a:

getAppletContext().showDocument(theURL);

O browser que contém Java applet com este código então carregará e exporá o documento nisto URL.

A listagem 14.5 mostra duas classes: ButtonLink e a sua classe de ajudante Bookmark. ButtonLink é um applet simples que expõe três botões que representam posições de Web importantes (os botões mostram-se na Figura 14.6). O clique nos botões faz que ao documento se carregue das posições às quais aqueles botões se referem.

A figura 14.6: botões de marcador de páginas.


A listagem 14.5. Botões de marcador de páginas.
 1: // Buttonlink.java starts here
 2: import java.awt.*;
 3: import java.net.*;
 4:
 5: public class ButtonLink extends java.applet.Applet {
 6:
 7:    Bookmark bmlist[] = new Bookmark[3];
 8:
 9:    public void init() {
10:        bmlist[0] = new Bookmark("Laura's Home Page",
11:             "http://www.lne.com/lemay/");
12:         bmlist[1] = new Bookmark("Gamelan",
13:             "http://www.gamelan.com");
14:         bmlist[2]= new Bookmark("Java Home Page",
15:             "http://java.sun.com");
16:
17:         setl1ayout(new GridLayout(bmlist.length,1, 10, 10));
18:         for (int i = 0; i < bmlist.length; i++) {
19:             add(new Button(bmlist[i].name));
20:         }
21:     }
22:
23:     public boolean action(Event evt, Object arg) {
24:         if (evt.target instanceof Button) {
25:             linkTo((String)arg);
26:             return true;
27:         }
28:         else return false;
29:     }
30:
31:     void linkTo(String name) {
32:         URL theURL = null;
33:         for (int i = 0; i < bmlist.length; i++) {
34:             if (name.equals(bmlist[i].name))
35:                 theURL = bmlist[i].url;
36:         }
37:         if (theURL != null)
38:             getAppletContext().showDocument(theURL);
39:     }
40: } //ButtonLink.java ends here
41:
42: //Bookmark.java starts here
43: import java.net.URL;
44: import java.net.MalformedURLException;
45:
46: class Bookmark {
47:     String name;
48:     URL url;
49:
50:     Bookmark(String name, String theURL) {
51:         this.name = name;
52:         try { this.url = new URL(theURL); }
53:         catch ( MalformedURLException e) {
54:         System.out.println("Bad URL: " + theURL);
55:     }
56: }
57:} //Bookmark.java ends here

Duas classes compõem este applet: O primeiro, ButtonLink, implementa o próprio applet real; o segundo, Bookmark, é uma classe que representa um marcador de páginas. Os marcadores de páginas têm duas partes: um nome e um URL.

Este determinado applet cria três exemplos de marcador de páginas (linhas 10 para 15) e guarda-os em uma tabela de marcadores de páginas (este applet pode modificar-se facilmente para aceitar marcadores de páginas como parâmetros de um arquivo de HTML). Para cada marcador de páginas, um botão cria-se cuja etiqueta é o valor do nome do marcador de páginas.

Quando os botões se apertam, o método de linkTo() chama-se. linkTo(), definido em linhas 31 para 38, extrai o nome do botão do evento, usa-o para procurar o URL real do objeto de marcador de páginas, e logo diz ao browser carregar o URL referido por aquele marcador de páginas.

Abertura de conexões de web

Em vez de pedir que o browser carregue somente os conteúdos de um arquivo, às vezes poderia querer vir mantêm-se de que os conteúdos de arquivo para que o seu applet pode usá-los. Se o arquivo que quer agarrar se guardar na Web e puder acessar-se usando as formas de URL mais comuns (http, ftp, e assim por diante), o seu applet pode usar a classe URL para adquiri-lo.

Observe que por razões de segurança, o applets pode unir-se à revelia atrás só ao mesmo anfitrião do qual originalmente carregaram. Isto significa que se mandar guardar o seu applets em um sistema chamado www.myhost.com, única máquina o seu applet pode abrir-se uma conexão a consistirá em que o mesmo anfitrião (e que o mesmo hostname, assim ter cuidado com pseudônimos de anfitrião). Se o arquivo que o applet quer recuperar estiver naquele mesmo sistema, usar conexões de URL é o modo mais fácil de adquiri-lo.

Esta restrição de segurança vai se modificar como tem escrito e tem testado applets até este ponto. Como não temos tratado com conexões de rede, fomos capazes de fazer toda a nossa prova no disco local simplesmente abrindo os arquivos de HTML em um browser ou com o instrumento de appletviewer . Não pode fazer isto com applets aquela rede aberta conexões. Para aqueles applets para trabalhar corretamente, deve fazer uma de duas coisas:

Saberá quando não faz coisas diretamente na consideração a assegurar-se do seu applet, e a conexão que abre, estão no mesmo servidor. Se tentar carregar um applet ou um arquivo de servidores diferentes, adquirirá uma exceção de segurança junto com a maior parte de outras mensagens de erro assustadoras impressas para a sua tela ou para o consolo de Java.

Isto disse, vamos mudar aos métodos e classes para recuperar arquivos da Web.

openStream()

A classe URL define um método chamado openStream(), que abre uma conexão de rede usando o URL dado (uma conexão HTTP da Web URLs, uma conexão de FTP DO FTP URLs, e assim por diante) e devolve um exemplo da classe InputStream (parte do pacote de java.io). Se converter aquela corrente em um DataInputStream (com um BufferedInputStream no meio da melhor realização), então pode ler carateres e linhas daquela corrente (aprenderá todos sobre correntes no Dia 19, "Correntes e entrada-saída"). Por exemplo, estas linhas abrem uma conexão ao URL guardado no theURL variável, e logo leem e ecoam cada linha do arquivo à produção padrão:

try {
    InputStream in = theURL.openStream();
    DataInputStream data = new DataInputStream(new BufferedInputStream(in);

    String line;
    while ((line = data.readLine()) != null) {
        System.out.println(line);
    }
}
catch (IOException e) {
    System.out.println("IO Error: " + e.getMessage());
}

Observar
Tem de agasalhar-se todas aquelas linhas em uma afirmação de try...catch para pegar IOException s gerado. Aprenderá mais sobre IOExceptions e o try e afirmações de catch sobre o Dia 17, "Exceções".

Aqui está um exemplo de um applet que usa o método de openStream() para abrir uma conexão a um Web site, lê um arquivo naquela conexão (o poema de Edgar Allen Poe "O Corvo") e expõe o resultado em uma área de texto. A listagem 14.6 mostra o código; a Figura 14.7 mostra o resultado depois que o arquivo se leu.

A figura 14.7: O GetRaven applet.

Uma nota importante: Se compilar este código como escrito, não trabalhará-you'll adquirem uma exceção de segurança. A razão consiste em que este applet abre uma conexão ao servidor www.lne.com para adquirir o arquivo raven.txt. Quando compila e dirige este applet, que applet não dirige em www.lne.com (a menos que seja eu, e já sei sobre este problema). Antes que compile este applet, assegure-se que modifica a linha 18 para apontar para uma cópia de raven.txt no seu servidor e instalar o seu applet e os seus arquivos de HTML naquele mesmo servidor (pode adquirir raven.txt do CD ou disto muito URL).

Alternadamente, pode usar o seu browser para apontar para o http://www.lne.com/Web/JavaProf/GetRaven.html URL. Aquela Página da Web carrega isto muito applet e carrega do arquivo corretamente. Como tanto o applet como o arquivo de texto estão no mesmo servidor, trabalha somente perfeito.


A listagem 14.6. A classe de GetRaven.
 1: import java.awt.*;
 2: import java.io.DataInputStream;
 3: import java.io.BufferedInputStream;
 4: import java.io.IOException;
 5: import java.net.URL;
 6: import java.net.URLConnection;
 7: import java.net.MalformedURLException;
 8:
 9: public class GetRaven extends java.applet.Applet implements Runnable {
10:   URL theURL;
11:  Thread runner;
12:   TextArea ta = new TextArea("Getting text...");
13:
14:   public void init() {
15:    setl1ayout(new GridLayout(1,1));
16:
17:     // chANGE THIS NEXT LINE BEFORE COMPILING!!!
18:     String url = "http://www.lne.com/Web/JavaProf/raven.txt";
19:     try { this.theURL = new URL(url); }
20:     catch ( MalformedURLException e) {
21:       System.out.println("Bad URL: " + theURL);
22:     }
23:     add(ta);
24:  }
25:
26:   public Insets insets() {
27:     return new Insets(10,10,10,10);
28:  }
29:
30:   public void start() {
31:     if (runner == null) {
32:       runner = new Thread(this);
33:       runner.start();
34:     }
35:  }
36:
37:   public void stop() {
38:     if (runner != null) {
39:       runner.stop();
40:       runner = null;
41:     }
42:  }
43:
44:   public void run() {
45:     URLConnection conn = null;
46:     DataInputStream data = null;
47:     String line;
48:    StringBuffer buf = new StringBuffer();
49:
50:     try {
51:       conn = this.theURL.openConnection();
52:       conn.connect();
53:      ta.setText("Connection opened...");
54:       data = new DataInputStream(new BufferedInputStream(
55:          conn.getInputStream()));
56:       ta.setText("Reading data...");
57:      while ((line = data.readLine()) != null) {
58:         buf.append(line + "\n");
59:       }
60:       ta.setText(buf.toString());
61:     }
62:     catch (IOException e) {
63:       System.out.println("IO Error:" + e.getMessage());
64:     }
65:}
66:}

O método de init() (linhas 14 para 24) funda o URL e a área de texto na qual aquele arquivo se exporá. O URL pode passar-se facilmente no applet via um parâmetro de HTML; aqui, somente codifica-se muito para a simplicidade.

Como poderia levar um tempo para carregar o arquivo sobre a rede, põe aquela rotina no seu próprio fio e usa o start() familiar, stop() e métodos de run() para controlar aquele fio.

Dentro de run() (linhas 44 para 64), o trabalho realiza-se. Aqui, inicializa um ramo de variáveis e logo abre a conexão ao URL (usando o método de openStream() na linha 50). Uma vez que a conexão está aberta, funda uma corrente de entrada em linhas 51 para 55 e lê nela, linha pela linha, pondo o resultado em um exemplo de StringBuffer (um buffer de cadeia é uma cadeia modificável). Pus todo este trabalho em um fio porque pode levar um tempo para a conexão para abrir-se e para o arquivo a ler-se em particular através de conexões mais lentas. Podem haver outras coisas que continuam no applet que tem de realizar-se concorrentemente ao carregamento de arquivo.

Uma vez que todos os dados leram-se, linha 60 conversos o objeto de StringBuffer em uma verdadeira cadeia e logo põem o que resulta na área de texto.

Uma outra coisa a observar sobre este exemplo consiste em que a parte do código que abriu uma conexão de rede, leia no arquivo, e criou uma cadeia rodeia-se da afirmação de catch e um try. Se algum erro ocorrer enquanto tenta ler ou processar o arquivo, estas afirmações permitem-lhe recuperar-se deles sem o choque de programa inteiro (neste caso, as saídas de programa com um erro, porque há pouco mais para fazer-se se o applet não puder ler o arquivo). try e catch dão-lhe a capacidade do manejo e recuperar-se de erros. Aprenderá mais sobre exceções no Dia 17.

Tomadas

Para transmitir aplicações em rede além que oferta de classes de URLconnection e URL (por exemplo, para outros protocolos ou para aplicações de ligação em rede mais gerais), Java fornece o Socket e classes de ServerSocket como uma abstração de técnicas de programação de tomada padrão. Aprenderá mais sobre o trabalho com tomadas de Java no Dia 26, "O Cliente/Servidor que Transmite em rede em Java", mas por agora aqui está um enfraquecimento muito curto das capacidades de tomada em Java.

A classe de Socket fornece uma interface de tomada de lado do cliente semelhante a tomadas de UNIX padrão. Para abrir uma conexão, crie um novo exemplo de Socket (onde hostname é o anfitrião para unir-se a, e portnum é o número de porto):

Socket connection = new Socket(hostname, portnum);

Observar
Se usar tomadas em um applet, ainda é sujeito às restrições de segurança applet que o impedem de unir a qualquer sistema outro do que o mesmo um o applet veio de.

Uma vez que a tomada está aberta, pode usar correntes de entrada e saída para ler e escrever daquela tomada (aprenderá todos sobre correntes de entrada e saída no Dia 19):

DataInputStream in = new DataInputStream(
    new BufferedInputStream(connection.getInputStream()));
DataOutputStream out= new DataOutputStream(
    new BufferedOutputStream(connection.getOutputStream()));

Uma vez que se faz com a tomada, não esqueça de fechá-la (isto também fecha todas as correntes de entrada e saída que pode ter fundado para aquela tomada):

connection.close();

As tomadas de lado do servidor funcionam semelhantemente com a exceção do método de accept(). Uma tomada de servidor escuta em um porto TCP de uma conexão de um cliente; quando um cliente se une àquele porto, o método de accept() aceita uma conexão daquele cliente. Usando tanto cliente como tomadas de servidor, pode criar aplicações que se comunicam um com outro sobre a rede.

Para criar uma tomada de servidor e atá-la a um porto, crie um novo exemplo de ServerSocket com o número de porto:

ServerSocket sconnection = new ServerSocket(8888);

Para escutar naquele porto (e aceitar uma conexão de qualquer cliente se um se fizer), use o método de accept():

sconnection.accept();

Uma vez que a conexão de tomada faz-se, pode usar correntes de entrada e saída para ler em e escrever ao cliente.

Ver o pacote de java.net de mais informação sobre tomadas de Java.

Modificações de tomadas de Java 1.1

Na 1.0.2 versão de Java, o Socket e as classes de ServerSocket fornecem uma implementação de tomada abstrata básica. Pode criar novos exemplos destas classes para fazer ou aceitar conexões e passar dados para a frente e para trás de um cliente a um servidor.

O problema vem quando tenta estender ou modificar o comportamento de tomada de Java. O Socket e as classes de ServerSocket no pacote de java.net são classes finais, que significa que não pode criar subclasses daquelas classes (aprenderá mais sobre a finalização de classes no Dia 15, "Modificadores, Controle de acesso e Desenho de Classe"). Para estender o comportamento das classes de tomada - por exemplo, permitir a conexões de rede trabalhar através de um firewall ou uma procuração, pode usar as classes abstratas SocketImpl e a interface SocketImplFactory para criar uma nova implementação de tomada de camada de transporte. Este desenho ajusta-se com a meta original de classes de tomada de Java: permitir àquelas classes ser portáteis a outros sistemas com mecanismos de transporte diferentes.

O problema com este mecanismo consiste em que enquanto trabalha para casos simples, o impede de acrescentar outros protocolos em cima de TCP (por exemplo, implementar um mecanismo de encriptação como SSL) ou para ter múltiplas implementações de tomada por tempo de execução de Java.

Por estas razões, em Java 1,1 tomadas vão se modificar tal que o Socket e as classes de ServerSocket são não-finais e extensíveis. Será capaz de criar subclasses destas classes em Java 1.1, que usam a implementação de tomada à revelia ou uma da sua própria criação. Isto permitirá capacidades de rede muito mais flexíveis a Java em 1,1.

Além disso, Java 1.1 acrescentou várias outras novas características ao pacote de java.net:

Já que mais informação sobre toda a ligação em rede se modifica entre Java 1.02 e 1.1, ver as páginas em http://java.sun.com/products/JDK/1.1/designspecs/net/index.html.

Outras insinuações de Applet

Nisto, seção última do dia anterior da segunda semana, vamos terminar com algumas pequenas insinuações que não se ajustaram em nenhuma parte: utilização de showStatus() para imprimir mensagens na janela de posição de browser, fornecimento applet informação e comunicação entre múltiplo applets na mesma página.

O método de showStatus()

O método de showStatus(), disponível na classe de Applet, permite-lhe expor uma cadeia na barra de posição do browser, que contém o applet. Pode usar isto para imprimir erro, conexão, ajuda ou outras mensagens de posição:

getAppletContext().showStatus("Change the color");

O método de getAppletContext() permite ao seu applet acessar características do browser que o contém. Já viu um uso disto com conexões, em que pode usar o método de showDocument() para dizer ao browser carregar uma página. usos de showStatus() que o mesmo mecanismo para imprimir mensagens de posição.

Observar
showStatus() não pode apoiar-se em todos os browseres, então não dependa dele para funcionalidade do seu applet ou interface. É um modo útil de comunicar a informação opcional ao seu usuário - se precisar de um método mais fiável da comunicação, fundar uma etiqueta no seu applet e o atualize para refletir modificações na sua mensagem.

Informação de Applet

O awt dá-lhe um mecanismo para associar a informação com o seu applet. Normalmente, há um mecanismo no browser que examina o applet para examinar a informação sobre exposição. Pode usar este mecanismo para assinar o seu nome ou a sua organização ao seu applet, ou fornecer a informação de contato para que os usuários possam vir mantêm-se de você se quiserem.

Para fornecer a informação sobre o seu applet, ignore o método de getAppletInfo():

public String getAppletInfo() {
    return "GetRaven copyright 1995 Laura Lemay";
}

Comunicação entre Applets

Às vezes quer ter uma página de HTML que tem vários applets diferentes nele. Para fazer isto, tudo que tem de fazer é incluem várias iterações diferentes da etiqueta de applet. O browser criará exemplos diferentes do seu applet para cada um que aparece na página de HTML.

E se quer comunicar-se entre aqueles applets? E se quer que uma modificação em um applet afete outro applets de algum modo? O melhor modo de fazer isto deve usar o contexto applet para vir a applets diferente na mesma página.

Observar
Previna-se que antes que faça o trabalho extenso com a comunicação inter-applet, o mecanismo descrito nesta seção se implementa diferentemente (e muitas vezes inseguramente) em browseres diferentes e ambientes de Java diferentes. Se tiver de confiar na comunicação entre applets das suas Páginas da Web, assegure-se que testa aqueles applets extensivamente em browseres diferentes em plataformas diferentes.

O contexto applet define-se em uma classe chamada, apropriadamente, AppletContext. Para adquirir um exemplo desta classe para você applet, usa o método de getAppletContext(). Já viu o uso do método de getAppletContext() de outros usos; também pode usá-lo para vir mantêm-se de outro applets na página. Por exemplo, para chamar um método denominado sendMessage() em todo o applets em uma página (inclusive a corrente applet), use o método de getApplets() e um laço de for que olha algo como isto:

for (Enumeration e = getAppletContext().getApplets();
        e.hasMoreElements();) {
     Applet current = (MyAppletSubclass)(e.nextElement());
     current.sendMessage();
}

O método de getApplets() devolve um objeto de Enumeration com uma lista do applets na página. Repetir sobre o objeto de Enumeration deste modo permite-lhe acessar cada elemento no Enumeration à sua vez. Observe que cada elemento no objeto de Enumeration é um exemplo da classe de Object; para conseguir que isto applet se comporte o modo ao qual o quer (e aceitam mensagens de outro applets), terá de lançá-lo para estar um exemplo da sua subclasse applet (aqui, a classe MyAppletSubclass).

Se quiser chamar um método em um applet específico, é ligeiramente mais complicado. Para fazer isto, dá ao seu applets um nome e logo envia-lhes de nome dentro do corpo do código para isto applet.

Para dar a um applet um nome, use o atributo de NAME a <APPLET> no seu arquivo de HTML:

<P>This applet sends information:
<APPLET CODE="MyApplet.class" WIDTH=100 HEIGHT=150
    NAME="sender"> </APPLET>
<P>This applet receives information from the sender:
<APPLET CODE="MyApplet.class" WIDTH=100 HEIGHT=150
    NAME="receiver"> </APPLET>

Para adquirir uma referência para outro applet na mesma página, use o método de getApplet() do contexto applet com o nome disto applet. Isto dá-lhe uma referência para o applet daquele nome. Então pode enviar a isto applet como se fosse somente outro objeto: chame métodos, estabeleça as suas variáveis de exemplo, e assim por diante. Aqui está algum código para fazer somente que:

// get ahold of the receiver applet
Applet receiver = (MyAppletSubclass)getAppletContext().getApplet("receiver");
// tell it to update itself.
receiver.update(text, value);

Neste exemplo usa o método de getApplet() para adquirir uma referência para o applet com o nome receiver. Observe que o objeto devolvido por getApplet é um exemplo da classe de Applet genérica; quererá mais provavelmente lançar aquele objeto a um exemplo da sua subclasse. Considerando a referência para o applet denominado, então pode chamar métodos nisto applet como se fosse somente outro objeto no seu próprio ambiente. Aqui, por exemplo, se ambos applets tiverem um método de update(), pode dizer a receiver atualizar-se usando a informação que a corrente applet tem.

Denominar o seu applets e logo referir-se para eles usando os métodos descritos nesta seção permitem ao seu applets comunicar-se e ficar na sincronização um com outro, fornecendo o comportamento uniforme para todo o applets na sua página.

Sumário

Congratulações! Tome um respiro-fundo-you're terminado com a Semana 2. Esta semana foi cheia da informação útil sobre criação applets e utilização de Java awt classes para expor, desenhar, animar, processar a entrada e criar interfaces totalmente emplumadas no seu applets.

Hoje terminou de explorar applets e o awt aprendendo aproximadamente três conceitos.

Em primeiro lugar, aprendeu sobre janelas, as armações, cardápios, e diálogos, que lhe permitem criar uma armação para o seu applets-ou permitem às suas aplicações de Java aproveitar-se de características applet.

Em segundo lugar, tinha uma breve introdução para a ligação em rede de Java por algumas classes no pacote de java.net. A ligação em rede de Applet inclui coisas como simples como indicação do browser a outra página do interior do seu applet, mas também pode incluir arquivos recuperam da Web usando protocolos de Web padrão (http, ftp, e assim por diante). Para capacidades de ligação em rede mais promovidas, Java fornece interfaces de tomada básicas que podem usar-se para implementar muitos interações applets-client/server orientadas à rede básicas, sessões de conversa, e assim por diante.

Finalmente, terminou com as pequenas pelos petiscos características de Java awt e de applets que não se ajustou em nenhuma parte, inclusive showStatus(), fornecendo a informação sobre o seu applet, e comunicando-se entre múltiplo applets em uma página única.

Perguntas e Respostas

Q:
Quando crio janelas instantâneas, todos eles destacam-se com esta grande barra amarela que diz Warning: applet window. O que isto significa?
A:
O aviso é dizer-lhe (e os usuários do seu applet) que a janela que se expõe se gerou por um applet, e não pelo próprio browser. Isto é uma característica de segurança para impedir um programador applet de surgir uma janela que as mascaradas como uma janela do navegador e, por exemplo, pedem a usuários as suas senhas.

Não há nada que pode fazer para esconder ou obscurecer o aviso.

Q:
O que bom tem uma caixa de diálogo de arquivo se não puder ler ou escrever arquivos do sistema de arquivos local?
A:
Applets muitas vezes não pode ler ou escrever do sistema de arquivos local (dependendo do browser), mas porque pode usar componentes awt em aplicações de Java bem como applets, a caixa de diálogo de arquivo também é muito útil para eles.
Q:
Como posso imitar uma submissão de forma de HTML em Java applet?
A:
Atualmente, os applets fazem difícil fazer isto. O melhor (e o caminho mais fácil) deve usar a notação de GET para conseguir que o browser submeta os conteúdos de forma para você.

http://www.blah.com/cgi-bin/myscript?foo=1&bar=2&name=Laura

Como a entrada de forma se codifica no URL, pode escrever que a Java applet imite uma forma, se introduza do usuário, e logo construir um novo objeto de URL com os dados de forma incluídos no fim. Então somente o passo que URL ao browser usando getAppletContext().showDocument() e o browser submeterá a forma resulta ela mesma. Para formas simples, isto é tudo do qual precisa.

Q:
Como posso fazer a submissão de forma de POST?
A:
Terá de imitar o que um browser faz para enviar formas usando POST: Abra uma tomada ao servidor e envie os dados, que olham algo como isto (o formato exato determina-se pelo protocolo HTTP; isto é só um subconjunto dele):

PONHA NO CORREIO/cgi-bin/mailto.cgi HTTP/1.0
Tipo contente: application/x-www-form-urlencoded
Comprimento contente: 36
{os seus dados de forma codificados aqui}

Se o tenha feito direito, recobra a produção de forma de CGI do servidor. Então está à altura do seu applet para tratar aquela produção propriamente. Observe que se a produção estiver no HTML, realmente não há um modo de passar aquela produção ao browser que dirige o seu applet ainda. Esta capacidade pode terminar em futuros lançamentos de Java. Se devolver um URL, contudo, pode redirecionar o browser a isto URL.

Q:
showStatus() não trabalha no meu browser. Como posso dar a minha informação sobre posição de leitores?
A:
Como aprendeu na seção em showStatus(), se uns suportes de browser showStatus() estão à altura daquele browser. Se dever ter comportamento parecido à posição no seu applet, considerar a criação de uma etiqueta de posição no próprio applet que se atualiza com a informação tem de apresentar.
Q:
Tenho tentado comunicar-me entre dois applets na minha Página da Web usando métodos de getApplet() e o getAppletContext(). Os meus applets continuam caindo com erros de NullPointerException. O que isto significa?
A:
O mecanismo que descrevi para comunicar-me entre applets é como o Sol e a biblioteca de classe de Java dizem que se supõe que trabalhe. Contudo, como showStatus(), se um browser implementa aquele mecanismo, ou o implementa corretamente, depende daquele browser. A versão do Netscape antes 3.0 e Internet Explorer ambos tem problemas estranhos com a comunicação inter-applet.
Q:
Parece ao método de openStream() e as classes de Socket implementam tomadas TCP. Java apoia UDP (Protocolo de Datagrama de usuário, muitas vezes somente chamado datagrama) tomadas?
A:
JDK 1.0 fornece duas classes, DatagramSocket e DatagramPacket, que implementam tomadas UDP. A classe de DatagramSocket funciona de mesmo modo à classe de Socket. Use exemplos de DatagramPacket de cada pacote que envia ou recebe sobre a tomada.

Ver a documentação API do pacote de java.net de mais informação.