Baixe o app para aproveitar ainda mais
Prévia do material em texto
Interfaces gráficas Swing & AWT Componentes Caixas de diálogo Layouts Manipulação de aspectos visuais Manipulação de eventos Interfaces gráficas Introdução • Uma interface gráfica com usuário (graphical user interface — GUI) apresenta um mecanismo amigável ao usuário para interagir com um aplicativo. • Uma GUI dá ao aplicativo uma “aparência e comportamento” distintos e são construídas a partir de componentes GUI. • Um componente GUI é um objeto com que o usuário interage por meio do mouse, do teclado ou de outro formulário de entrada, como reconhecimento de voz por exemplo. GUI de exemplo Entrada/saída com JOptionPane • A maioria dos aplicativos que você usa diariamente utiliza janelas ou caixas de diálogo para interagir com o usuário. • Por exemplo, um programa de e-mail permite digitar e ler mensagens em uma janela que o programa fornece. • As caixas de diálogo são janelas em que programas exibem mensagens importantes para o usuário ou obtêm informações do usuário. • A classe JOptionPane do Java (pacote javax.swing) fornece caixas de diálogo pré-construídas tanto para entrada como para saída. Entrada/saída com JOptionPane Entrada/saída com JOptionPane Swing & AWT Visão geral de componentes Swing •Embora seja possível realizar entrada e saída usando os diálogos JOptionPane, a maioria dos aplicativos GUI exige interfaces com o usuário mais elaboradas. •Ao longo do curso iremos trabalhar com muitos componentes GUI que permitem aos desenvolvedores criar aplicações GUI robustas. Swing versus AWT • Nas versões anteriores do Java, GUIs eram construídas com componentes do Abstract Window Toolkit (AWT) no pacote java.awt. • Eles se pareciam com os componentes GUI nativos da plataforma em que um programa Java executa. • Às vezes, até a maneira como um usuário pode interagir com um componente AWT difere entre plataformas. Swing versus AWT • Os componentes GUI Swing permitem especificar uniformemente a aparência e comportamento para o aplicativo em todas as plataformas. • A maioria dos componentes Swing são componentes leves — eles são escritos, manipulados e exibidos completamente no Java. • Componentes AWT são componentes pesados, porque eles contam com sistema de janelas da plataforma local para determinar sua funcionalidade e sua aparência e comportamento. Modelo de desenvolvimento do Swing Modelo de desenvolvimento do Swing • Uma interface gráfica em Java é baseada em dois elementos: • Containers: servem para agrupar e exibir outros componentes; • Components: botões, labels, scrollbars, etc. Modelo de desenvolvimento do Swing • Dessa forma, todo programa que ofereça uma interface vai possuir pelo menos um container, que pode ser: • JFrame - janela principal do programa; • JDialog - janela para diálogos; • JApplet - janela para Applets ; Containers e componentes • Para construirmos uma interface gráfica em JAVA, adicionamos componentes (Botões, Menus, Textos, Tabelas, Listas, etc.) sobre a área da janela. • Por essa razão a área da janela é um container, ou seja, um elemento capaz de armazenar uma lista de componentes. Uma simples janela Uma simples janela JPanel • Para adicionarmos novos elementos ao nosso frame é necessário adicionar um container do tipo JPanel. • Nele podemos adicionar novos componentes que irão compor nossa GUI, como botões , campos de texto e etc. • O JPanel é um container genérico e visual, que trabalha em conjunto com o controle de layouts. Lista de vários componentes GUI JPanel JPanel Componentes Componentes JButton • Um botão destinado a executar uma ação. • Construtor: • JButton() – cria um botão vazio • JButton(String) – cria um botão com texto • Alguns métodos importantes: • setText(String) – altera o texto do botão JLabel • Um texto informativo que pode passar uma orientação ao usuário. • Construtor: • JLabel(String) – cria o label com o texto especificado • JLabel(String, int) – cria o label de texto especificando o alinhamento, que pode ser: SwingConstants.LEFT, SwingConstants.CENTER, SwingConstants.RIGHT • Alguns métodos importantes: • setText(String) – altera o texto. • getText() – retorna o texto atual. JTextField • Uma caixa onde o usuário pode informar um texto em uma linha. • Construtor: • JTextField(int) – cria o campo de texto com a largura especificada. • JTextField(String, int) – cria o campo de texto com um texto inicial e a largura especificada. • Alguns métodos importantes: • setText(String) – altera o texto. • getText() – retorna o texto atual. • getSelectedText() – retorna o texto selecionado pelo usuário. JPasswordField • Um campo de texto protegido. É uma subclasse de JTextField. • Construtor: • JPasswordField(int) – cria o campo de texto com a largura especificada. • Alguns métodos importantes: • setEchoChar(char) - define o caractere que aparece ao digitar um texto. JTextArea • Uma caixa onde o usuário pode informar várias linhas de texto. • Construtor: • JTextArea(int, int) – cria a área de texto especificando o número de linhas e de colunas. • JTextArea(String, int, int) – cria a área especificando o texto, o número de linhas e de colunas. JTextArea • Alguns métodos importantes: • setText(String) – altera o texto. • getText() – retorna o texto atual. • getSelectedText() – retorna o texto selecionado pelo usuário. • append(String) – adiciona um texto ao final do texto atual. • insert(String, int) – insere um texto na posição especificada. • setLineWrap(boolean) – ativa a quebra automática de linha. • setWrapStyleWord(boolean) – define se a quebra se dará por palavra ou por caractere JTextArea •OBS: • Um objeto do tipo JTextArea não apresenta, naturalmente, barras de rolagem. • Para tanto, é preciso instanciar outra classe, ou seja, criar um objeto da classe JScrollPane e associá-lo à área de texto. JScrollPane • Um tipo de painel que possibilita o uso de barras de rolagem. • Construtor: • JScrollPane(Component) – cria o painel contendo o componente especificado. • JScrollPane(Component, int, int) – cria o painel configurando as barras de rolagem vertical e horizontal. Deve-se usar: • ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER, • ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER JCheckBox • Caixa de seleção, permite selecionar ou não uma opção. • Construtor: • JCheckBox(String) – cria a caixa com o texto especificado • JCheckBox(String, boolean) – cria a caixa com o texto especificado e a opção de seleção (true/false) • Alguns métodos importantes: • setSelected(boolean) – altera o estado da caixa de seleção • isSelected() – retorna true se a caixa estiver marcada, e false se não estiver JRadioButton • Construtor: • JRadioButton(String) – cria a caixa com o texto especificado • JRadioButton(String, boolean) – cria a caixa com o texto especificado e a opção de seleção (true/false) • Alguns métodos importantes: • setSelected(boolean) – altera o estado da caixa de seleção • isSelected() – retorna true se a caixa estiver marcada, e false se não estiver JRadioButton • Componente semelhante ao JCheckBox, inclusive com os mesmos construtores e métodos. • A diferença é que um botão de opção pode ser agrupado a outros, tornando-o exclusivo dentro do grupo. Para isso, deve-se usar a classe ButtonGroup. • O que faz um objeto ButtonGroup ? Organiza um grupo de botões, mas ele mesmo não é exibido. Em seu lugar, os objetos individuais de JRadioButton são exibidos. JRadioButton • Exemplo ButtonGroup escolha = new ButtonGroup(); JRadioButton opcao1 = new JRadioButton(“Sim”); JRadioButton opcao2 = new JRadioButton(“Não”); JRadioButton opcao3 = new JRadioButton(“Talvez”); escolha.add(opcao1); escolha.add(opcao2); escolha.add(opcao3); container.add(opcao1); container.add(opcao2);container.add(opcao3); JComboBox • Uma caixa de combinação, da qual o usuário pode selecionar uma opção. • Construtor: • JComboBox() – cria a caixa de combinação • JComboBox(Object[]) – cria uma lista que contém um array de objetos (String, por exemplo) • Alguns métodos importantes: • addItem(Object) – adiciona um item à lista de opções • setEditable(boolean) – permite que o usuário digite uma opção • getItemAt(int) – retorna o item que está na posição especificada JComboBox • Alguns métodos importantes (Continuação): • getSelectedIndex() – retorna a posição do item atualmente selecionado • getSelectedItem() – retorna o texto do item atualmente selecionado • setSelectedIndex(int) – seleciona o item da posição especificada • setSelectedIndex(Object) – seleciona o objeto especificado na lista JList • Uma lista de opções que permite a seleção de mais de um item simultaneamente. • Construtor: • JList() – cria uma lista vazia • JList(Object[]) – cria uma lista que contém um array de objetos (String, por exemplo) • Alguns métodos importantes: • setListData(Object[]) – preenche ou altera os itens de uma lista • getSelectedValues() – retorna um array de objetos contendo os itens selecionados na lista JMenuBar & Jmenu • JMenubar • Uma implementação de uma barra de menu. Você pode adicionar objetos JMenu para a barra de menu para a construção do menu. • Jmenu • Uma janela pop-up contendo JMenuItens que é exibido quando o usuário seleciona um item no JMenuBar. Um Jmenu também pode conter Jseparators. Jseparator & JMenuItem • JSeparator • Fornece um componente de uso geral para a implementação de linhas divisórias. Mais comumente usado como um divisor entre os itens de menu que os divide em grupos lógicos. • JMenuItem • Uma implementação de um item em um menu. Um item de menu é essencialmente um botão em uma lista. Quando o usuário seleciona o botão, a ação associada ao item de menu é executado. JMenuBar JMenuBar barra = new JMenuBar(); JMenu m1 = new JMenu("Arquivo"); JMenuItem m11 = new JMenuItem("Novo"); JMenuItem m12 = new JMenuItem("Abrir"); JMenuItem m13 = new JMenuItem("Salvar"); JMenuItem m14 = new JMenuItem("Sair"); JMenu m2 = new JMenu("Ajuda"); JMenuItem m21 = new JMenuItem("Conteudo"); JMenuItem m22 = new JMenuItem("Sobre"); JMenuBar, Jmenu, JMenuItem m1.add(m11); m1.add(m12); m1.add(m13); m1.addSeparator(); m1.add(m14); m2.add(m21); m2.addSeparator(); m2.add(m22); barra.add(m1); barra.add(m2); janela.setJMenuBar(barra); Outros componentes Swing • Há diversos outros componentes Swing que podem ser úteis dependendo da aplicação. • Exemplos: JSlider, JProgressBar, JToolBar, JTabbedPane • https://docs.oracle.com/javase/8/docs/api/javax/swing/pac kage-summary.html https://docs.oracle.com/javase/8/docs/api/javax/swing/package-summary.html Caixas de diálogo Caixas de diálogo • Para pequenas mensagens ou questões ao usuário, existem caixas de diálogo padrão, implementadas pela classe JOptionPane. • Os métodos que criam as caixas de diálogo são estáticos, por isso a classe não precisa ser instanciada para chamá-los. Caixas de diálogo • Existem quatro caixas de diálogo padrão: • ConfirmDialog • InputDialog • MessageDialog • OptionDialog ConfirmDialog • JOptionPane.showConfirmDialog(Component, Object, String, int, int) • Component: indica qual é o container que chama a caixa de diálogo, pode ser null. • Object: a mensagem a ser exibida. Pode ser uma String ou uma imagem, por exemplo. • String: opcional. Título da janela. ConfirmDialog • int: opcional. Botões que serão mostrados: • JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.YES_NO_OPTION • int: opcional. Tipo da caixa de diálogo (ícone mostrado): • JOptionPane.ERROR_MESSAGE, JOptionPane.INFORMATION_MESSAGE, JOptionPane.PLAIN_MESSAGE, JOptionPane.QUESTION_MESSAGE, JOptionPane.WARNING_MESSAGE ConfirmDialog • O retorno da função é um valor inteiro baseado na opção escolhida pelo usuário, que pode ser: JOptionPane.YES_OPTION (0), JOptionPane.NO_OPTION (1) ou JOptionPane.CANCEL_OPTION (2) InputDialog • JOptionPane.showInputDialog(Component, Object, String, int) • Component: indica qual é o container que chama a caixa de diálogo, pode ser null. • Object: a mensagem a ser exibida. Pode ser uma String ou uma imagem, por exemplo. • String: opcional. Título da janela. • int: opcional. Tipo da caixa de diálogo (ícone mostrado), mesmas opções do showConfirmDialog. InputDialog • O retorno da função é uma String contendo o texto digitado pelo usuário. • Caso o usuário clique em Cancel ou feche a janela, é retornado null. MessageDialog • JOptionPane.showMessageDialog(Component, Object, String, int) • Component: indica qual é o container que chama a caixa de diálogo, pode ser null. • Object: a mensagem a ser exibida. Pode ser uma String ou uma imagem, por exemplo. • String: opcional. Título da janela. • int: opcional. Tipo da caixa de diálogo (ícone mostrado), mesmas opções do showConfirmDialog e showInputDialog. • O método showMessageDialog não retorna valor. OptionDialog • JOptionPane.showOptionDialog(Component, Object, String, int, int, Icon, Object[], Object) • Component: indica qual é o container que chama a caixa de diálogo, pode ser null. • Object: a mensagem a ser exibida. Pode ser uma String ou uma imagem, por exemplo. • String: título da janela. • int: botões que serão mostrados, mesmas opções do showConfirmDialog, ou 0 (zero) se outros botões forem usados. OptionDialog • int: ícone da caixa de diálogo, mesmas opções do showConfirmDialog, ou 0 (zero) se for usado outro ícone. • Icon: ícone a ser usado se a opção anterior for 0. • Object[] – array contendo os textos dos botões, caso não seja usado um dos padrões. • Object – um elemento da array indicando qual é o botão se seleção padrão. • O retorno da função é um inteiro, indicando a posição do array relativa ao botão selecionado. Exercício • Utilizando o swing, desenha a janela abaixo: Layouts Gerenciadores de Layout • Uma vez aprendido a criar e exibir componentes, é necessário posicioná-los e dimensioná-los. • Para isso foi criado um conjunto de gerenciadores de layout para realizar o calculo de alinhamento, posicionamento e dimensionamento, independentes da plataforma de execução: • FlowLayout • GridLayout • BorderLayout • GridBagLayout • Layouts compostos Gerenciadores de Layout • Todos os gerenciadores de layout implementam a interface LayoutManager que faz parte do pacote java.awt. • Existe o método setLayout da classe Container que aceita um objeto que implementa a interface LayoutManager como um argumento. FlowLayout • Com o gerenciador de layout FlowLayout, os componentes são posicionados em um contêiner da esquerda para a direita na ordem em que eles são adicionados. • Gerenciador de layout padrão do JPanel. • Quando componentes não cabem na linha atual, eles continuam a ser exibidos da esquerda para a direita na linha seguinte. • Se o contêiner for redimensionado, um FlowLayout reorganiza os componentes, possivelmente com mais ou menos linhas com base na nova largura do contêiner. FlowLayout FlowLayout GridLayout • Divide o contêiner em uma grade de modo que os componentes podem ser colocados nas linhas e colunas. • Cada Component em um GridLayout tem a mesma largura e altura. • Os componentes são adicionados a um GridLayout iniciando a célula na parte superior esquerda da grade e prosseguindo da esquerda para a direita até a linha estar cheia. • Então, o processo continua da esquerda para a direita na próxima linha da grade e assim por diante. GridLayout GridLayout BorderLayout • O BorderLayout é capaz de posicionar até cinco componentes em posições específicas do container. • Cada posição é representada por uma das constantes definidas na classe BorderLayout, sendo elas: • NORTH, SOUTH, EAST, WEST e CENTER • O tamanho original dos componentes é afetado quando há um redimensionamentoda janela. • O container pode receber somente um componente por área. GridBagLayout • É um gerenciador de layout que divide o contêiner em uma grade de modo que os componentes podem ser colocados nas linhas e colunas. • É um dos mais flexíveis e ao mesmo tempo o mais complexo dos layouts. • É necessário um planejamento mais cuidadoso durante o desenho da interface. • Cada elemento precisa ter: • Uma posição inicial e uma final; • Um tamanho e uma escala; • Um alinhamento e um preenchimento; GridBagLayout • Superficialmente é semelhante ao GridLayout, no entanto apresenta 3 diferenças significativas: • As colunas e linhas podem ser de diferentes tamanhos; • Um componente não está confinado a uma única célula, podendo ocupar uma área retangular de qualquer tamanho dentro do container, desde que não se sobreponha a outros componentes; • É possível indicar a posição de cada componente, não sendo necessário adicionar os componentes por uma ordem específica. GridBagLayout • Através da classe GridBagConstraints conseguimos controlar o posicionamento dos componentes. • A classe GridBagConstraints possui onze atributos de instância, e dependendo do valor atribuído a cada um deles, o componente se organiza de uma maneira diferente. • Segue uma breve descrição de alguns destes atributos: GridBagLayout Atributo Descrição gridx Indica a coluna onde o objeto será posicionado. gridy Indica a linha onde o objeto será posicionado. gridwidth Indica o número de colunas a serem ocupadas pelo objeto. gridheight Indica o número de linhas a serem ocupadas pelo objeto. weightx Especifica como distribuir o espaço horizontal extra quando o contêiner for redimensionado. O valor 0 (zero) indica que o objeto não vai ser expandido automaticamente GridBagLayout Atributo Descrição weighty Especifica como distribuir o espaço vertical extra quando o contêiner for redimensionado. O valor 0 (zero) indica que o objeto não vai ser expandido automaticamente. fill Utilizamos esse atributo quando a área referente ao componente é menor do que o necessário para que ele caiba dentro dela. anchor Utilizamos esse atributo quando o tamanho do componente é menor que a área em que ele foi inserido. GridBagLayout GridBagLayout Layout Composto • A classe JPanel é derivada de Container e pode ser usada para agrupar Componentes de maneira a criar Layouts compostos. • Por ser também um Container, um JPanel pode ter seu Layout próprio. • Como um Container pode conter outros Containers, podemos agrupar vários Componentes em um JPanel e passar a considerá-los como um único Componente para efeitos de layout. • Dessa forma, utilizamos um Container com vários JPanel, cada um com seu layout. Layout Composto Layout Composto Manipulação de aspectos visuais Manipulação de aspectos visuais • Todos os componentes originados da superclasse JComponent possuem um conjunto de métodos que permite controlar aspectos visuais como fonte, cursor, borda, cor de fonte e cor de fundo • public void setCursor (javax.swing.Cursor cursor) • public void setBackground (javax.swing.Color color) • public void setForeground (javax.swing.Color color) • public void setEnabled (boolean enabled) • public void setFont (javax.awt.Font font) • public void setBorder (javax.swing.border.Border border) • public void setToolTipText (String text) Cursor • public void setCursor (java.awt.Cursor cursor) • Permite trocar o cursor quando esse componente está em foco; • Exemplos: • Cursor hand = new Cursor(Cursor.HAND CURSOR); • botao.setCursor(hand); Background • public void setBackground (java.awt.Color color) • Permite trocar a cor de fundo do componente; • Exemplos • setBackground(new Color(192, 192, 192)); • setBackground(Color.BLUE); Foreground • public void setForeground (java.awt.Color color) • Permite trocar a cor de frente do componente; • Exemplos: • setForeground(Color.black); Enable • public void setEnabled (boolean enabled) • Permite habilitar ou desabilitar o componente; • Exemplos • setEnable(false); Font • Public void setFont (java.awt.Font font) • Permite escolher uma fonte para o componente • Exemplos: • Font arialBold = new Font("Arial", Font.BOLD, 12); • areaTexto.setFont(arialBold); Border • public void setBorder (javax.swing.border.Border border) • Permite definir uma borda para o componente • Exemplos • Border borda = new LineBorder(Color.RED, 2); • barraStatus.setBorder(borda); ToolTipText • public void setToolTipText (String text) • Permite associar um texto de dica ao componente • Exemplos: • novo.setToolTipText("Cria um novo documento"); Manipulação de eventos Eventos • Na programação orientada a objetos, pode não haver uma ordem determinada de execução de um programa; • Janelas e interfaces gráficas não servem para nada sem os eventos; • Quando um usuário interage com os componentes da tela, estes geram eventos; • O tratamento desses eventos (o que fazer quando ocorrem) é feito por tratadores de eventos. Eventos • Exemplos de eventos: • Pressionar um botão; • Clicar com o mouse; • Arrastar uma janela; • Fechar uma janela; • Digitar um caractere. Ouvintes (Listeners) • O Swing trata eventos através de interfaces chamadas “ouvintes de eventos” (EventListener); • Quando um ouvinte é associado a um componente, ele passa a responder aos eventos ocorridos; • O sistema operacional (no caso do Java, a máquina virtual), monitora todas as ações que são executadas, seja pelo usuário ou por outros programas; • Quando um evento ocorre, ele “avisa” o ouvinte; Ouvintes (Listeners) • Os ouvintes de evento básicos são interfaces, todas contidas no pacote java.awt.event: • ActionListener – eventos de ação • AdjustmentListener – eventos de ajuste • FocusListener – eventos de foco • ItemListener – eventos de item • KeyListener – eventos do teclado • MouseListener – eventos do mouse • MouseMotionListener – eventos de movimento do mouse • TextListener – eventos de texto • WindowListener – eventos de janela Tratando eventos • Os eventos não são tratados automaticamente. Para fazer isso você deve seguir os seguintes passos: • Para cada componente de interface que você criou, decida quais são os eventos que você quer tratar (cada componente pode gerar um ou mais tipos de eventos); • Após, defina uma classe adicional no seu programa que seja capaz de tratar cada um desses eventos; Tratando eventos • Essa classe, tratadora de eventos, deve implementar a interface correspondente aos eventos que deverão ser tratados; • Finalmente, crie objetos que sejam do tipo da classe tratadora de eventos que você definiu e depois diga para cada componente, qual é o objeto que trata seus eventos; Métodos de adição de tratadores de eventos • Para cada componente que você deseja tratar eventos, você deve criar e adicionar o tratador de eventos correspondente. • addWindowListener(tratador_de_eventos) - adiciona um tratador de eventos de janela; • addActionListener(tratador_de_eventos) - adiciona um tratador de eventos gerados por ações em componentes (geralmente utilizado em botões); Métodos de adição de tratadores de eventos • addMouseListener(tratador_de_eventos) - adiciona um tratador de eventos gerados pelo movimento do mouse; • addMouseMotionListener(tratador_de_eventos) -adiciona um tratador de eventos gerados por ações do mouse; • addKeyListener(tratador_de_eventos) - adiciona um tratador de eventos gerados pelo teclado; Observação • A diferença entre um Listener e um Adapter é que o primeiro é uma interface, e você deve implementar (implements) todos os seus métodos. • Já o segundo é uma classe-pai pronta, e você pode redefinir somente os métodos para os eventos que lhe interessam. ActionListener public interface ActionListener extends EventListener { public void actionPerformed(ActionEvent e); } MouseListener public interface MouseListener extends EventListener { public void mouseClicked(MouseEvent e); publicvoid mousePressed(MouseEvent e); public void mouseReleased(MouseEvent e); public void mouseEntered(MouseEvent e); public void mouseExited(MouseEvent e); } KeyListener public interface KeyListener extends EventListener { public void keyTyped(KeyEvent e); public void keyPressed(KeyEvent e); public void keyReleased(KeyEvent e); } • Para determinar a tecla associada ao evento, usa-se o método getKeyChar() no objeto e (KeyEvent). WindowListener public interface WindowListener extends EventListener { public void windowOpened(WindowEvent e); public void windowClosing(WindowEvent e); public void windowClosed(WindowEvent e); public void windowIconified(WindowEvent e); public void windowDeiconified(WindowEvent e); public void windowActivated(WindowEvent e); public void windowDeactivated(WindowEvent e); } MouseMotionListener public interface MouseMotionListener extends EventListener{ public void mouseDragged(MouseEvent e); public void mouseMoved(MouseEvent e); } • Alguns métodos que podem ser usados no objeto e MouseEvent) são: • int getClickCount() – retorna quantas vezes o mouse foi clicado; • Point getPoint() – retorna as coordenadas x,y dentro do componente onde ocorreu o evento do mouse; • int getX() – retorna a posição x; • int getY() – retorna a posição y; FocusListener public interface FocusListener extends EventListener { public void focusGained(FocusEvent e); public void focusLost(FocusEvent e); } TextListener public interface TextListener extends EventListener { public void textValueChanged(TextEvent e); } Referências • DEITEL, H. M.; DEITEL, P. J. Java: Como programar 10a. ed. Rio de Janeiro: Pearson, 2017. • SANTOS, Fabiano. Linguagens de programação Rio de janeiro: SESES, 2015. • SANTOS, Fabiano. Programação I. Rio de janeiro: SESES, 2017.
Compartilhar