From 6db103cd042a51833b21344c98cd1d62ad282c31 Mon Sep 17 00:00:00 2001 From: 230404 <230404@epvc.pt> Date: Wed, 25 Mar 2026 21:00:01 +0000 Subject: [PATCH] first commit --- Awesome_API/.vscode/settings.json | 7 + Awesome_API/README.md | 18 ++ Awesome_API/bin/Main$1.class | Bin 0 -> 954 bytes Awesome_API/bin/Main$2.class | Bin 0 -> 962 bytes Awesome_API/bin/Main.class | Bin 0 -> 9124 bytes Awesome_API/src/Main.java | 334 ++++++++++++++++++++++++++++++ 6 files changed, 359 insertions(+) create mode 100644 Awesome_API/.vscode/settings.json create mode 100644 Awesome_API/README.md create mode 100644 Awesome_API/bin/Main$1.class create mode 100644 Awesome_API/bin/Main$2.class create mode 100644 Awesome_API/bin/Main.class create mode 100644 Awesome_API/src/Main.java diff --git a/Awesome_API/.vscode/settings.json b/Awesome_API/.vscode/settings.json new file mode 100644 index 0000000..e112a70 --- /dev/null +++ b/Awesome_API/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "java.project.sourcePaths": ["src"], + "java.project.outputPath": "bin", + "java.project.referencedLibraries": [ + "lib/**/*.jar" + ] +} diff --git a/Awesome_API/README.md b/Awesome_API/README.md new file mode 100644 index 0000000..7c03a53 --- /dev/null +++ b/Awesome_API/README.md @@ -0,0 +1,18 @@ +## Getting Started + +Welcome to the VS Code Java world. Here is a guideline to help you get started to write Java code in Visual Studio Code. + +## Folder Structure + +The workspace contains two folders by default, where: + +- `src`: the folder to maintain sources +- `lib`: the folder to maintain dependencies + +Meanwhile, the compiled output files will be generated in the `bin` folder by default. + +> If you want to customize the folder structure, open `.vscode/settings.json` and update the related settings there. + +## Dependency Management + +The `JAVA PROJECTS` view allows you to manage your dependencies. More details can be found [here](https://github.com/microsoft/vscode-java-dependency#manage-dependencies). diff --git a/Awesome_API/bin/Main$1.class b/Awesome_API/bin/Main$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e02b54b3f212f4039b37f3e1a7c2e89fc08aeee7 GIT binary patch literal 954 zcmZWnT~8B16g|_fEZwd^`TkN-QA_!#R7Is|NLrDSLWr0e;?vTO?U-e^*;pSyKKS`7<})1a6V?k zW98MeTf2@YT{^5OPesoK;_11HfKl*k(n1^w8&}XH&|g-b+&MZtkil!`z?Do>_N$It zaRQ~^XGSAxs8FD{+^Lrr=xefaRPYa*z9+p%U^HFU1hUR?lzkaE&4#Lm`MHWNma@@@ zeiK6iLzjGVMH3?ozX;S6Q|{^lCdOFn94q*)A6OX0gyug6n@==?aKCvvrxAH%uT_&k2lNhH^!AJyvfDjQnXnNWOp5I z(OwiVf+7X%lIO{w;5uO_^(O4dFxvFP2s3PboGS^$_;IQDHhIhP6xxz$q4#SWw)odD zIFTg(cE^F|RlW?pB(&(@FSHpvw=(lB49x$);Pxqo_mjy}jP4Jt4tz@CcMIdm%n7DG zYg;^pUn%^ht%Vyq3yUYXwGfXJzN=kMFxO=;Ne;jmsgA?K1XeJKJf={>bemPCQ~8V) tIbab>nBR^%Y}m5u*+CMZ^056Ik8OnB9Ta|5P<5ZB2ae z2l%6m-z*zI>L#-@^IguKbH4rk=jSf~ukb951VgGLJXNN1lA-iLOoS_rj4LNn8MmXy zq1+vaPeuj|t2*$8o)SJou05-4YF`Hp24^Dta&K&mRty_a{@4wVJT-Lp_o6TrrJj4r zGcOn_m1Ttgc2v6z$)+C23>YqRq_OH?1zC;^atte#YS(589G8${$hJKt55|W*8N3%g zUs9&6`@-*vz_a%_m^33VBt7k^bmGMitj)acd1D zg{3+E1*!~dQ(?!RvAUdhdK~oSYtLGfvFdj$1v0Ls`o0cnSRH9bdXUC88E*?XcHlDP zL-W~}9hyX-rqi6wa7jR8&Sy@Pzg0>GO<#new9X&M(7e&1AuDK#^fxAG(FlQD!48>j zHkyG$`87K2QiY9VYujhwwI5io)z6UsPN4*f^j?qBC)DzV&L_A+F;30Yf(>la&Ttji zVz?%C*-vI`r-XKj{5h_l;$ literal 0 HcmV?d00001 diff --git a/Awesome_API/bin/Main.class b/Awesome_API/bin/Main.class new file mode 100644 index 0000000000000000000000000000000000000000..12e90d4cc8f45e48d5382c499c967475f432ba9e GIT binary patch literal 9124 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 cmbFrom; + private JComboBox cmbTo; + private JTextField txtValue; + private JLabel lblResult; + private JLabel lblResultSub; + + // Texto de Exemplo (Placeholder) + private final String PLACEHOLDER_TEXT = "Ex: 100.00"; + + public Main() { + setTitle("Conversor de Moedas"); + setSize(420, 750); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setLocationRelativeTo(null); + + // Painel Principal com Gradiente Azul + JPanel mainPanel = new JPanel() { + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2 = (Graphics2D) g.create(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + GradientPaint gp = new GradientPaint(0, 0, COLOR_BG_TOP, 0, getHeight(), COLOR_BG_BOTTOM); + g2.setPaint(gp); + g2.fillRect(0, 0, getWidth(), getHeight()); + g2.dispose(); + } + }; + mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); + mainPanel.setBorder(new EmptyBorder(20, 20, 20, 20)); + setContentPane(mainPanel); + + // --- TÍTULO --- + JLabel title = new JLabel("Conversor de Moedas", SwingConstants.CENTER); + title.setFont(new Font("Segoe UI", Font.BOLD, 30)); + title.setForeground(Color.WHITE); + title.setAlignmentX(Component.CENTER_ALIGNMENT); + mainPanel.add(title); + mainPanel.add(Box.createVerticalStrut(20)); + + // --- CARTÃO 1: SELEÇÃO DE MOEDAS --- + RoundedPanel cardMoedas = new RoundedPanel(); + cardMoedas.setLayout(new BoxLayout(cardMoedas, BoxLayout.Y_AXIS)); + + JLabel lblDe = new JLabel("Converter De:"); + lblDe.setFont(new Font("Segoe UI", Font.PLAIN, 14)); + lblDe.setForeground(Color.DARK_GRAY); + + cmbFrom = new JComboBox<>(moedaDisplay); + styleComboBox(cmbFrom); + + JLabel lblPara = new JLabel("Para:"); + lblPara.setFont(new Font("Segoe UI", Font.PLAIN, 14)); + lblPara.setForeground(Color.DARK_GRAY); + + cmbTo = new JComboBox<>(moedaDisplay); + styleComboBox(cmbTo); + cmbTo.setSelectedIndex(2); // Padrão BRL + + JPanel pnlDe = new JPanel(new FlowLayout(FlowLayout.LEFT)); pnlDe.setOpaque(false); pnlDe.add(lblDe); + JPanel pnlPara = new JPanel(new FlowLayout(FlowLayout.LEFT)); pnlPara.setOpaque(false); pnlPara.add(lblPara); + + cardMoedas.add(pnlDe); + cardMoedas.add(cmbFrom); + cardMoedas.add(Box.createVerticalStrut(15)); + cardMoedas.add(pnlPara); + cardMoedas.add(cmbTo); + + mainPanel.add(cardMoedas); + mainPanel.add(Box.createVerticalStrut(15)); + + // --- CARTÃO 2: QUANTIDADE COM PLACEHOLDER --- + RoundedPanel cardValor = new RoundedPanel(); + cardValor.setLayout(new BoxLayout(cardValor, BoxLayout.Y_AXIS)); + + JLabel lblVal = new JLabel("Quantidade a Converter:"); + lblVal.setFont(new Font("Segoe UI", Font.PLAIN, 14)); + lblVal.setForeground(Color.DARK_GRAY); + JPanel pnlVal = new JPanel(new FlowLayout(FlowLayout.LEFT)); pnlVal.setOpaque(false); pnlVal.add(lblVal); + + // Configuração do Placeholder + txtValue = new JTextField(PLACEHOLDER_TEXT); + txtValue.setForeground(Color.GRAY); // Cor de texto fantasma + styleTextField(txtValue); + + // Evento para limpar o placeholder quando se clica + txtValue.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + if (txtValue.getText().equals(PLACEHOLDER_TEXT)) { + txtValue.setText(""); + txtValue.setForeground(Color.BLACK); // Volta à cor normal para o user escrever + } + } + + @Override + public void focusLost(FocusEvent e) { + if (txtValue.getText().isEmpty()) { + txtValue.setForeground(Color.GRAY); + txtValue.setText(PLACEHOLDER_TEXT); // Volta o texto fantasma se não escreverem nada + } + } + }); + + cardValor.add(pnlVal); + cardValor.add(txtValue); + mainPanel.add(cardValor); + mainPanel.add(Box.createVerticalStrut(20)); + + // --- BOTÕES PRINCIPAIS --- + JButton btnConvert = new RoundedButton("Converter Agora", COLOR_BTN_PRIMARY, Color.BLACK); + mainPanel.add(btnConvert); + mainPanel.add(Box.createVerticalStrut(10)); + + JButton btnInvert = new RoundedButton("🔁 Inverter Moedas", COLOR_BTN_SECONDARY, Color.WHITE); + btnInvert.addActionListener(e -> inverterMoedas()); + mainPanel.add(btnInvert); + mainPanel.add(Box.createVerticalStrut(20)); + + // --- CARTÃO 3: RESULTADO --- + RoundedPanel cardResult = new RoundedPanel(); + cardResult.setLayout(new BoxLayout(cardResult, BoxLayout.Y_AXIS)); + + JLabel lblRecebera = new JLabel("Você receberá:"); + lblRecebera.setFont(new Font("Segoe UI", Font.PLAIN, 14)); + lblRecebera.setForeground(Color.DARK_GRAY); + lblRecebera.setAlignmentX(Component.CENTER_ALIGNMENT); + + lblResult = new JLabel("0.00", SwingConstants.CENTER); + lblResult.setFont(new Font("Segoe UI", Font.BOLD, 42)); + lblResult.setForeground(new Color(20, 20, 20)); + lblResult.setAlignmentX(Component.CENTER_ALIGNMENT); + + lblResultSub = new JLabel("-"); + lblResultSub.setFont(new Font("Segoe UI", Font.PLAIN, 16)); + lblResultSub.setForeground(Color.DARK_GRAY); + lblResultSub.setAlignmentX(Component.CENTER_ALIGNMENT); + + cardResult.add(Box.createVerticalStrut(10)); + cardResult.add(lblRecebera); + cardResult.add(Box.createVerticalStrut(10)); + cardResult.add(lblResult); + cardResult.add(lblResultSub); + cardResult.add(Box.createVerticalStrut(10)); + + mainPanel.add(cardResult); + + // --- LÓGICA DO BOTÃO CONVERTER --- + btnConvert.addActionListener(e -> { + int indexFrom = cmbFrom.getSelectedIndex(); + int indexTo = cmbTo.getSelectedIndex(); + + String input = txtValue.getText().replace(",", "."); + + // Verifica se o utilizador não escreveu nada e deixou o placeholder lá + if (input.equals(PLACEHOLDER_TEXT) || input.isEmpty()) { + JOptionPane.showMessageDialog(this, "Insere um número válido, senão vai dar merda!", "Erro", JOptionPane.ERROR_MESSAGE); + return; + } + + final double val; + try { + val = Double.parseDouble(input); + } catch (NumberFormatException ex) { + JOptionPane.showMessageDialog(this, "Apenas números, por favor. Senão vai dar merda!", "Erro", JOptionPane.ERROR_MESSAGE); + return; + } + + if (indexFrom == indexTo) { + lblResult.setText(String.format("%.2f %s", val, moedaAbrev[indexTo])); + lblResultSub.setText(moedaDisplay[indexTo]); + return; + } + + lblResult.setText("A calcular..."); + + new Thread(() -> { + try { + String m1 = moedaAbrev[indexFrom]; + String m2 = moedaAbrev[indexTo]; + double rate = obterTaxaDeCambio(m1, m2); + double finalValue = val * rate; + + SwingUtilities.invokeLater(() -> { + lblResult.setText(String.format("%.2f %s", finalValue, m2)); + lblResultSub.setText(moedaDisplay[indexTo]); + }); + + } catch (Exception ex) { + SwingUtilities.invokeLater(() -> { + lblResult.setText("Erro"); + JOptionPane.showMessageDialog(this, "Erro de rede: " + ex.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE); + }); + } + }).start(); + }); + + // Foca o ecrã para o placeholder funcionar logo na primeira vez + getContentPane().requestFocusInWindow(); + } + + private void inverterMoedas() { + int indexFrom = cmbFrom.getSelectedIndex(); + int indexTo = cmbTo.getSelectedIndex(); + cmbFrom.setSelectedIndex(indexTo); + cmbTo.setSelectedIndex(indexFrom); + } + + private static double obterTaxaDeCambio(String m1, String m2) throws Exception { + String urlStr = "https://economia.awesomeapi.com.br/json/last/" + m1 + "-" + m2; + URL url = new URL(urlStr); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + conn.setConnectTimeout(5000); + conn.setReadTimeout(5000); + + if (conn.getResponseCode() != 200) throw new IOException("HTTP Error: " + conn.getResponseCode()); + + BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + StringBuilder response = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) response.append(line); + reader.close(); + + Pattern pattern = Pattern.compile("\"bid\"\\s*:\\s*\"([^\"]+)\""); + Matcher matcher = pattern.matcher(response.toString()); + if (matcher.find()) return Double.parseDouble(matcher.group(1)); + else throw new Exception("Chave 'bid' não encontrada."); + } + + // --- CLASSES DE ESTILO CUSTOMIZADAS --- + + // Painel Arredondado + class RoundedPanel extends JPanel { + public RoundedPanel() { + setOpaque(false); + setBorder(new EmptyBorder(15, 20, 15, 20)); + setMaximumSize(new Dimension(360, 200)); + } + @Override + protected void paintComponent(Graphics g) { + Graphics2D g2 = (Graphics2D) g.create(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setColor(new Color(0, 0, 0, 20)); + g2.fillRoundRect(2, 2, getWidth() - 4, getHeight() - 4, 25, 25); + g2.setColor(COLOR_CARD); + g2.fillRoundRect(0, 0, getWidth() - 4, getHeight() - 4, 25, 25); + g2.dispose(); + super.paintComponent(g); + } + } + + // Botão Arredondado + class RoundedButton extends JButton { + private Color bgColor; + public RoundedButton(String text, Color bg, Color fg) { + super(text); + this.bgColor = bg; + setForeground(fg); + setFont(new Font("Segoe UI", Font.BOLD, 18)); + setFocusPainted(false); + setContentAreaFilled(false); + setBorderPainted(false); + setAlignmentX(Component.CENTER_ALIGNMENT); + setMaximumSize(new Dimension(360, 50)); + setCursor(new Cursor(Cursor.HAND_CURSOR)); + + addMouseListener(new MouseAdapter() { + public void mouseEntered(MouseEvent e) { bgColor = bg.brighter(); repaint(); } + public void mouseExited(MouseEvent e) { bgColor = bg; repaint(); } + }); + } + @Override + protected void paintComponent(Graphics g) { + Graphics2D g2 = (Graphics2D) g.create(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setColor(new Color(0, 0, 0, 30)); + g2.fillRoundRect(2, 4, getWidth() - 4, getHeight() - 4, 20, 20); + g2.setColor(bgColor); + g2.fillRoundRect(0, 0, getWidth() - 4, getHeight() - 5, 20, 20); + g2.dispose(); + super.paintComponent(g); + } + } + + private void styleComboBox(JComboBox cb) { + cb.setMaximumSize(new Dimension(320, 40)); + cb.setFont(new Font("Segoe UI", Font.PLAIN, 16)); + cb.setBackground(Color.WHITE); + cb.setFocusable(false); + cb.setAlignmentX(Component.CENTER_ALIGNMENT); + } + + private void styleTextField(JTextField tf) { + tf.setMaximumSize(new Dimension(320, 45)); + tf.setFont(new Font("Segoe UI", Font.PLAIN, 18)); + tf.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1, true), + new EmptyBorder(5, 10, 5, 10) + )); + tf.setAlignmentX(Component.CENTER_ALIGNMENT); + } + + public static void main(String[] args) { + SwingUtilities.invokeLater(() -> { + new Main().setVisible(true); + }); + } +} \ No newline at end of file