diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF new file mode 100644 index 0000000..37197ef --- /dev/null +++ b/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: Main + diff --git a/src/Main.java b/src/Main.java index 025ed04..4a62ba4 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,106 +1,209 @@ import editores.Editor; +import editores.EditorLinha; +import models.Botao; import views.Modo; import views.Paleta; import views.Quadro; import views.Reproduzivel; import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.border.CompoundBorder; +import javax.swing.border.LineBorder; +import javax.swing.filechooser.*; +import javax.swing.filechooser.FileFilter; +import java.awt.*; import java.awt.event.*; +import java.awt.image.BufferedImage; +import java.io.*; +import java.util.ArrayList; public class Main implements MouseListener, MouseMotionListener, ActionListener { static Quadro quadro; static Paleta paleta; static Modo modo; + static JFileChooser fc; + static JFrame f; + static JToolBar toolbar; static Reproduzivel figuraSelecionada; + static final String NEW = "NEW"; + static final String SAVE = "SAVE"; + static final String OPEN = "OPEN"; + static final String EXIT = "EXIT"; + public static void main(String[] argv) { - JFrame f = new JFrame(); + f = new JFrame(); + fc = new JFileChooser(); + fc.setMultiSelectionEnabled(false); + fc.setFileFilter(new FileFilter() { + @Override + public boolean accept(File f) { + return f.getName().endsWith(".sim1"); + } + + @Override + public String getDescription() { + return "Simulador de Circuitor (.sim1)"; + } + }); + fc.setAcceptAllFileFilterUsed(false); + f.setLayout(new BorderLayout()); quadro = new Quadro(); modo = new Modo(); - paleta = new Paleta(quadro); - f.setContentPane(quadro); + paleta = new Paleta(quadro, modo); JMenuBar barra = new JMenuBar(); f.setJMenuBar(barra); + Main main = new Main(); + JMenu guia; guia = new JMenu("Arquivo"); barra.add(guia); JMenuItem item; - item = new JMenuItem("Sair"); - item.addActionListener(new Main()); - guia.add(item); - - guia = new JMenu("Paleta"); - barra.add(guia); - item = new JMenuItem("Porta AND"); - item.setActionCommand(Paleta.AND); - item.addActionListener(paleta); + item = new JMenuItem("Novo"); + item.setActionCommand(NEW); + item.addActionListener(main); guia.add(item); - item = new JMenuItem("Porta OR"); - item.setActionCommand(Paleta.OR); - item.addActionListener(paleta); + item = new JMenuItem("Abrir"); + item.setActionCommand(OPEN); + item.addActionListener(main); guia.add(item); - item = new JMenuItem("Porta XOR"); - item.setActionCommand(Paleta.XOR); - item.addActionListener(paleta); + item = new JMenuItem("Salvar"); + item.setActionCommand(SAVE); + item.addActionListener(main); guia.add(item); - item = new JMenuItem("Porta NOT"); - item.setActionCommand(Paleta.NOT); - item.addActionListener(paleta); + item = new JMenuItem("Sair"); + item.setActionCommand(EXIT); + item.addActionListener(main); guia.add(item); - item = new JMenuItem("Porta NAND"); - item.setActionCommand(Paleta.NAND); - item.addActionListener(paleta); - guia.add(item); + toolbar = new JToolBar(); + toolbar.setOrientation(JToolBar.VERTICAL); + JButton botao; + f.add(toolbar, BorderLayout.WEST); + f.add(new JScrollPane( + quadro, + JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, + JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED + ), BorderLayout.CENTER, 1); - item = new JMenuItem("Porta NOR"); - item.setActionCommand(Paleta.NOR); - item.addActionListener(paleta); - guia.add(item); - item = new JMenuItem("Porta NXOR"); - item.setActionCommand(Paleta.NXOR); - item.addActionListener(paleta); - guia.add(item); + botao = new JButton("Porta AND"); + botao.setActionCommand(Paleta.AND); + botao.addActionListener(paleta); + toolbar.add(botao); - item = new JMenuItem("Conector"); - item.setActionCommand(Paleta.LINHA); - item.addActionListener(paleta); - guia.add(item); + botao = new JButton("Porta OR"); + botao.setActionCommand(Paleta.OR); + botao.addActionListener(paleta); + toolbar.add(botao); - guia = new JMenu("Modo"); - barra.add(guia); + botao = new JButton("Porta XOR"); + botao.setActionCommand(Paleta.XOR); + botao.addActionListener(paleta); + toolbar.add(botao); - item = new JMenuItem("Criar"); - item.setActionCommand(Modo.CRIAR); - item.addActionListener(modo); - guia.add(item); + botao = new JButton("Porta NOT"); + botao.setActionCommand(Paleta.NOT); + botao.addActionListener(paleta); + toolbar.add(botao); - item = new JMenuItem("Editar"); - item.setActionCommand(Modo.EDITAR); - item.addActionListener(modo); - guia.add(item); + botao = new JButton("Porta NAND"); + botao.setActionCommand(Paleta.NAND); + botao.addActionListener(paleta); + toolbar.add(botao); - item = new JMenuItem("Apagar"); - item.setActionCommand(Modo.APAGAR); - item.addActionListener(modo); - guia.add(item); + botao = new JButton("Porta NOR"); + botao.setActionCommand(Paleta.NOR); + botao.addActionListener(paleta); + toolbar.add(botao); + + botao = new JButton("Porta NXOR"); + botao.setActionCommand(Paleta.NXOR); + botao.addActionListener(paleta); + toolbar.add(botao); + + botao = new JButton("Conector"); + botao.setActionCommand(Paleta.LINHA); + botao.addActionListener(paleta); + toolbar.add(botao); + + botao = new JButton("Botão"); + botao.setActionCommand(Paleta.BOTAO); + botao.addActionListener(paleta); + toolbar.add(botao); f.setVisible(true); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(800, 600); f.setTitle("Simulador de Circuitos"); desenhar(); + for(Component c: toolbar.getComponents()) { + botao = (JButton) c; + botao.setBackground(null); + } } - public void actionPerformed(ActionEvent e){ - System.exit(0); //sai da aplicação com o código de status zero + public void actionPerformed(ActionEvent e) { + String command = e.getActionCommand(); + if (command.equals(EXIT)) { + System.exit(0); //sai da aplicação com o código de status zero + } + else if (command.equals(OPEN)) { + int returnVal = fc.showOpenDialog(f); + if (returnVal == JFileChooser.APPROVE_OPTION) { + File file = fc.getSelectedFile(); + FileInputStream fi; + ObjectInputStream is; + ArrayList q; + try { + fi = new FileInputStream(file); + is = new ObjectInputStream(fi); + q = (ArrayList) is.readObject(); + fi.close(); + } catch (IOException e1) { + JOptionPane.showMessageDialog(null, "Arquivo inválido!"); + return; + } catch(ClassNotFoundException e2) { + e2.printStackTrace(); + return; + } + quadro.setFigs(q); + } + } else if(command.equals(SAVE)) { + int returnVal = fc.showSaveDialog(f); + if (returnVal == JFileChooser.APPROVE_OPTION) { + File file = fc.getSelectedFile(); + if(!file.getAbsolutePath().endsWith(".sim1")) { + file = new File(file.getAbsolutePath()+".sim1"); + } + FileOutputStream fo; + ObjectOutputStream os; + try { + fo = new FileOutputStream(file); + os = new ObjectOutputStream(fo); + os.writeObject(quadro.getFigs()); + os.flush(); + fo.close(); + } catch(FileNotFoundException e1) { + e1.printStackTrace(); + return; + } catch (IOException e2) { + e2.printStackTrace(); + return; + } + } + + } else if(command.equals(NEW)) { + quadro.getFigs().clear(); + quadro.repaint(); + } } static void desenhar() { @@ -110,49 +213,50 @@ static void desenhar() { } public void mouseClicked(MouseEvent e) { + int x = e.getX(); + int y = e.getY(); if (modo.estaCriando()) { - int x = e.getX(); - int y = e.getY(); Editor editor = Main.paleta.editor(); - if(editor == null){ - JOptionPane.showMessageDialog(null, "Selecione um componente no menu 'Paleta'!"); - - } else { - editor.clique(x, y); + if (editor != null) { + if (editor.clique(x, y)) { + modo.setaEditando(); + for(Component c: toolbar.getComponents()) { + JButton botao = (JButton) c; + botao.setBackground(null); + } + } + } + } else if (modo.estaEditando()) { + figuraSelecionada = Main.quadro.pegaObjetoEm(x, y); + if (figuraSelecionada instanceof Botao) { + figuraSelecionada.calcula(); } } } public void mousePressed(MouseEvent e) { - if (modo.estaEditando()) { - int x = e.getX(); - int y = e.getY(); - figuraSelecionada = Main.quadro.pegaObjetoEm(x, y); - if(figuraSelecionada == null) { - JOptionPane.showMessageDialog(null, "Selecione um componente e arraste!"); - } - else { - figuraSelecionada.selecionaPonto(x, y); - } + if (modo.estaCriando()) { + return; } - else if(modo.estaApagando()){ - int x = e.getX(); - int y = e.getY(); - figuraSelecionada = Main.quadro.pegaObjetoEm(x, y); - if(figuraSelecionada == null) { - JOptionPane.showMessageDialog(null, "Selecione um componente para apagar"); - } - else { + int x = e.getX(); + int y = e.getY(); + figuraSelecionada = Main.quadro.pegaObjetoEm(x, y); + if (figuraSelecionada != null) { + if(e.getButton() == MouseEvent.BUTTON1) { + figuraSelecionada.selecionaPonto(x, y); + } else { quadro.removeFig(figuraSelecionada); quadro.repaint(); } + } } public void mouseReleased(MouseEvent e) { - if (modo.estaEditando() && figuraSelecionada != null) { - figuraSelecionada = null; + if (modo.estaCriando()) { + return; } + quadro.repaint(); } public void mouseEntered(MouseEvent e) { diff --git a/src/editores/Editor.java b/src/editores/Editor.java index 0c7bd10..31a1adb 100644 --- a/src/editores/Editor.java +++ b/src/editores/Editor.java @@ -1,6 +1,6 @@ package editores; public interface Editor { - void clique(int x, int y); + boolean clique(int x, int y); } diff --git a/src/editores/EditorAnd.java b/src/editores/EditorAnd.java index 7b20f74..70c3a03 100644 --- a/src/editores/EditorAnd.java +++ b/src/editores/EditorAnd.java @@ -1,19 +1,21 @@ package editores; -import views.*; -import models.*; - -import javax.swing.*; +import models.Ponto; +import views.FigAND; +import views.Quadro; public class EditorAnd extends EditorPortaLogica { - public EditorAnd(Quadro quadro){ + public EditorAnd(Quadro quadro) { super(quadro); - } - public void clique(int x, int y){ + } + + public boolean clique(int x, int y) { FigAND and = new FigAND(new Ponto(x, y)); - if(this.continuaInsercao(and)){ + if (this.continuaInsercao(and)) { this.quadro.addFig(and); this.quadro.repaint(); + return true; } - } + return false; + } } diff --git a/src/editores/EditorBotao.java b/src/editores/EditorBotao.java new file mode 100644 index 0000000..ff2db15 --- /dev/null +++ b/src/editores/EditorBotao.java @@ -0,0 +1,22 @@ +package editores; + +import models.Ponto; +import views.FigAND; +import views.FigBotao; +import views.Quadro; + +public class EditorBotao extends EditorPortaLogica { + public EditorBotao(Quadro quadro) { + super(quadro); + } + + public boolean clique(int x, int y) { + FigBotao botao = new FigBotao(new Ponto(x, y)); + if (this.continuaInsercao(botao)) { + this.quadro.addFig(botao); + this.quadro.repaint(); + return true; + } + return false; + } +} diff --git a/src/editores/EditorLinha.java b/src/editores/EditorLinha.java index 4c8583a..c036e73 100644 --- a/src/editores/EditorLinha.java +++ b/src/editores/EditorLinha.java @@ -2,101 +2,120 @@ import models.*; import views.FigLinha; -import views.Modo; import views.Quadro; import views.Reproduzivel; import javax.swing.*; -public class EditorLinha implements Editor{ +public class EditorLinha implements Editor { private Quadro quadro; private FigLinha linha; private int nEstado = 0; + public EditorLinha(Quadro quadro) { this.quadro = quadro; } - public void clique(int x, int y){ + private boolean verificaClique(Circulo circ, int x, int y) { + boolean match = false; + int margin = 5; + for(int xVerify=x-margin; xVerify <= (x+margin); xVerify++) { + for(int yVerify=y-margin; yVerify <= (y+margin); yVerify++) { + if(match) { + break; + } + match = circ.contemPonto(xVerify, yVerify); + } + } + return match; + } + public boolean clique(int x, int y) { Circulo circulo = null; Reproduzivel figura = this.quadro.pegaObjetoEm(x, y); - if(nEstado == 0) { + if (nEstado == 0) { linha = new FigLinha(); this.quadro.addFig(linha); - if(figura == null) { + if (figura == null) { JOptionPane.showMessageDialog(null, "Selecione um ponto em um conector ou saida em uma porta logica!"); - return; - } - else if (figura instanceof PortaLogica) { // Se o objeto selecionado for uma PortaLogica... + return false; + } else if (figura instanceof PortaLogica) { // Se o objeto selecionado for uma PortaLogica... PortaLogica porta = (PortaLogica) figura; Saida[] saidas = porta.pegaSaidas(); - for(int i=0; i < saidas.length; i++){ - if(saidas[i].contemPonto(x, y)) { + for (int i = 0; i < saidas.length; i++) { + if (this.verificaClique(saidas[i], x, y)) { circulo = saidas[i]; break; } } if (circulo == null) { JOptionPane.showMessageDialog(null, "Selecione a saida da porta logica!"); - return; + return false; } - } - else if(figura instanceof Linha) { // Se o objeto selecionado for uma Linha... - Linha linha = (Linha) figura; - Circulo[] pontos = linha.pontos(); - for(int i=0; i 1) { - nEstado = 0; - } - else { + return false; + } else if (linha.npontos() > 1) { + porta.conectaEntrada(linha); + linha.conectaSaida(porta); + linha.addPonto(circulo); + this.quadro.repaint(); + return true; + } else { JOptionPane.showMessageDialog(null, "Por favor, adicione pelo menos mais um ponto antes de conectar este cabo diretamente a uma porta lógica!"); - return; + return false; } - } - else if(figura instanceof Linha) { + + } else if (figura instanceof Linha) { Linha linhaSelecionada = (Linha) figura; Circulo[] pontos = linhaSelecionada.pontos(); - for(int i=0; i 1) { - nEstado = 0; - } - else { + if (linha.npontos() > 1) { + linhaSelecionada.conectaEntrada(linha); + linha.conectaSaida(linhaSelecionada); + linha.addPonto(circulo); + this.quadro.repaint(); + return true; + } else { JOptionPane.showMessageDialog(null, "Por favor, adicione pelo menos mais um ponto antes de conectar este cabo diretamente a uma outro cabo!"); - return; + return false; } } linha.addPonto(circulo); } this.quadro.repaint(); + return false; } } diff --git a/src/editores/EditorNOR.java b/src/editores/EditorNOR.java index ccc8f50..bfa7b9c 100644 --- a/src/editores/EditorNOR.java +++ b/src/editores/EditorNOR.java @@ -1,20 +1,22 @@ package editores; -import views.*; -import models.*; - -import javax.swing.*; +import models.Ponto; +import views.FigNOR; +import views.Quadro; public class EditorNOR extends EditorPortaLogica { - public EditorNOR(Quadro quadro){ - super(quadro); - } - public void clique(int x, int y){ + public EditorNOR(Quadro quadro) { + super(quadro); + } + + public boolean clique(int x, int y) { FigNOR nand = new FigNOR(new Ponto(x, y)); - if(this.continuaInsercao(nand)){ + if (this.continuaInsercao(nand)) { this.quadro.addFig(nand); this.quadro.repaint(); + return true; } - } + return false; + } } \ No newline at end of file diff --git a/src/editores/EditorNOT.java b/src/editores/EditorNOT.java index 2e06aa8..12ff3eb 100644 --- a/src/editores/EditorNOT.java +++ b/src/editores/EditorNOT.java @@ -1,17 +1,21 @@ package editores; -import views.*; -import models.*; +import models.Ponto; +import views.FigNOT; +import views.Quadro; public class EditorNOT extends EditorPortaLogica { - public EditorNOT(Quadro quadro){ - super(quadro); - } - public void clique(int x, int y){ + public EditorNOT(Quadro quadro) { + super(quadro); + } + + public boolean clique(int x, int y) { FigNOT not = new FigNOT(new Ponto(x, y)); - if(this.continuaInsercao(not)) { + if (this.continuaInsercao(not)) { this.quadro.addFig(not); this.quadro.repaint(); + return true; } - } + return false; + } } \ No newline at end of file diff --git a/src/editores/EditorNXOR.java b/src/editores/EditorNXOR.java index 2f0bd7b..c6085b7 100644 --- a/src/editores/EditorNXOR.java +++ b/src/editores/EditorNXOR.java @@ -1,17 +1,21 @@ package editores; -import views.*; -import models.*; +import models.Ponto; +import views.FigNXOR; +import views.Quadro; public class EditorNXOR extends EditorPortaLogica { - public EditorNXOR(Quadro quadro){ - super(quadro); - } - public void clique(int x, int y){ + public EditorNXOR(Quadro quadro) { + super(quadro); + } + + public boolean clique(int x, int y) { FigNXOR nxor = new FigNXOR(new Ponto(x, y)); - if(this.continuaInsercao(nxor)) { + if (this.continuaInsercao(nxor)) { this.quadro.addFig(nxor); this.quadro.repaint(); + return true; } - } + return false; + } } \ No newline at end of file diff --git a/src/editores/EditorNand.java b/src/editores/EditorNand.java index 700475f..4f8441e 100644 --- a/src/editores/EditorNand.java +++ b/src/editores/EditorNand.java @@ -1,19 +1,21 @@ package editores; -import views.*; -import models.*; - -import javax.swing.*; +import models.Ponto; +import views.FigNAND; +import views.Quadro; public class EditorNand extends EditorPortaLogica { - public EditorNand(Quadro quadro){ + public EditorNand(Quadro quadro) { super(quadro); } - public void clique(int x, int y){ - FigNAND nand = new FigNAND(new Ponto(x,y)); - if(this.continuaInsercao(nand)){ + + public boolean clique(int x, int y) { + FigNAND nand = new FigNAND(new Ponto(x, y)); + if (this.continuaInsercao(nand)) { this.quadro.addFig(nand); this.quadro.repaint(); + return true; } + return false; } } \ No newline at end of file diff --git a/src/editores/EditorOR.java b/src/editores/EditorOR.java index 9185c9d..39a4888 100644 --- a/src/editores/EditorOR.java +++ b/src/editores/EditorOR.java @@ -1,18 +1,22 @@ package editores; -import views.*; -import models.*; +import models.Ponto; +import views.FigOR; +import views.Quadro; -public class EditorOR extends EditorPortaLogica{ - public EditorOR(Quadro quadro){ - super(quadro); - } - public void clique(int x, int y){ +public class EditorOR extends EditorPortaLogica { + public EditorOR(Quadro quadro) { + super(quadro); + } + + public boolean clique(int x, int y) { FigOR or = new FigOR(new Ponto(x, y)); - if(this.continuaInsercao(or)) { + if (this.continuaInsercao(or)) { this.quadro.addFig(or); this.quadro.repaint(); + return true; } - } + return false; + } } \ No newline at end of file diff --git a/src/editores/EditorPortaLogica.java b/src/editores/EditorPortaLogica.java index 19174f1..ab9e5ce 100644 --- a/src/editores/EditorPortaLogica.java +++ b/src/editores/EditorPortaLogica.java @@ -7,21 +7,23 @@ public abstract class EditorPortaLogica implements Editor { protected Quadro quadro; + public EditorPortaLogica(Quadro quadro) { this.quadro = quadro; } + protected boolean colideCom(PortaLogica porta) { - return this.quadro.pegaObjetoEm(porta.x(), porta.y()) != null + return this.quadro.pegaObjetoEm(porta.x(), porta.y()) != null || this.quadro.pegaObjetoEm(porta.x() + porta.largura(), porta.y()) != null || this.quadro.pegaObjetoEm(porta.x(), porta.y() + porta.altura()) != null || this.quadro.pegaObjetoEm(porta.x() + porta.largura(), porta.y() + porta.altura()) != null; } + protected boolean continuaInsercao(PortaLogica porta) { - if(this.colideCom(porta)){ + if (this.colideCom(porta)) { JOptionPane.showMessageDialog(null, "Não sobreponha esta porta lógica sob outra porta lógica ou cabo!"); return false; - } - else { + } else { return true; } } diff --git a/src/editores/EditorXor.java b/src/editores/EditorXor.java index c83222c..a6599e1 100644 --- a/src/editores/EditorXor.java +++ b/src/editores/EditorXor.java @@ -1,17 +1,21 @@ package editores; -import views.*; -import models.*; +import models.Ponto; +import views.FigXOR; +import views.Quadro; -public class EditorXor extends EditorPortaLogica{ - public EditorXor(Quadro quadro){ +public class EditorXor extends EditorPortaLogica { + public EditorXor(Quadro quadro) { super(quadro); } - public void clique(int x, int y){ - FigXOR xor = new FigXOR(new Ponto(x,y)); - if(this.continuaInsercao(xor)) { + + public boolean clique(int x, int y) { + FigXOR xor = new FigXOR(new Ponto(x, y)); + if (this.continuaInsercao(xor)) { this.quadro.addFig(xor); this.quadro.repaint(); + return true; } + return false; } } \ No newline at end of file diff --git a/src/models/AND.java b/src/models/AND.java index dcfdb82..517d829 100644 --- a/src/models/AND.java +++ b/src/models/AND.java @@ -1,23 +1,49 @@ package models; -public class AND extends PortaLogica{ - public AND(Ponto superiorEsquerdo){ - super(superiorEsquerdo); - } - - public Entrada[] pegaEntradas() { - Entrada[] entradasAnd = new Entrada[2]; - entradasAnd[0] = new Entrada(this, 0, 13); - entradasAnd[1] = new Entrada(this, 0, 39); - return entradasAnd; - } - public Saida[] pegaSaidas() { - Saida[] saidasAnd = new Saida[1]; - saidasAnd[0] = new Saida(this, 87, 26); - return saidasAnd; - } - - public int altura(){ +import views.Editavel; + +import java.util.ArrayList; +import java.util.List; + +public class AND extends PortaLogica { + public AND(Ponto superiorEsquerdo) { + super(superiorEsquerdo); + } + + public Entrada[] pegaEntradas() { + Entrada[] entradasAnd = new Entrada[2]; + entradasAnd[0] = new Entrada(this, 0, 13); + entradasAnd[1] = new Entrada(this, 0, 39); + return entradasAnd; + } + + public Saida[] pegaSaidas() { + Saida[] saidasAnd = new Saida[1]; + saidasAnd[0] = new Saida(this, 87, 26); + return saidasAnd; + } + + public void calcula() { + Sinal oldValor = this.valor; + this.valor = this.entradas.isEmpty() ? Sinal.DESATIVADO : Sinal.ATIVADO; + if (this.entradas.size() == 1) { + this.valor = Sinal.DESATIVADO; + return; + } + for(Editavel entrada: this.entradas) { + if (entrada.pegaValor() == Sinal.DESATIVADO) { + this.valor = Sinal.DESATIVADO; + break; + } + } + if (oldValor != this.valor) { + for(Editavel saida: this.saidas) { + saida.calcula(); + } + } + } + + public int altura() { return 53; } diff --git a/src/models/Botao.java b/src/models/Botao.java new file mode 100644 index 0000000..8e13551 --- /dev/null +++ b/src/models/Botao.java @@ -0,0 +1,37 @@ +package models; + + +import views.Editavel; + +public class Botao extends PortaLogica +{ + public Botao(Ponto superiorEsquerdo) { + super(superiorEsquerdo); + } + + public Entrada[] pegaEntradas() { + Entrada[] entradasBotao = new Entrada[0]; + return entradasBotao; + } + + public Saida[] pegaSaidas() { + Saida[] saidasAnd = new Saida[1]; + saidasAnd[0] = new Saida(this, 10, 10, 5); + return saidasAnd; + } + + public void calcula() { + this.valor = this.valor == Sinal.ATIVADO ? Sinal.DESATIVADO : Sinal.ATIVADO; + for(Editavel saida: this.saidas) { + saida.calcula(); + } + } + + public int altura() { + return 20; + } + + public int largura() { + return 20; + } +} diff --git a/src/models/Circulo.java b/src/models/Circulo.java index c31655a..ee69c8f 100644 --- a/src/models/Circulo.java +++ b/src/models/Circulo.java @@ -2,38 +2,50 @@ import views.Editavel; -public class Circulo extends Ponto implements Editavel{ +public class Circulo extends Ponto { private int raio; private int xSel, ySel; public Circulo(int x, int y, int raio) { - super(x,y); + super(x, y); this.raio = raio; } public int diametro() { - return 2*raio; + return 2 * raio; } public int x0() { return this.x0(raio); } + public int y0() { return this.y0(raio); } public boolean contemPonto(int x, int y) { - return this.x0() <= x && (this.x0() + this.diametro()) >= x && this.y0() <= y && (this.y0()+this.diametro()) >= y; + int x0 = this.x0(); + int y0 = this.y0(); + int diametro = this.diametro(); + return x0 <= x && (x0 + diametro) >= x && y0 <= y && (y0 + diametro) >= y; } // Seleciona o retangulo public void selecionaPonto(int x, int y) { - this.xSel = x-this.x0(); - this.ySel = y-this.y0(); + this.xSel = x - this.x0(); + this.ySel = y - this.y0(); + } + + public int getXSel() { + return this.xSel + this.x(); + } + + public int getYSel() { + return this.ySel + this.y(); } // Move o ponto - public void movePara(int x, int y){ + public void movePara(int x, int y) { x -= this.xSel; y -= this.ySel; this.deslocarX(x - this.x0()); diff --git a/src/models/Entrada.java b/src/models/Entrada.java index 19e3323..15ab357 100644 --- a/src/models/Entrada.java +++ b/src/models/Entrada.java @@ -1,9 +1,10 @@ package models; -import models.Ponto; +import views.Editavel; public class Entrada extends Circulo { PortaLogica referencia; + Entrada(PortaLogica referencia, int x, int y) { super(x, y, 5); this.referencia = referencia; @@ -12,7 +13,8 @@ public class Entrada extends Circulo { public int x0() { return this.referencia.x() + super.x0(); } + public int y0() { - return this.referencia.y() + super.y0() ; + return this.referencia.y() + super.y0(); } } diff --git a/src/models/Linha.java b/src/models/Linha.java index 8bccb01..c0e92df 100644 --- a/src/models/Linha.java +++ b/src/models/Linha.java @@ -1,46 +1,130 @@ package models; -import models.Ponto; import views.Editavel; +import views.Reproduzivel; import java.util.ArrayList; import java.util.List; -public class Linha implements Editavel{ +public class Linha implements Editavel { private List pontos = new ArrayList(); private Circulo pontoSelecionado = null; // Guarda o ponto selecionado da linha. Ver se ha melhor forma de fazer isso. + protected List entradas = new ArrayList(); + protected List saidas = new ArrayList(); + protected Sinal valor = Sinal.DESATIVADO; - public int[] x() { - int[] x = new int[npontos()]; - for(int i=0, l = npontos(); i < l; i++) { - x[i] = pontos.get(i).x0(); + public void apaga() { + for(Editavel entrada: entradas) { + if (entrada instanceof PortaLogica) { + PortaLogica porta = (PortaLogica) entrada; + porta.desconectaSaida(this); + } else if(entrada instanceof Linha) { + Linha linha = (Linha) entrada; + linha.desconectaSaida(this); + } + } + for(Editavel saida: saidas) { + if (saida instanceof PortaLogica) { + PortaLogica porta = (PortaLogica) saida; + porta.desconectaEntrada(this); + } else if(saida instanceof Linha) { + Linha linha = (Linha) saida; + linha.desconectaEntrada(this); + } + } + } + + public void conectaSaida(Editavel saida) { + this.saidas.add(saida); + } + + public void conectaEntrada(Editavel entrada) { + this.entradas.add(entrada); + } + + public void desconectaSaida(Editavel saida) { + this.saidas.remove(saida); + } + + public void desconectaEntrada(Editavel entrada) { + this.entradas.remove(entrada); + } + + public void calcula(){ + Sinal oldValor = this.valor; + this.valor = Sinal.DESATIVADO; + for(Editavel entrada: this.entradas) { + if (entrada.pegaValor() == Sinal.ATIVADO) { + this.valor = Sinal.ATIVADO; + break; + } + } + if (oldValor != this.valor) { + for(Editavel saida: this.saidas) { + saida.calcula(); + } + } + } + + public Sinal pegaValor() { + return this.valor; + } + + public int altura() { + int altura = 0; + for(Circulo ponto: pontos) { + if(altura < ponto.y()+ponto.diametro()) { + altura = ponto.y()+ponto.diametro(); + } + } + return altura; + } + + public int largura() { + int largura = 0; + for(Circulo ponto: pontos) { + if(largura < ponto.x()+ponto.diametro()) { + largura = ponto.x()+ponto.diametro(); + } + } + return largura; + } + + public int x() { + int x = Integer.MAX_VALUE; + for(Circulo ponto: pontos) { + if(x > ponto.x()) { + x = ponto.x(); + } } return x; } - public int[] y() { - int[] y = new int[npontos()]; - for(int i=0, l = npontos(); i < l; i++) { - y[i] = pontos.get(i).y0(); + public int y() { + int y = Integer.MAX_VALUE; + for(Circulo ponto: pontos) { + if(y > ponto.y()) { + y = ponto.y(); + } } return y; } - public Circulo[] pontos(){ + public Circulo[] pontos() { Circulo[] resultado = new Circulo[pontos.size()]; - for(int i=0; i entradas = new ArrayList(); + protected List saidas = new ArrayList(); + protected Sinal valor; + + protected PortaLogica(Ponto superiorEsquerdo) { super(superiorEsquerdo); this.centralizaClique(); } + public void apaga() { + for(Editavel entrada: entradas) { + Linha linha = (Linha) entrada; + linha.desconectaSaida(this); + } + for(Editavel saida: saidas) { + Linha linha = (Linha) saida; + linha.desconectaEntrada(this); + } + } + + public void conectaSaida(Editavel saida) { + this.saidas.add(saida); + } + + public void conectaEntrada(Editavel entrada) { + if (this.entradas.size() >= this.pegaEntradas().length) { + JOptionPane.showMessageDialog(null, "Você não pode adicionar mais entradas a esta porta lógica"); + return; + } + this.entradas.add(entrada); + } + + public void desconectaSaida(Editavel saida) { + this.saidas.remove(saida); + } + + public void desconectaEntrada(Editavel entrada) { + this.entradas.remove(entrada); + } + + public abstract void calcula(); + + public Sinal pegaValor() { + return this.valor; + } + + // Porta logicas tambem tem entradas... public abstract Entrada[] pegaEntradas(); @@ -18,10 +67,10 @@ protected PortaLogica(Ponto superiorEsquerdo) { // E tambem altura.. abstract public int altura(); - // Desloca X e Y de forma que a porta logica apaerca exatamente no meio do clique do usuario + // Desloca X e Y de forma que a porta logica apareca exatamente no meio do clique do usuario protected void centralizaClique() { - int mediaAltura = this.altura()/2; - int mediaLargura = this.largura()/2; + int mediaAltura = this.altura() / 2; + int mediaLargura = this.largura() / 2; this.deslocarX(-(mediaLargura)); this.deslocarY(-(mediaAltura)); } diff --git a/src/models/Retangulo.java b/src/models/Retangulo.java index 2f7d4c6..d28569c 100644 --- a/src/models/Retangulo.java +++ b/src/models/Retangulo.java @@ -1,26 +1,28 @@ package models; -import views.Editavel; -import views.Selecionavel; +import java.io.Serializable; -public class Retangulo implements Editavel { +public class Retangulo implements Serializable { private Ponto ponto1, ponto2; private int xSel, ySel; // Usados para guardar o x e y selecionados. Ver se ha melhor forma de fazer isso. - public Retangulo(Ponto ponto1, Ponto ponto2){ + public Retangulo() {} + + public Retangulo(Ponto ponto1, Ponto ponto2) { this.ponto1 = ponto1; this.ponto2 = ponto2; } public Retangulo(Ponto superiorEsquerdo) { this.ponto1 = superiorEsquerdo; - this.ponto2 = new Ponto(superiorEsquerdo.x()+this.largura(), superiorEsquerdo.y()+this.altura()); + this.ponto2 = new Ponto(superiorEsquerdo.x() + this.largura(), superiorEsquerdo.y() + this.altura()); } - public void deslocarX(int val){ + public void deslocarX(int val) { ponto1.deslocarX(val); ponto2.deslocarX(val); } - public void deslocarY(int val){ + + public void deslocarY(int val) { ponto1.deslocarY(val); ponto2.deslocarY(val); } @@ -30,29 +32,37 @@ public int x() { } public int y() { - return this.ponto1.ysup(this.ponto2); + return this.ponto1.ysup(this.ponto2); } - public int largura(){ + public int largura() { return ponto1.distanciaX(ponto2); } - public int altura(){ + public int altura() { return ponto1.distanciaY(ponto2); } public boolean contemPonto(int x, int y) { - return this.x() <= x && (this.x() + this.largura()) >= x && this.y() <= y && (this.y()+this.altura()) >= y; + return this.x() <= x && (this.x() + this.largura()) >= x && this.y() <= y && (this.y() + this.altura()) >= y; } // Seleciona o retangulo public void selecionaPonto(int x, int y) { - this.xSel = x-this.x(); - this.ySel = y-this.y(); + this.xSel = x - this.x(); + this.ySel = y - this.y(); + } + + public int getXSel() { + return this.xSel + this.x(); + } + + public int getYSel() { + return this.ySel + this.y(); } // Move o ponto - public void movePara(int x, int y){ + public void movePara(int x, int y) { x -= this.xSel; y -= this.ySel; this.deslocarX(x - this.x()); diff --git a/src/models/Saida.java b/src/models/Saida.java index c34b389..103ec57 100644 --- a/src/models/Saida.java +++ b/src/models/Saida.java @@ -1,18 +1,25 @@ package models; -import models.Ponto; +import views.Editavel; public class Saida extends Circulo { PortaLogica referencia; + Saida(PortaLogica referencia, int x, int y) { super(x, y, 5); this.referencia = referencia; } + Saida(PortaLogica referencia, int x, int y, int raio) { + super(x, y, raio); + this.referencia = referencia; + } + public int x0() { return this.referencia.x() + super.x0(); } + public int y0() { - return this.referencia.y() + super.y0() ; + return this.referencia.y() + super.y0(); } } diff --git a/src/models/Sinal.java b/src/models/Sinal.java new file mode 100644 index 0000000..2209457 --- /dev/null +++ b/src/models/Sinal.java @@ -0,0 +1,8 @@ +package models; + +/** + * Created by fernando on 21/10/14. + */ +public enum Sinal { + ATIVADO, DESATIVADO; +} diff --git a/src/models/XOR.java b/src/models/XOR.java index 7f2d7f9..a62af75 100644 --- a/src/models/XOR.java +++ b/src/models/XOR.java @@ -1,8 +1,10 @@ package models; +import views.Editavel; + public class XOR extends PortaLogica { //private int numeroPortas; - public XOR(Ponto superiorEsquerdo){ + public XOR(Ponto superiorEsquerdo) { super(superiorEsquerdo); } @@ -13,17 +15,32 @@ public Entrada[] pegaEntradas() { return entradasXor; } - public Saida[] pegaSaidas(){ + public void calcula() { + Sinal oldValor = this.valor; + this.valor = Sinal.DESATIVADO; + if (this.entradas.size() == 2) { + Editavel entrada1 = this.entradas.get(0); + Editavel entrada2 = this.entradas.get(1); + this.valor = entrada1.pegaValor() != entrada2.pegaValor() ? Sinal.ATIVADO: Sinal.DESATIVADO; + } + if (oldValor != this.valor) { + for(Editavel saida: this.saidas) { + saida.calcula(); + } + } + } + + public Saida[] pegaSaidas() { Saida[] saidasXor = new Saida[1]; saidasXor[0] = new Saida(this, 80, 24); return saidasXor; } - public int altura(){ + public int altura() { return 53; } - public int largura(){ + public int largura() { return 83; } } diff --git a/src/views/Editavel.java b/src/views/Editavel.java index d8c2adb..56caacf 100644 --- a/src/views/Editavel.java +++ b/src/views/Editavel.java @@ -1,5 +1,14 @@ package views; -public interface Editavel extends Selecionavel{ +import models.Sinal; + +public interface Editavel extends Selecionavel { public void movePara(int x, int y); + public void apaga(); + public void conectaSaida(Editavel saida); + public void conectaEntrada(Editavel entrada); + public void desconectaSaida(Editavel saida); + public void desconectaEntrada(Editavel entrada); + public void calcula(); + public Sinal pegaValor(); } diff --git a/src/views/FigAND.java b/src/views/FigAND.java index 39b0b20..dc0a7ee 100644 --- a/src/views/FigAND.java +++ b/src/views/FigAND.java @@ -1,9 +1,6 @@ package views; -import models.AND; -import models.Entrada; -import models.Ponto; -import models.Saida; +import models.*; import javax.imageio.ImageIO; import javax.swing.*; @@ -11,15 +8,19 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; +import java.io.InputStream; public class FigAND extends AND implements Reproduzivel { - public FigAND(Ponto superiorEsquerdo){ - super(superiorEsquerdo); - } - public void reproduzir(Graphics g) { + public FigAND(Ponto superiorEsquerdo) { + super(superiorEsquerdo); + } + + public void reproduzir(Graphics g) { BufferedImage image; try { - image = ImageIO.read(new File("imagens/and.png")); + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + InputStream input = classLoader.getResourceAsStream("imagens/and.png"); + image = ImageIO.read(input); } catch (IOException e) { JOptionPane.showMessageDialog(null, "Erro ao carregar imagem: imagens/and.png"); return; @@ -28,12 +29,19 @@ public void reproduzir(Graphics g) { Entrada[] entradas = this.pegaEntradas(); Saida[] saidas = this.pegaSaidas(); g.setColor(Color.RED); - for(int i=0; i 0) { + if (pontoAnterior != null) { // O "+5" aqui e para centralizar a linha junto ao circulo - g.drawLine(x[i - 1]+5, y[ i - 1]+5, x[i]+5, y[i]+5); + g.drawLine(pontoAnterior.x0() + 5, pontoAnterior.y0() + 5, ponto.x0() + 5, ponto.y0() + 5); } - g.fillOval(x[i], y[i], 10, 10); + g.fillOval(ponto.x0(), ponto.y0(), 10, 10); + pontoAnterior = ponto; } + g.setColor(Color.BLACK); } } diff --git a/src/views/FigNAND.java b/src/views/FigNAND.java index 770456a..896deb6 100644 --- a/src/views/FigNAND.java +++ b/src/views/FigNAND.java @@ -1,9 +1,6 @@ package views; -import models.Entrada; -import models.NAND; -import models.Ponto; -import models.Saida; +import models.*; import javax.imageio.ImageIO; import javax.swing.*; @@ -11,16 +8,20 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; +import java.io.InputStream; public class FigNAND extends NAND implements Reproduzivel { - public FigNAND(Ponto superiorEsquerdo){ + public FigNAND(Ponto superiorEsquerdo) { super(superiorEsquerdo); } - public void reproduzir(Graphics g){ + + public void reproduzir(Graphics g) { BufferedImage image; try { - image = ImageIO.read(new File("imagens/nand.png")); - } catch(IOException e){ + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + InputStream input = classLoader.getResourceAsStream("imagens/nand.png"); + image = ImageIO.read(input); + } catch (IOException e) { JOptionPane.showMessageDialog(null, "Erro ao carregar imagem: imagens/nand.png"); return; } @@ -28,13 +29,21 @@ public void reproduzir(Graphics g){ Entrada[] entradas = this.pegaEntradas(); Saida[] saidas = this.pegaSaidas(); g.setColor(Color.RED); - for(int i=0; i fig = new ArrayList(); + private ArrayList fig = new ArrayList(); - public void addFig(Reproduzivel fig){ + public void addFig(Reproduzivel fig) { this.fig.add(fig); } - public void removeFig(Reproduzivel fig){ - this.fig.remove(fig); + + public void removeFig(Reproduzivel fig) { + fig.apaga(); + this.fig.remove(fig); + } + + public ArrayList getFigs() { + return fig; } - public Reproduzivel pegaObjetoEm(int x, int y){ - for(int i=0; i < fig.size(); i++) { - if (fig.get(i).contemPonto(x, y)) { - return fig.get(i); + + public void setFigs(ArrayList figs) { + this.fig = figs; + this.repaint(); + } + + private boolean verificaObjetoEm(Reproduzivel obj, int x, int y) { + boolean match = false; + int margin = 10; + for(int xVerify=x-margin; xVerify <= (x+margin); xVerify++) { + for(int yVerify=y-margin; yVerify <= (y+margin); yVerify++) { + if(match) { + break; + } + match = obj.contemPonto(xVerify, yVerify); + } + } + return match; + } + + public Reproduzivel pegaObjetoEm(int x, int y) { + for (int i = 0; i < fig.size(); i++) { + Reproduzivel obj = fig.get(i); + if (this.verificaObjetoEm(obj, x, y)) { + return obj; } } return null; @@ -27,8 +54,19 @@ public void paintComponent(Graphics g) { g.setColor(Color.WHITE); g.fillRect(0, 0, this.getWidth(), this.getHeight()); g.setColor(Color.BLACK); + int maxX = 0; + int maxY = 0; for (int i = 0; i < fig.size(); i++) { - fig.get(i).reproduzir(g); + Reproduzivel figure = fig.get(i); + figure.reproduzir(g); + if (maxX < figure.x()+figure.largura()) { + maxX = figure.x()+figure.largura(); + } + if (maxY < figure.y()+figure.altura()) { + maxY = figure.y()+figure.altura(); + } } + setPreferredSize(new Dimension(maxX+20, maxY+20)); + this.revalidate(); } } \ No newline at end of file diff --git a/src/views/Reproduzivel.java b/src/views/Reproduzivel.java index b8038d2..e077647 100644 --- a/src/views/Reproduzivel.java +++ b/src/views/Reproduzivel.java @@ -4,4 +4,9 @@ public interface Reproduzivel extends Editavel { public void reproduzir(Graphics g); + public int x(); + public int y(); + public int largura(); + public int altura(); + } diff --git a/src/views/Selecionavel.java b/src/views/Selecionavel.java index 1f6c3b7..8136cb2 100644 --- a/src/views/Selecionavel.java +++ b/src/views/Selecionavel.java @@ -1,6 +1,14 @@ package views; -public interface Selecionavel { +import java.io.Serializable; + +public interface Selecionavel extends Serializable { public boolean contemPonto(int x, int y); + public void selecionaPonto(int x, int y); + + public int getXSel(); + + public int getYSel(); + }