From 3969b66c684ed345926ed9c2903826c969fe4f39 Mon Sep 17 00:00:00 2001 From: Mysaa Date: Sun, 27 Jun 2021 11:03:13 +0200 Subject: [PATCH] =?UTF-8?q?Une=20interface=20plus=20jolie,=20la=20capacit?= =?UTF-8?q?=C3=A9=20de=20d=C3=A9sactiver=20les=20enceintes=20depuis=20Mast?= =?UTF-8?q?er=20(NON=20TEST=C3=89=20!)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/bernard/murder/Parametres.java | 23 +++++ .../com/bernard/murder/audio/AudioServer.java | 83 ++++++++++++++++- .../bernard/murder/audio/SpeakerServer.java | 8 ++ .../murder/view/EnceinteServeurFrame.java | 4 + .../bernard/murder/view/MicServeurFrame.java | 3 +- .../murder/view/minel/ActionsMinel.java | 11 ++- .../murder/view/minel/InventaireMinel.java | 14 ++- .../murder/view/minel/ObjetSearchMinel.java | 34 +++++-- .../murder/view/minel/ServeurMinel.java | 93 +++++++++++++------ .../murder/view/minel/TextPanMinel.java | 16 +++- 10 files changed, 237 insertions(+), 52 deletions(-) create mode 100644 src/main/java/com/bernard/murder/Parametres.java diff --git a/src/main/java/com/bernard/murder/Parametres.java b/src/main/java/com/bernard/murder/Parametres.java new file mode 100644 index 0000000..d987a3b --- /dev/null +++ b/src/main/java/com/bernard/murder/Parametres.java @@ -0,0 +1,23 @@ +package com.bernard.murder; + +import java.awt.Color; +import java.awt.Font; +import java.awt.font.TextAttribute; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.UIManager; + +public class Parametres { + + public static Font minielTitleFont = UIManager.getFont("Label.font"); + static { + Map ftAttrs = new HashMap<>(minielTitleFont.getAttributes()); + ftAttrs.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); + minielTitleFont = minielTitleFont.deriveFont(Font.BOLD).deriveFont(ftAttrs); + } + + public static Color textPanMinielBackgroundColor = new Color(0xFFE085); + public static Color textPanMinielTextColor = new Color(0x274290); + +} diff --git a/src/main/java/com/bernard/murder/audio/AudioServer.java b/src/main/java/com/bernard/murder/audio/AudioServer.java index 0f10f02..1c810ea 100755 --- a/src/main/java/com/bernard/murder/audio/AudioServer.java +++ b/src/main/java/com/bernard/murder/audio/AudioServer.java @@ -15,6 +15,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.UUID; +import java.util.function.Consumer; import javax.sound.sampled.AudioFormat; import javax.swing.JOptionPane; @@ -42,6 +43,7 @@ public class AudioServer { public static final byte ASK_STOP_STREAMING = 0x09; // Format des paquets: [commande 1, int id] // -> Master demande à un micro de ne plus émettre. + // -> Master annonce à une enceinte qu'il n'emmet plus le micro demandé. public static final byte STOP_STREAMING = 0x08; // Format des paquets [commande 1, int id, ~ data] public static final byte AUDIO_STREAM = 0x01; @@ -71,6 +73,7 @@ public class AudioServer { Map> listening; // micId, List private Set changeListeners; + private Set> serverErrorException; public AudioServer() throws SocketException, UnknownHostException { mics = new HashMap(); @@ -80,6 +83,7 @@ public class AudioServer { listening = new HashMap>(); changeListeners = new HashSet<>(); + serverErrorException = new HashSet<>(); initServer(); } @@ -283,7 +287,7 @@ public class AudioServer { return -1; } - public void publishAudioList(Collection co) { + public void publishAudioList(Collection to) { ByteBuffer out = ByteBuffer.allocate(AudioServer.packetMaxSize); out.put(AudioServer.GIVE_AUDIO_LIST); out.putInt(mics.size()); @@ -292,12 +296,81 @@ public class AudioServer { BytesUtils.writeString(out, mic.getValue()); } - try { - for(SocketAddress addr : co) { + for(SocketAddress addr : to) { + try { serveur.sendData(out, addr); + } catch (Exception e) { + serverErrorException.forEach(c -> c.accept(e)); } - } catch (IOException e1) { - e1.printStackTrace(); } } + + public int enceinteIdFromName(String name) { + for(int i:speakers.keySet()) { + if(name.equalsIgnoreCase(speakers.get(i))) + return i; + } + return -1; + } + + public void forceSilence(int id) { + if(!speakers.containsKey(id)) + return; + + int lstTo = listens(id); + if(lstTo!=-1) { + // On enlève le lien d'écoute + listening.get(lstTo).remove(id); + + // Si il n'y a plus rien à écouter. + ByteBuffer out4 = ByteBuffer.allocate(AudioServer.packetMaxSize); + out4.put(AudioServer.STOP_STREAMING); + out4.putInt(lstTo); + try { + serveur.sendData(out4, speakersAddr.get(id)); + } catch (Exception e1) { + serverErrorException.forEach(c -> c.accept(e1)); + } + + } + } + + public void disconnectEnceinte(int id) { + + if(!speakers.containsKey(id)) + return; + // On lui annonce notre déconnection, puis on la supprime des données + ByteBuffer decoBuf = ByteBuffer.allocate(AudioServer.packetMaxSize); + decoBuf.put(AudioServer.DISCONNECTING); + decoBuf.put(AudioServer.MASTER_DEVICE); + decoBuf.putInt(0); + try { + serveur.sendData(decoBuf, speakersAddr.get(id)); + } catch (Exception e) { + serverErrorException.forEach(c -> c.accept(e)); + } + + speakers.remove(id); + speakersAddr.remove(id); + changeListeners.forEach(Runnable::run); + + int lstTo = listens(id); + if(lstTo!=-1) { + // On enlève le lien d'écoute + listening.get(lstTo).remove(id); + + if(listening.get(lstTo).isEmpty()) { + // Si il n'y a plus rien à écouter. + ByteBuffer out4 = ByteBuffer.allocate(AudioServer.packetMaxSize); + out4.put(AudioServer.STOP_STREAMING); + out4.putInt(lstTo); + try { + serveur.sendData(out4, micsAddr.get(lstTo)); + } catch (Exception e1) { + serverErrorException.forEach(c -> c.accept(e1)); + } + } + } + + } } diff --git a/src/main/java/com/bernard/murder/audio/SpeakerServer.java b/src/main/java/com/bernard/murder/audio/SpeakerServer.java index cc7cbe0..4a2f2df 100755 --- a/src/main/java/com/bernard/murder/audio/SpeakerServer.java +++ b/src/main/java/com/bernard/murder/audio/SpeakerServer.java @@ -205,6 +205,14 @@ public class SpeakerServer { System.out.println("Un appareil de type "+deviceType2+" s'est déconécté, mais je m'en fout ^^"); } break; + case AudioServer.STOP_STREAMING: + int deviceId3 = data.getInt(); + if(listeningTo==deviceId3) { + System.out.println("Le micro que l'on écoutait arêtte d'émmetre."); + listeningTo=-1; + for(Runnable toRun : brokenMicListener) + toRun.run(); + } default: System.out.println("Je ne devait pas recevoir cette commade !"); break; diff --git a/src/main/java/com/bernard/murder/view/EnceinteServeurFrame.java b/src/main/java/com/bernard/murder/view/EnceinteServeurFrame.java index d97991c..f7b4ac9 100755 --- a/src/main/java/com/bernard/murder/view/EnceinteServeurFrame.java +++ b/src/main/java/com/bernard/murder/view/EnceinteServeurFrame.java @@ -57,11 +57,13 @@ public class EnceinteServeurFrame extends JFrame{ InformedSourceDataline[] marray = getEnceinteList(); JList enceinteListe = new JList(marray); + enceinteListe.setOpaque(false); JTextField masterIP = new JTextField("192.168.1.1",15); JButton serverControl = new JButton("Lancer"); JList mics = new JList<>(); + mics.setOpaque(false); JButton silenceButton = new JButton("Silence"); serverControl.addActionListener(e->{ @@ -128,6 +130,8 @@ public class EnceinteServeurFrame extends JFrame{ JPanel headP = new JPanel(new BorderLayout()); + headP.setBorder(new EmptyBorder(3, 3, 5, 3)); + JPanel centerP = new JPanel(new GridLayout(2, 1)); headP.add(serverControl,BorderLayout.EAST); diff --git a/src/main/java/com/bernard/murder/view/MicServeurFrame.java b/src/main/java/com/bernard/murder/view/MicServeurFrame.java index 974894e..82987bc 100755 --- a/src/main/java/com/bernard/murder/view/MicServeurFrame.java +++ b/src/main/java/com/bernard/murder/view/MicServeurFrame.java @@ -52,7 +52,7 @@ public class MicServeurFrame extends JFrame{ InformedTargetDataline[] marray = getEnceinteList(); JList micListe = new JList(marray); - + micListe.setOpaque(false); JPanel masterPanel = new JPanel(new BorderLayout()); JTextField masterIP = new JTextField("192.168.1.1"); @@ -90,6 +90,7 @@ public class MicServeurFrame extends JFrame{ JPanel headP = new JPanel(new BorderLayout()); + headP.setBorder(new EmptyBorder(3, 3, 5, 3)); headP.add(serverControl,BorderLayout.EAST); headP.add(masterIP,BorderLayout.CENTER); diff --git a/src/main/java/com/bernard/murder/view/minel/ActionsMinel.java b/src/main/java/com/bernard/murder/view/minel/ActionsMinel.java index 2213a58..5c05840 100755 --- a/src/main/java/com/bernard/murder/view/minel/ActionsMinel.java +++ b/src/main/java/com/bernard/murder/view/minel/ActionsMinel.java @@ -7,6 +7,7 @@ import java.util.HashSet; import java.util.Map; import java.util.stream.Collectors; +import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JLabel; @@ -18,6 +19,7 @@ import javax.swing.Timer; import com.amihaiemil.eoyaml.Yaml; import com.amihaiemil.eoyaml.YamlMapping; import com.amihaiemil.eoyaml.YamlMappingBuilder; +import com.bernard.murder.Parametres; import com.bernard.murder.ParseUtils; import com.bernard.murder.game.GameManager; import com.bernard.murder.model.Action; @@ -71,9 +73,14 @@ public class ActionsMinel extends Minel { Timer timer = new Timer(100, e->updateTexts()); timer.start(); } + JScrollPane globalScroll = new JScrollPane(actionsListPan); - JLabel titleLabel = new JLabel("Actions de "+personnage.getNom()); - globalPan.add(titleLabel,BorderLayout.NORTH); + + JLabel titre = new JLabel("Actions de "+personnage.getNom(),JLabel.CENTER); + titre.setFont(Parametres.minielTitleFont); + titre.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); + + globalPan.add(titre,BorderLayout.NORTH); globalPan.add(globalScroll,BorderLayout.CENTER); updateTexts(); diff --git a/src/main/java/com/bernard/murder/view/minel/InventaireMinel.java b/src/main/java/com/bernard/murder/view/minel/InventaireMinel.java index d34bd59..a06c8a7 100644 --- a/src/main/java/com/bernard/murder/view/minel/InventaireMinel.java +++ b/src/main/java/com/bernard/murder/view/minel/InventaireMinel.java @@ -4,6 +4,7 @@ import java.awt.BorderLayout; import java.awt.Component; import java.awt.Font; +import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JList; @@ -13,6 +14,7 @@ import javax.swing.ListCellRenderer; import com.amihaiemil.eoyaml.Yaml; import com.amihaiemil.eoyaml.YamlMapping; import com.amihaiemil.eoyaml.YamlMappingBuilder; +import com.bernard.murder.Parametres; import com.bernard.murder.game.GameManager; import com.bernard.murder.model.Inventaire; import com.bernard.murder.model.Objet; @@ -37,11 +39,15 @@ public class InventaireMinel extends Minel { public JPanel genContentPane() { JPanel globalpan = new JPanel(new BorderLayout()); + JLabel titre; - if(inv.getInventoryName()!=null) { - JLabel invName = new JLabel(inv.getInventoryName()); - globalpan.add(invName, BorderLayout.NORTH); - } + if(inv.getInventoryName()!=null) + titre = new JLabel(inv.getInventoryName(),JLabel.CENTER); + else + titre = new JLabel("Inventaire",JLabel.CENTER); + titre.setFont(Parametres.minielTitleFont); + titre.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); + globalpan.add(titre, BorderLayout.NORTH); JPanel inventaire = new JPanel(); diff --git a/src/main/java/com/bernard/murder/view/minel/ObjetSearchMinel.java b/src/main/java/com/bernard/murder/view/minel/ObjetSearchMinel.java index 1afd876..90414d4 100755 --- a/src/main/java/com/bernard/murder/view/minel/ObjetSearchMinel.java +++ b/src/main/java/com/bernard/murder/view/minel/ObjetSearchMinel.java @@ -8,16 +8,20 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; +import javax.swing.BorderFactory; +import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; import com.amihaiemil.eoyaml.Scalar; import com.amihaiemil.eoyaml.Yaml; import com.amihaiemil.eoyaml.YamlMapping; import com.amihaiemil.eoyaml.YamlMappingBuilder; import com.amihaiemil.eoyaml.YamlNode; +import com.bernard.murder.Parametres; import com.bernard.murder.ParseUtils; import com.bernard.murder.YamlUtils; import com.bernard.murder.game.GameManager; @@ -59,29 +63,32 @@ public class ObjetSearchMinel extends Minel { JPanel globalPan = new JPanel(new BorderLayout()); + JLabel titre = new JLabel("Recherche d'objets",JLabel.CENTER); + titre.setFont(Parametres.minielTitleFont); + + JPanel panel = new JPanel(new BorderLayout()); + panel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); JTextField searchField = new JTextField(); searchField.setToolTipText("Objet à chercher"); JList searchResults = new JList<>(); + searchResults.setOpaque(false); + searchResults.setBorder(BorderFactory.createEmptyBorder(5,2,2,2)); - - - searchField.getDocument().addDocumentListener(new SimpleDocumentListener() { + DocumentListener dl = new SimpleDocumentListener() { @Override public void changedUpdate(DocumentEvent e) { - System.out.println("Updated to "+e.getDocument().toString()); String searchText = searchField.getText(); - if(searchText.isBlank()) { + /*if(searchText.isBlank()) { searchResults.setListData(new InventorizedObject[0]); return; - } + }*/ Set startMatch = new HashSet<>(); Set anyMatch = new HashSet<>(); Set subwordMatch = new HashSet<>(); for(Objet o : objets.keySet()) { - System.out.println(o+"->"+searchText); if(o.getNom().startsWith(searchText)) startMatch.add(new InventorizedObject(o,objets.get(o))); else if(o.getNom().contains(searchText)) @@ -99,11 +106,18 @@ public class ObjetSearchMinel extends Minel { searchResults.setListData(results); } - }); + }; + searchField.getDocument().addDocumentListener(dl); - globalPan.add(searchField, BorderLayout.NORTH); - globalPan.add(searchResults,BorderLayout.CENTER); + //Remplis la liste pour la première fois + dl.changedUpdate(null); + + panel.add(searchField, BorderLayout.NORTH); + panel.add(searchResults,BorderLayout.CENTER); + + globalPan.add(titre,BorderLayout.NORTH); + globalPan.add(panel,BorderLayout.CENTER); return globalPan; } diff --git a/src/main/java/com/bernard/murder/view/minel/ServeurMinel.java b/src/main/java/com/bernard/murder/view/minel/ServeurMinel.java index 94de057..2db713d 100755 --- a/src/main/java/com/bernard/murder/view/minel/ServeurMinel.java +++ b/src/main/java/com/bernard/murder/view/minel/ServeurMinel.java @@ -3,25 +3,25 @@ package com.bernard.murder.view.minel; import java.awt.BorderLayout; import java.awt.Font; import java.awt.GridLayout; -import java.awt.font.TextAttribute; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.net.SocketException; import java.net.UnknownHostException; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; import java.util.Vector; -import java.util.stream.Collectors; import javax.swing.BorderFactory; import javax.swing.JLabel; import javax.swing.JList; +import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; +import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import com.amihaiemil.eoyaml.Yaml; import com.amihaiemil.eoyaml.YamlMapping; import com.amihaiemil.eoyaml.YamlMappingBuilder; +import com.bernard.murder.Parametres; import com.bernard.murder.audio.AudioServer; import com.bernard.murder.game.GameManager; @@ -29,6 +29,12 @@ public class ServeurMinel extends Minel { AudioServer serveur; + JList microList; + JList enceinteListe; + + JPopupMenu microPopup; + JPopupMenu enceintePopup; + public ServeurMinel(GameManager manager) { super(manager); try { @@ -52,30 +58,22 @@ public class ServeurMinel extends Minel { JPanel panel = new JPanel(new BorderLayout()); JLabel titre = new JLabel("Status du serveur",JLabel.CENTER); - Font ft = titre.getFont(); - Map ftAttrs = new HashMap<>(ft.getAttributes()); - ftAttrs.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); - titre.setFont(ft.deriveFont(Font.BOLD).deriveFont(ftAttrs)); + titre.setFont(Parametres.minielTitleFont); + titre.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); - JList microList = new JList<>(); - JList enceinteListe = new JList<>(); + microList = new JList<>(); + microList.setOpaque(false); + enceinteListe = new JList<>(); + enceinteListe.setOpaque(false); - serveur.addChangeListener(new Runnable() { - - @Override - public void run() { + EnceintePopupListener epl = new EnceintePopupListener(); + enceintePopup = epl.makePopup(); + enceinteListe.addMouseListener(epl); + + serveur.addChangeListener(() -> { // Updating lists content - Collection micsData = serveur.getMics().values(); - microList.setListData(new Vector(micsData)); - - Collection spksData = serveur.getSpeakers().entrySet().stream() - .map(e -> e.getValue() + ( - (serveur.listens(e.getKey())!=-1) - ?(" <- "+serveur.getMics().get(serveur.listens(e.getKey()))) - :"")) - .collect(Collectors.toSet()); - enceinteListe.setListData(new Vector(spksData)); - } + microList.setListData(new Vector(serveur.getMics().keySet())); + enceinteListe.setListData(new Vector(serveur.getSpeakers().keySet())); }); JScrollPane jE = new JScrollPane(enceinteListe); @@ -94,6 +92,49 @@ public class ServeurMinel extends Minel { return panel; } + public class EnceintePopupListener extends MouseAdapter{ + + public final JPopupMenu makePopup() { + JPopupMenu popup = new JPopupMenu(); + + JLabel idText = new JLabel(); + idText.setFont(idText.getFont().deriveFont(Font.ITALIC)); + idText.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + enceinteListe.getSelectionModel().addListSelectionListener(e -> + idText.setText("Id: "+ (enceinteListe.getSelectedValue()!=null?enceinteListe.getSelectedValue():-1)) + ); + popup.add(idText); + JMenuItem jmi = new JMenuItem("Silence"); + jmi.addActionListener(e -> { + serveur.forceSilence(enceinteListe.getSelectedValue()); + }); + popup.add(jmi); + jmi = new JMenuItem("Déconnecter"); + jmi.addActionListener(e -> { + serveur.disconnectEnceinte(enceinteListe.getSelectedValue()); + }); + popup.add(jmi); + return popup; + } + + public void mousePressed(MouseEvent e) { + maybeShowPopup(e); + } + + public void mouseReleased(MouseEvent e) { + maybeShowPopup(e); + } + + private void maybeShowPopup(MouseEvent e) { + if (e.isPopupTrigger()) { + enceinteListe.setSelectedIndex(enceinteListe.locationToIndex(e.getPoint())); + if(!enceinteListe.isSelectionEmpty()) + enceintePopup.show(e.getComponent(), e.getX(), e.getY()); + } + } + } + + @Override public YamlMappingBuilder saveToYaml() { return Yaml.createYamlMappingBuilder(); diff --git a/src/main/java/com/bernard/murder/view/minel/TextPanMinel.java b/src/main/java/com/bernard/murder/view/minel/TextPanMinel.java index 2b40765..56068f1 100644 --- a/src/main/java/com/bernard/murder/view/minel/TextPanMinel.java +++ b/src/main/java/com/bernard/murder/view/minel/TextPanMinel.java @@ -2,6 +2,8 @@ package com.bernard.murder.view.minel; import java.awt.BorderLayout; +import javax.swing.BorderFactory; +import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; @@ -10,6 +12,7 @@ import javax.swing.border.EmptyBorder; import com.amihaiemil.eoyaml.Yaml; import com.amihaiemil.eoyaml.YamlMapping; import com.amihaiemil.eoyaml.YamlMappingBuilder; +import com.bernard.murder.Parametres; import com.bernard.murder.game.GameManager; public class TextPanMinel extends Minel { @@ -29,15 +32,20 @@ public class TextPanMinel extends Minel { @Override public JPanel genContentPane() { JPanel globalPan = new JPanel(new BorderLayout()); - //globalPan.setBackground(ParseUtils.randColor()); + + JLabel titre = new JLabel("Notes",JLabel.CENTER); + titre.setFont(Parametres.minielTitleFont); + titre.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); + + textArea = new JTextArea(); textArea.setBorder(new EmptyBorder(23,23,23,23)); textArea.setText(initTexte); - //Color col = ParseUtils.randColor(); - //textArea.setBackground(col); - //textArea.setForeground(ParseUtils.getContrastColor(col)); + textArea.setBackground(Parametres.textPanMinielBackgroundColor); + textArea.setForeground(Parametres.textPanMinielTextColor); + globalPan.add(titre,BorderLayout.NORTH); globalPan.add(new JScrollPane(textArea),BorderLayout.CENTER); return globalPan; }