package ui; import config.Config; import crypto.KeyManager; import model.Chat; import model.Message; import net.RelayClient; import net.direct.DirectServer; import javax.swing.*; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.IOException; import java.security.PublicKey; import java.util.ArrayList; import java.util.HashMap; public class MainWindow extends JFrame implements RelayClient.MessageReceiver { private HashMap chatHashMap = new HashMap<>(); //Name und Chat private DefaultListModel chatListModel = new DefaultListModel<>(); private JPanel mainPanel = new JPanel(new BorderLayout()); private JList chatList = new JList<>(chatListModel); private JScrollPane chatScrollPane = new JScrollPane(chatList); private RelayClient relayClient; private DirectServer directServer; private ArrayList openChatWindows = new ArrayList(); public MainWindow() { try { KeyManager.init(); } catch (Exception e) { System.out.println("KeyManager error! Please try starting the Application again."); } Config.loadConfig(); initializeWindow(); setupUI(); setupEventListeners(); setupRelayConnection(); setVisible(true); } private void setupRelayConnection() { if(Config.USE_RELAY){ try { this.relayClient = new RelayClient(Config.RELAY_SERVER_IP, KeyManager.getPublicKey(), this); } catch (IOException e) { System.out.println("Couldn't connect to main Relay-Server! Try changing your Settings."); } }else{ this.directServer = new DirectServer(this); this.directServer.start(); } } private void initializeWindow() { setTitle("Peer-to-Peer Chat"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(500, 600); setLocationRelativeTo(null); add(mainPanel); } private void setupUI() { mainPanel.removeAll(); JPanel chatListPanel = new JPanel(new BorderLayout()); chatListPanel.add(chatScrollPane, BorderLayout.CENTER); JLabel instructionLabel = new JLabel("Doppelklick zum Oeffnen, Rechtsklick fuer Optionen"); instructionLabel.setHorizontalAlignment(SwingConstants.CENTER); instructionLabel.setForeground(Color.GRAY); chatListPanel.add(instructionLabel, BorderLayout.NORTH); mainPanel.add(chatListPanel, BorderLayout.CENTER); JPanel buttonPanel = createButtonPanel(); mainPanel.add(buttonPanel, BorderLayout.SOUTH); mainPanel.revalidate(); mainPanel.repaint(); } private JPanel createButtonPanel() { JPanel buttonPanel = new JPanel(); JButton newChatBtn = new JButton("Neuer Chat"); JButton settingsBtn = new JButton("Einstellungen"); buttonPanel.add(newChatBtn); buttonPanel.add(settingsBtn); return buttonPanel; } private void setupEventListeners() { JButton newChatBtn = (JButton) ((JPanel) mainPanel.getComponent(1)).getComponent(0); newChatBtn.addActionListener(e -> { NewChatDialog dialog = new NewChatDialog(this, (name, chat) -> { chatHashMap.put(name, chat); updateChatList(); new ChatWindow(name, chat, this); }); dialog.setVisible(true); }); JButton settingsBtn = (JButton) ((JPanel) mainPanel.getComponent(1)).getComponent(1); settingsBtn.addActionListener(e -> new SettingsDialog(this).setVisible(true)); MainWindow receiver = this; chatList.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { String selected = chatList.getSelectedValue(); if (selected != null) { Chat selectedChat = chatHashMap.get(selected); new ChatWindow(selected, selectedChat, receiver); } } } }); JPopupMenu contextMenu = createChatContextMenu(); chatList.setComponentPopupMenu(contextMenu); } private JPopupMenu createChatContextMenu() { JPopupMenu menu = new JPopupMenu(); JMenuItem openItem = new JMenuItem("Chat öffnen"); JMenuItem editItem = new JMenuItem("Eigenschaften bearbeiten"); JMenuItem deleteItem = new JMenuItem("Chat löschen"); openItem.addActionListener(e -> { String selected = chatList.getSelectedValue(); if (selected != null) { Chat selectedChat = chatHashMap.get(selected); new ChatWindow(selected, selectedChat, this); } }); editItem.addActionListener(e -> { String selected = chatList.getSelectedValue(); if (selected != null) { Chat selectedChat = chatHashMap.get(selected); new EditChatWindow(this, selected, selectedChat, (newName, updatedChat) -> { chatHashMap.remove(selected); chatHashMap.put(newName, updatedChat); updateChatList(); }); } }); deleteItem.addActionListener(e -> { String selected = chatList.getSelectedValue(); if (selected != null) { int result = JOptionPane.showConfirmDialog( this, "Möchten Sie den Chat mit '" + selected + "' wirklich löschen?", "Chat löschen", JOptionPane.YES_NO_OPTION ); if (result == JOptionPane.YES_OPTION) { chatHashMap.remove(selected); updateChatList(); } } }); menu.add(openItem); menu.add(editItem); menu.add(deleteItem); return menu; } private void updateChatList() { chatListModel.clear(); for (String chatName : chatHashMap.keySet()) { chatListModel.addElement(chatName); } chatList.revalidate(); chatList.repaint(); //printChatList(); } public void printChatList() { System.out.println("Current chats: " + chatHashMap.keySet()); } @Override public void onMessage(Message msg) { PublicKey senderKey = msg.getSenderKey(); if (senderKey.equals(KeyManager.getPublicKey())) { return; } Chat chat = null; for (Chat existingChat : chatHashMap.values()) { if (existingChat.getTargetKey().equals(senderKey)) { chat = existingChat; break; } } if (chat == null) { if (msg.isDirectMessage()) { chat = new Chat(false, msg.getFromIp(), msg.getUsingPort(), senderKey); } else { chat = new Chat(true, Config.RELAY_SERVER_IP, Config.RELAY_SERVER_PORT, senderKey); } chatHashMap.put(KeyManager.publicKeyToString(senderKey).substring(0, 6), chat); updateChatList(); } chat.addMessage(msg); for (ChatWindow window : openChatWindows) { if (window.getChat().getTargetKey().equals(senderKey)) { window.addMessage(msg); } } } public void closedWindow(ChatWindow closedWindow) { this.openChatWindows.remove(closedWindow); } }