Ajout des paramètres, et déplacement des classes Util dans BernardLibs
This commit is contained in:
parent
11c91fe87e
commit
7567602c61
@ -30,6 +30,6 @@ jar {
|
|||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
implementation 'com.amihaiemil.web:eo-yaml:5.2.1'
|
implementation 'com.amihaiemil.web:eo-yaml:5.2.1'
|
||||||
implementation 'com.formdev:flatlaf:0.37'
|
implementation 'com.formdev:flatlaf:1.3'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
11
murderator-config.yml
Normal file
11
murderator-config.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
class: com.bernard.murder.Parametres
|
||||||
|
minielTitleFont:
|
||||||
|
name: Dialog
|
||||||
|
style: 1
|
||||||
|
size: 12
|
||||||
|
textPanMinielBackgroundColor: 0xffffe085
|
||||||
|
textPanMinielTextColor: 0xff274290
|
||||||
|
minielMinSize: 200x300
|
||||||
|
minielParLigne: 2
|
||||||
|
lignesDeMinielAvantScroll: 2
|
||||||
|
lookAndFeel: "flatlaf-light"
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package com.bernard.murder;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
import java.util.stream.Stream.Builder;
|
|
||||||
|
|
||||||
public class BytesUtils {
|
|
||||||
|
|
||||||
public static String readString(ByteBuffer buffer) {
|
|
||||||
int stringLength = buffer.getInt();
|
|
||||||
byte[] stringData = new byte[stringLength];
|
|
||||||
buffer.get(stringData);
|
|
||||||
return new String(stringData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void writeString(ByteBuffer buffer, String s) {
|
|
||||||
byte[] data = s.getBytes();
|
|
||||||
buffer.putInt(data.length);
|
|
||||||
buffer.put(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Stream<Byte> toStream(ByteBuffer buffer){
|
|
||||||
Builder<Byte> bldr = Stream.builder();
|
|
||||||
|
|
||||||
for(Byte b: buffer.array())
|
|
||||||
bldr.add(b);
|
|
||||||
|
|
||||||
return bldr.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void dump(ByteBuffer buffer) {
|
|
||||||
System.out.println(toStream(buffer).limit(buffer.position()).map(b -> Integer.toString(Byte.toUnsignedInt(b))).collect(Collectors.joining(",")));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
package com.bernard.murder;
|
|
||||||
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
public class FuncUtils {
|
|
||||||
|
|
||||||
public static final <A,B,C> Function<A,C> compose(Function<B,C> f,Function<? super A,? extends B> g) {
|
|
||||||
return f.compose(g);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -9,21 +9,31 @@ import java.util.Map;
|
|||||||
|
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
|
import com.bernard.configurator.annotations.ConfigClass;
|
||||||
|
|
||||||
|
@ConfigClass(requireOption = false)
|
||||||
public class Parametres {
|
public class Parametres {
|
||||||
|
|
||||||
public static Font minielTitleFont = UIManager.getFont("Label.font");
|
public static Parametres instance;
|
||||||
static {
|
|
||||||
|
public Font minielTitleFont = UIManager.getFont("Label.font");
|
||||||
|
|
||||||
|
public Color textPanMinielBackgroundColor = new Color(0xFFE085);
|
||||||
|
public Color textPanMinielTextColor = new Color(0x274290);
|
||||||
|
|
||||||
|
|
||||||
|
public Dimension minielMinSize = new Dimension(200, 300);
|
||||||
|
public int minielParLigne = 2;
|
||||||
|
public int lignesDeMinielAvantScroll = 2;
|
||||||
|
|
||||||
|
public String lookAndFeel = "flatlaf-darcula";
|
||||||
|
|
||||||
|
public Parametres() {
|
||||||
Map<TextAttribute, Object> ftAttrs = new HashMap<>(minielTitleFont.getAttributes());
|
Map<TextAttribute, Object> ftAttrs = new HashMap<>(minielTitleFont.getAttributes());
|
||||||
ftAttrs.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
|
ftAttrs.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
|
||||||
minielTitleFont = minielTitleFont.deriveFont(Font.BOLD).deriveFont(ftAttrs);
|
minielTitleFont = minielTitleFont.deriveFont(Font.BOLD).deriveFont(ftAttrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Color textPanMinielBackgroundColor = new Color(0xFFE085);
|
|
||||||
public static Color textPanMinielTextColor = new Color(0x274290);
|
|
||||||
|
|
||||||
|
|
||||||
public static Dimension minielMinSize = new Dimension(200, 300);
|
|
||||||
public static int minielParLigne = 2;
|
|
||||||
public static int lignesDeMinielAvantScroll = 2;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,184 +0,0 @@
|
|||||||
package com.bernard.murder;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.ObjectInputStream;
|
|
||||||
import java.io.ObjectOutputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.LocalTime;
|
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.Spliterator;
|
|
||||||
import java.util.Spliterators;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
import java.util.stream.StreamSupport;
|
|
||||||
|
|
||||||
import com.amihaiemil.eoyaml.Yaml;
|
|
||||||
import com.amihaiemil.eoyaml.YamlMapping;
|
|
||||||
import com.amihaiemil.eoyaml.YamlMappingBuilder;
|
|
||||||
import com.amihaiemil.eoyaml.YamlNode;
|
|
||||||
import com.amihaiemil.eoyaml.YamlSequence;
|
|
||||||
import com.amihaiemil.eoyaml.YamlSequenceBuilder;
|
|
||||||
|
|
||||||
public class ParseUtils {
|
|
||||||
|
|
||||||
|
|
||||||
static Pattern timeLengthPattern = Pattern.compile("^(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s?)?$");
|
|
||||||
|
|
||||||
public static long parseTimeLength(String tl) {
|
|
||||||
Matcher mtch = timeLengthPattern.matcher(tl);
|
|
||||||
if(!mtch.matches())throw new IllegalArgumentException("La chaine de caractères «"+tl+"» ne décrit pas un intervalle de temps normalisé");
|
|
||||||
int h = mtch.group(2)==null?0:Integer.parseInt(mtch.group(2));
|
|
||||||
int m = mtch.group(4)==null?0:Integer.parseInt(mtch.group(4));
|
|
||||||
int s = mtch.group(6)==null?0:Integer.parseInt(mtch.group(6));
|
|
||||||
return (h*3600+m*60+s)*1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T watch(T el) {
|
|
||||||
System.out.println(el);
|
|
||||||
return el;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static String dumpTimeLength(long t) {
|
|
||||||
long h=t/1000/3600, m=t/1000/60%60, s=t/1000%60;
|
|
||||||
return (h!=0?h+"h":"" )+ (m!=0?m+"m":"")+(s!=0?s+"s":"");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static String dumpHourDate(long t) {
|
|
||||||
return DateTimeFormatter.ISO_LOCAL_TIME.format(LocalTime.ofInstant(Instant.ofEpochMilli(t-t%1000), ZoneId.systemDefault()));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static <T> Set<T> union(Collection<T> c1, Collection<T> c2){
|
|
||||||
Set<T> out = c1.stream().collect(Collectors.toSet());
|
|
||||||
out.addAll(c2);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isSubWord(String word, String subword) {
|
|
||||||
int i=0,j=0;
|
|
||||||
while(true) {
|
|
||||||
if(i==subword.length())return true;
|
|
||||||
if(j==word.length())return false;
|
|
||||||
if(subword.charAt(i)==word.charAt(j))i++;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean and(boolean[] bb) {
|
|
||||||
for(boolean b : bb)
|
|
||||||
if(!b)return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static Set<String> mappingStringKeys(YamlMapping mapping) throws IOException{
|
|
||||||
return mapping.keys().stream().map(n ->n.asScalar().value()).collect(Collectors.toSet());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static Stream<YamlNode> sequenceStream(YamlSequence sequence){
|
|
||||||
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(sequence.iterator(),Spliterator.ORDERED),false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> Function<YamlNode,T> wetherMapping(Function<YamlNode,T> fnot,Function<YamlMapping,T> fyes){
|
|
||||||
return n -> (n instanceof YamlMapping)?fyes.apply((YamlMapping)n):fnot.apply(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Color randColor() {
|
|
||||||
return Color.getHSBColor((float) Math.random(), 1.0f, 1.0f);
|
|
||||||
}
|
|
||||||
public static Color randDarkColor() {
|
|
||||||
return Color.getHSBColor((float) Math.random(), 1.0f, 0.3f);
|
|
||||||
}
|
|
||||||
public static Color randDarkBlueColor() {
|
|
||||||
// 180° to 240°
|
|
||||||
return Color.getHSBColor( (float) (0.5f + 0.2f*Math.random()), 1.0f, 0.3f);
|
|
||||||
}
|
|
||||||
public static Color getContrastColor(Color color) {
|
|
||||||
double y = (299 * color.getRed() + 587 * color.getGreen() + 114 * color.getBlue()) / 1000;
|
|
||||||
return y >= 128 ? Color.black : Color.white;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static final <M> YamlMapping setToMapSS(Set<M> nodes, Function<M,String> key, Function<M,String> value) {
|
|
||||||
YamlMappingBuilder builder = Yaml.createYamlMappingBuilder();
|
|
||||||
for(M n : nodes)
|
|
||||||
builder = builder.add(key.apply(n), value.apply(n));
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
public static final <M> YamlMapping setToMapSY(Set<M> nodes, Function<M,String> key, Function<M,YamlNode> value) {
|
|
||||||
YamlMappingBuilder builder = Yaml.createYamlMappingBuilder();
|
|
||||||
for(M n : nodes)
|
|
||||||
builder = builder.add(key.apply(n), value.apply(n));
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
public static final <M> YamlMapping setToMapYS(Set<M> nodes, Function<M,YamlNode> key, Function<M,String> value) {
|
|
||||||
YamlMappingBuilder builder = Yaml.createYamlMappingBuilder();
|
|
||||||
for(M n : nodes)
|
|
||||||
builder = builder.add(key.apply(n), value.apply(n));
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
public static final <M> YamlMapping setToMapYY(Set<M> nodes, Function<M,YamlNode> key, Function<M,YamlNode> value) {
|
|
||||||
YamlMappingBuilder builder = Yaml.createYamlMappingBuilder();
|
|
||||||
for(M n : nodes)
|
|
||||||
builder = builder.add(key.apply(n), value.apply(n));
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
public static final <M> YamlSequence setToSeqY(Set<YamlNode> nodes) {
|
|
||||||
YamlSequenceBuilder builder = Yaml.createYamlSequenceBuilder();
|
|
||||||
for(YamlNode n : nodes)
|
|
||||||
builder = builder.add(n);
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final <M> YamlSequence setToSeqS(Set<String> nodes) {
|
|
||||||
YamlSequenceBuilder builder = Yaml.createYamlSequenceBuilder();
|
|
||||||
for (String n : nodes)
|
|
||||||
builder = builder.add(n);
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Object fromBase64(String s) throws ClassNotFoundException {
|
|
||||||
try {
|
|
||||||
byte[] data = Base64.getDecoder().decode(s);
|
|
||||||
ObjectInputStream ois;
|
|
||||||
ois = new ObjectInputStream(new ByteArrayInputStream(data));
|
|
||||||
Object o = ois.readObject();
|
|
||||||
ois.close();
|
|
||||||
return o;
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.err.println("Erreur dans la lecture de la chaine de caractères");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final String toBase64(Serializable o) {
|
|
||||||
try {
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
ObjectOutputStream oos;
|
|
||||||
oos = new ObjectOutputStream(baos);
|
|
||||||
oos.writeObject(o);
|
|
||||||
oos.close();
|
|
||||||
return Base64.getEncoder().encodeToString(baos.toByteArray());
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.err.println("Erreur dans l'écriture de la chaine de caractères");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,124 +0,0 @@
|
|||||||
package com.bernard.murder;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.BinaryOperator;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.stream.Collector;
|
|
||||||
|
|
||||||
import com.amihaiemil.eoyaml.Yaml;
|
|
||||||
import com.amihaiemil.eoyaml.YamlMapping;
|
|
||||||
import com.amihaiemil.eoyaml.YamlMappingBuilder;
|
|
||||||
import com.amihaiemil.eoyaml.YamlNode;
|
|
||||||
import com.amihaiemil.eoyaml.YamlSequence;
|
|
||||||
import com.amihaiemil.eoyaml.YamlSequenceBuilder;
|
|
||||||
|
|
||||||
|
|
||||||
public class YamlUtils {
|
|
||||||
|
|
||||||
public static final YamlSequence listToSeq(List<YamlNode> nodes) {
|
|
||||||
YamlSequenceBuilder ysb = Yaml.createYamlSequenceBuilder();
|
|
||||||
for(YamlNode n : nodes)
|
|
||||||
ysb = ysb.add(n);
|
|
||||||
return ysb.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final YamlSequence listToSeqString(List<String> nodes) {
|
|
||||||
YamlSequenceBuilder ysb = Yaml.createYamlSequenceBuilder();
|
|
||||||
for(String n : nodes)
|
|
||||||
ysb = ysb.add(n);
|
|
||||||
return ysb.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final YamlMapping mapToMapping(Map<YamlNode,YamlNode> nodes) {
|
|
||||||
YamlMappingBuilder ysb = Yaml.createYamlMappingBuilder();
|
|
||||||
for(Entry<YamlNode, YamlNode> n : nodes.entrySet())
|
|
||||||
ysb = ysb.add(n.getKey(),n.getValue());
|
|
||||||
return ysb.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final <A,B> YamlMapping mapToMapping(Map<A,B> map,Function<A,YamlNode> fKey,Function<B,YamlNode> fVal) {
|
|
||||||
YamlMappingBuilder ysb = Yaml.createYamlMappingBuilder();
|
|
||||||
for(Entry<A,B> e : map.entrySet())
|
|
||||||
ysb.add(fKey.apply(e.getKey()), fVal.apply(e.getValue()));
|
|
||||||
return ysb.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final YamlNode scalar(Object in) {
|
|
||||||
return Yaml.createYamlScalarBuilder().addLine(in.toString()).buildPlainScalar();
|
|
||||||
}
|
|
||||||
public static final YamlNode foldedScalar(String in) {
|
|
||||||
return Yaml.createYamlScalarBuilder().addLine(in).buildFoldedBlockScalar();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final YamlSequenceBuilder seqMerge(YamlSequenceBuilder ysba,YamlSequenceBuilder ysbb) {
|
|
||||||
for(YamlNode na : ysba.build().values())
|
|
||||||
ysbb = ysbb.add(na);
|
|
||||||
return ysbb;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final CollectorImpl<YamlNode, YamlSequenceBuilder, YamlSequence> sequenceCollector =
|
|
||||||
new CollectorImpl<>(
|
|
||||||
Yaml::createYamlSequenceBuilder,
|
|
||||||
YamlSequenceBuilder::add,
|
|
||||||
YamlUtils::seqMerge,
|
|
||||||
YamlSequenceBuilder::build,
|
|
||||||
Set.of(Collector.Characteristics.UNORDERED));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* (Copied from Collectors class)
|
|
||||||
* Simple implementation class for {@code Collector}.
|
|
||||||
*
|
|
||||||
* @param <T> the type of elements to be collected
|
|
||||||
* @param <R> the type of the result
|
|
||||||
*/
|
|
||||||
static class CollectorImpl<T, A, R> implements Collector<T, A, R> {
|
|
||||||
private final Supplier<A> supplier;
|
|
||||||
private final BiConsumer<A, T> accumulator;
|
|
||||||
private final BinaryOperator<A> combiner;
|
|
||||||
private final Function<A, R> finisher;
|
|
||||||
private final Set<Characteristics> characteristics;
|
|
||||||
|
|
||||||
CollectorImpl(Supplier<A> supplier,
|
|
||||||
BiConsumer<A, T> accumulator,
|
|
||||||
BinaryOperator<A> combiner,
|
|
||||||
Function<A,R> finisher,
|
|
||||||
Set<Characteristics> characteristics) {
|
|
||||||
this.supplier = supplier;
|
|
||||||
this.accumulator = accumulator;
|
|
||||||
this.combiner = combiner;
|
|
||||||
this.finisher = finisher;
|
|
||||||
this.characteristics = characteristics;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BiConsumer<A, T> accumulator() {
|
|
||||||
return accumulator;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Supplier<A> supplier() {
|
|
||||||
return supplier;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BinaryOperator<A> combiner() {
|
|
||||||
return combiner;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Function<A, R> finisher() {
|
|
||||||
return finisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Characteristics> characteristics() {
|
|
||||||
return characteristics;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -25,9 +25,9 @@ import com.amihaiemil.eoyaml.Yaml;
|
|||||||
import com.amihaiemil.eoyaml.YamlMapping;
|
import com.amihaiemil.eoyaml.YamlMapping;
|
||||||
import com.amihaiemil.eoyaml.YamlNode;
|
import com.amihaiemil.eoyaml.YamlNode;
|
||||||
import com.amihaiemil.eoyaml.YamlSequenceBuilder;
|
import com.amihaiemil.eoyaml.YamlSequenceBuilder;
|
||||||
import com.bernard.murder.BytesUtils;
|
import com.bernard.util.BytesUtils;
|
||||||
import com.bernard.murder.ParseUtils;
|
import com.bernard.util.ParseUtils;
|
||||||
import com.bernard.murder.YamlUtils;
|
import com.bernard.util.YamlUtils;
|
||||||
|
|
||||||
public class AudioServer {
|
public class AudioServer {
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import java.util.UUID;
|
|||||||
import javax.sound.sampled.LineUnavailableException;
|
import javax.sound.sampled.LineUnavailableException;
|
||||||
import javax.sound.sampled.TargetDataLine;
|
import javax.sound.sampled.TargetDataLine;
|
||||||
|
|
||||||
import com.bernard.murder.BytesUtils;
|
import com.bernard.util.BytesUtils;
|
||||||
|
|
||||||
public class MicServer {
|
public class MicServer {
|
||||||
|
|
||||||
|
|||||||
@ -14,8 +14,8 @@ import java.util.UUID;
|
|||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import com.bernard.murder.BytesUtils;
|
import com.bernard.util.BytesUtils;
|
||||||
import com.bernard.murder.ParseUtils;
|
import com.bernard.util.ParseUtils;
|
||||||
|
|
||||||
public class Serveur {
|
public class Serveur {
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import java.util.function.Consumer;
|
|||||||
import javax.sound.sampled.LineUnavailableException;
|
import javax.sound.sampled.LineUnavailableException;
|
||||||
import javax.sound.sampled.SourceDataLine;
|
import javax.sound.sampled.SourceDataLine;
|
||||||
|
|
||||||
import com.bernard.murder.BytesUtils;
|
import com.bernard.util.BytesUtils;
|
||||||
|
|
||||||
|
|
||||||
public class SpeakerServer {
|
public class SpeakerServer {
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
package com.bernard.murder.game;
|
package com.bernard.murder.game;
|
||||||
|
|
||||||
import static com.bernard.murder.ParseUtils.mappingStringKeys;
|
import static com.bernard.util.ParseUtils.mappingStringKeys;
|
||||||
import static com.bernard.murder.ParseUtils.parseTimeLength;
|
import static com.bernard.util.ParseUtils.parseTimeLength;
|
||||||
import static com.bernard.murder.ParseUtils.sequenceStream;
|
import static com.bernard.util.ParseUtils.sequenceStream;
|
||||||
|
import static com.bernard.util.ParseUtils.watch;
|
||||||
import static com.bernard.murder.ParseUtils.watch;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
@ -27,13 +26,13 @@ import com.amihaiemil.eoyaml.YamlMappingBuilder;
|
|||||||
import com.amihaiemil.eoyaml.YamlNode;
|
import com.amihaiemil.eoyaml.YamlNode;
|
||||||
import com.amihaiemil.eoyaml.YamlPrinter;
|
import com.amihaiemil.eoyaml.YamlPrinter;
|
||||||
import com.amihaiemil.eoyaml.YamlSequence;
|
import com.amihaiemil.eoyaml.YamlSequence;
|
||||||
import com.bernard.murder.ParseUtils;
|
|
||||||
import com.bernard.murder.model.Action;
|
import com.bernard.murder.model.Action;
|
||||||
import com.bernard.murder.model.Objet;
|
import com.bernard.murder.model.Objet;
|
||||||
import com.bernard.murder.model.Partie;
|
import com.bernard.murder.model.Partie;
|
||||||
import com.bernard.murder.model.Personnage;
|
import com.bernard.murder.model.Personnage;
|
||||||
import com.bernard.murder.model.Piece;
|
import com.bernard.murder.model.Piece;
|
||||||
import com.bernard.murder.model.Status;
|
import com.bernard.murder.model.Status;
|
||||||
|
import com.bernard.util.ParseUtils;
|
||||||
|
|
||||||
public class GameCreator {
|
public class GameCreator {
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,8 @@ package com.bernard.murder.view;
|
|||||||
|
|
||||||
import java.awt.GridLayout;
|
import java.awt.GridLayout;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -15,25 +17,80 @@ import javax.swing.JPanel;
|
|||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.UnsupportedLookAndFeelException;
|
import javax.swing.UnsupportedLookAndFeelException;
|
||||||
|
|
||||||
|
import com.amihaiemil.eoyaml.Yaml;
|
||||||
|
import com.amihaiemil.eoyaml.YamlNode;
|
||||||
|
import com.amihaiemil.eoyaml.YamlPrinter;
|
||||||
|
import com.bernard.configurator.Configurator;
|
||||||
|
import com.bernard.murder.Parametres;
|
||||||
import com.bernard.murder.game.GameCreator;
|
import com.bernard.murder.game.GameCreator;
|
||||||
import com.bernard.murder.game.GameCreator.QuicksavedPartie;
|
import com.bernard.murder.game.GameCreator.QuicksavedPartie;
|
||||||
import com.bernard.murder.game.GameManager;
|
import com.bernard.murder.game.GameManager;
|
||||||
import com.bernard.murder.model.Partie;
|
import com.bernard.murder.model.Partie;
|
||||||
import com.bernard.murder.model.Personnage;
|
import com.bernard.murder.model.Personnage;
|
||||||
import com.bernard.murder.view.minel.Minel;
|
import com.bernard.murder.view.minel.Minel;
|
||||||
|
import com.formdev.flatlaf.FlatDarculaLaf;
|
||||||
|
import com.formdev.flatlaf.FlatDarkLaf;
|
||||||
|
import com.formdev.flatlaf.FlatIntelliJLaf;
|
||||||
|
import com.formdev.flatlaf.FlatLightLaf;
|
||||||
|
|
||||||
public class LauncherFrame extends JFrame{
|
public class LauncherFrame extends JFrame{
|
||||||
|
|
||||||
private static final long serialVersionUID = 5831232688024137883L;
|
private static final long serialVersionUID = 5831232688024137883L;
|
||||||
|
|
||||||
|
public static final String paramPath = "./murderator-config.yml";
|
||||||
|
|
||||||
|
public static void main2(String[] args) throws IOException {
|
||||||
|
File test = new File("/tmp/test.yml");
|
||||||
|
YamlPrinter yp = Yaml.createYamlPrinter(new FileWriter(test));
|
||||||
|
YamlNode theNode = Configurator.objectToNode(new Parametres());
|
||||||
|
System.out.println(theNode);
|
||||||
|
yp.print(theNode);
|
||||||
|
System.out.println("--------------------------------------------");
|
||||||
|
System.out.println("On tente de relire ...");
|
||||||
|
Parametres params = Configurator.readYaml(theNode, Parametres.class);
|
||||||
|
System.out.println(params);
|
||||||
|
System.out.println("Terminé !");
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
File paramFile = new File(LauncherFrame.paramPath);
|
||||||
|
if(!paramFile.exists()) {
|
||||||
|
try {
|
||||||
|
YamlPrinter yp = Yaml.createYamlPrinter(new FileWriter(paramFile));
|
||||||
|
yp.print(Configurator.objectToNode(new Parametres()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
YamlNode theConf = Yaml.createYamlInput(paramFile).readYamlMapping();
|
||||||
|
Parametres.instance = (Parametres)Configurator.readYaml(theConf, Parametres.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("Impossible de lire les paramètres, on tombe sur les défauts.");
|
||||||
|
e.printStackTrace();
|
||||||
|
Parametres.instance = new Parametres();
|
||||||
|
}
|
||||||
new LauncherFrame();
|
new LauncherFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
public LauncherFrame() {
|
public LauncherFrame() {
|
||||||
try {
|
try {
|
||||||
//TODO implement flatlaf look&feel
|
//TODO implement flatlaf look&feel
|
||||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
if(Parametres.instance.lookAndFeel==null)
|
||||||
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
|
else
|
||||||
|
switch(Parametres.instance.lookAndFeel) {
|
||||||
|
case "flatlaf-light":
|
||||||
|
FlatLightLaf.install();break;
|
||||||
|
case "flatlaf-dark":
|
||||||
|
FlatDarkLaf.install();break;
|
||||||
|
case "flatlaf-intelliJ":
|
||||||
|
FlatIntelliJLaf.install();break;
|
||||||
|
case "flatlaf-darcula":
|
||||||
|
FlatDarculaLaf.install();break;
|
||||||
|
default:
|
||||||
|
UIManager.setLookAndFeel(Parametres.instance.lookAndFeel);
|
||||||
|
}
|
||||||
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e1) {
|
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e1) {
|
||||||
e1.printStackTrace();
|
e1.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import com.amihaiemil.eoyaml.YamlMapping;
|
|||||||
import com.amihaiemil.eoyaml.YamlMappingBuilder;
|
import com.amihaiemil.eoyaml.YamlMappingBuilder;
|
||||||
import com.amihaiemil.eoyaml.YamlNode;
|
import com.amihaiemil.eoyaml.YamlNode;
|
||||||
import com.amihaiemil.eoyaml.YamlSequence;
|
import com.amihaiemil.eoyaml.YamlSequence;
|
||||||
import com.bernard.murder.YamlUtils;
|
|
||||||
import com.bernard.murder.game.GameCreator.QuicksavedPartie;
|
import com.bernard.murder.game.GameCreator.QuicksavedPartie;
|
||||||
import com.bernard.murder.game.GameManager;
|
import com.bernard.murder.game.GameManager;
|
||||||
import com.bernard.murder.model.Partie;
|
import com.bernard.murder.model.Partie;
|
||||||
@ -25,6 +24,7 @@ import com.bernard.murder.view.minel.Minel;
|
|||||||
import com.bernard.murder.view.minel.ObjetSearchMinel;
|
import com.bernard.murder.view.minel.ObjetSearchMinel;
|
||||||
import com.bernard.murder.view.minel.ServeurMinel;
|
import com.bernard.murder.view.minel.ServeurMinel;
|
||||||
import com.bernard.murder.view.minel.TextPanMinel;
|
import com.bernard.murder.view.minel.TextPanMinel;
|
||||||
|
import com.bernard.util.YamlUtils;
|
||||||
|
|
||||||
public class MinelsCreator {
|
public class MinelsCreator {
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,6 @@ import javax.swing.JScrollPane;
|
|||||||
import javax.swing.JTabbedPane;
|
import javax.swing.JTabbedPane;
|
||||||
|
|
||||||
import com.bernard.murder.Parametres;
|
import com.bernard.murder.Parametres;
|
||||||
import com.bernard.murder.ParseUtils;
|
|
||||||
import com.bernard.murder.game.GameCreator.QuicksavedPartie;
|
import com.bernard.murder.game.GameCreator.QuicksavedPartie;
|
||||||
import com.bernard.murder.game.GameManager;
|
import com.bernard.murder.game.GameManager;
|
||||||
import com.bernard.murder.model.Partie;
|
import com.bernard.murder.model.Partie;
|
||||||
@ -24,6 +23,7 @@ import com.bernard.murder.model.Personnage;
|
|||||||
import com.bernard.murder.util.view.MouseReactiveTabbedPane;
|
import com.bernard.murder.util.view.MouseReactiveTabbedPane;
|
||||||
import com.bernard.murder.util.view.ScrollablePanel;
|
import com.bernard.murder.util.view.ScrollablePanel;
|
||||||
import com.bernard.murder.view.minel.Minel;
|
import com.bernard.murder.view.minel.Minel;
|
||||||
|
import com.bernard.util.ParseUtils;
|
||||||
|
|
||||||
public class MurderatorGameFrame extends JFrame{
|
public class MurderatorGameFrame extends JFrame{
|
||||||
|
|
||||||
@ -70,18 +70,18 @@ public class MurderatorGameFrame extends JFrame{
|
|||||||
for(String s : minelsSup.keySet()) {
|
for(String s : minelsSup.keySet()) {
|
||||||
//Calcul des dimensions max
|
//Calcul des dimensions max
|
||||||
int minelCount = minelsSup.get(s).size();
|
int minelCount = minelsSup.get(s).size();
|
||||||
int lincount = (int) Math.ceil(((double)minelCount)/((double)Parametres.minielParLigne));
|
int lincount = (int) Math.ceil(((double)minelCount)/((double)Parametres.instance.minielParLigne));
|
||||||
ScrollablePanel centralLocalBpanPan = new ScrollablePanel(new GridLayout(lincount,Parametres.minielParLigne,-1,-1));
|
ScrollablePanel centralLocalBpanPan = new ScrollablePanel(new GridLayout(lincount,Parametres.instance.minielParLigne,-1,-1));
|
||||||
centralLocalBpanPan.setScrollableWidth( ScrollablePanel.ScrollableSizeHint.FIT );
|
centralLocalBpanPan.setScrollableWidth( ScrollablePanel.ScrollableSizeHint.FIT );
|
||||||
minelsSup.get(s).stream()
|
minelsSup.get(s).stream()
|
||||||
.map(m -> m.genContentPane())
|
.map(m -> m.genContentPane())
|
||||||
.forEach(mpan -> {
|
.forEach(mpan -> {
|
||||||
centralLocalBpanPan.add(mpan);
|
centralLocalBpanPan.add(mpan);
|
||||||
mpan.setBorder(BorderFactory.createLineBorder(ParseUtils.randDarkBlueColor(),3));
|
mpan.setBorder(BorderFactory.createLineBorder(ParseUtils.randDarkBlueColor(),3));
|
||||||
mpan.setMinimumSize(Parametres.minielMinSize);
|
mpan.setMinimumSize(Parametres.instance.minielMinSize);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
if(lincount > Parametres.lignesDeMinielAvantScroll) {
|
if(lincount > Parametres.instance.lignesDeMinielAvantScroll) {
|
||||||
|
|
||||||
JScrollPane jsp = new JScrollPane(centralLocalBpanPan,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
JScrollPane jsp = new JScrollPane(centralLocalBpanPan,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
||||||
centerPan.insertTab(s,null,jsp,null,j++);
|
centerPan.insertTab(s,null,jsp,null,j++);
|
||||||
@ -93,19 +93,19 @@ public class MurderatorGameFrame extends JFrame{
|
|||||||
|
|
||||||
//Calcul des dimensions max
|
//Calcul des dimensions max
|
||||||
int minelCount = minels.get(p).size();
|
int minelCount = minels.get(p).size();
|
||||||
int lincount = (int) Math.ceil(((double)minelCount)/((double)Parametres.minielParLigne));
|
int lincount = (int) Math.ceil(((double)minelCount)/((double)Parametres.instance.minielParLigne));
|
||||||
ScrollablePanel centralLocalBpanPan = new ScrollablePanel(new GridLayout(lincount,Parametres.minielParLigne,-1,-1));
|
ScrollablePanel centralLocalBpanPan = new ScrollablePanel(new GridLayout(lincount,Parametres.instance.minielParLigne,-1,-1));
|
||||||
centralLocalBpanPan.setScrollableWidth( ScrollablePanel.ScrollableSizeHint.FIT );
|
centralLocalBpanPan.setScrollableWidth( ScrollablePanel.ScrollableSizeHint.FIT );
|
||||||
minels.get(p).stream()
|
minels.get(p).stream()
|
||||||
.map(m -> m.genContentPane())
|
.map(m -> m.genContentPane())
|
||||||
.forEach(mpan -> {
|
.forEach(mpan -> {
|
||||||
centralLocalBpanPan.add(mpan);
|
centralLocalBpanPan.add(mpan);
|
||||||
mpan.setBorder(BorderFactory.createLineBorder(ParseUtils.randDarkBlueColor(),3));
|
mpan.setBorder(BorderFactory.createLineBorder(ParseUtils.randDarkBlueColor(),3));
|
||||||
mpan.setMinimumSize(Parametres.minielMinSize);
|
mpan.setMinimumSize(Parametres.instance.minielMinSize);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if(lincount > Parametres.lignesDeMinielAvantScroll) {
|
if(lincount > Parametres.instance.lignesDeMinielAvantScroll) {
|
||||||
JScrollPane jsp = new JScrollPane(centralLocalBpanPan,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
JScrollPane jsp = new JScrollPane(centralLocalBpanPan,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
||||||
centerPan.insertTab(p.getNom(),null,jsp,null,j++);
|
centerPan.insertTab(p.getNom(),null,jsp,null,j++);
|
||||||
} else
|
} else
|
||||||
|
|||||||
@ -26,10 +26,10 @@ import com.amihaiemil.eoyaml.Yaml;
|
|||||||
import com.amihaiemil.eoyaml.YamlMapping;
|
import com.amihaiemil.eoyaml.YamlMapping;
|
||||||
import com.amihaiemil.eoyaml.YamlMappingBuilder;
|
import com.amihaiemil.eoyaml.YamlMappingBuilder;
|
||||||
import com.bernard.murder.Parametres;
|
import com.bernard.murder.Parametres;
|
||||||
import com.bernard.murder.ParseUtils;
|
|
||||||
import com.bernard.murder.game.GameManager;
|
import com.bernard.murder.game.GameManager;
|
||||||
import com.bernard.murder.model.Action;
|
import com.bernard.murder.model.Action;
|
||||||
import com.bernard.murder.model.Personnage;
|
import com.bernard.murder.model.Personnage;
|
||||||
|
import com.bernard.util.ParseUtils;
|
||||||
|
|
||||||
public class ActionsMinel extends Minel {
|
public class ActionsMinel extends Minel {
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ public class ActionsMinel extends Minel {
|
|||||||
JScrollPane globalScroll = new JScrollPane(actionsListPan);
|
JScrollPane globalScroll = new JScrollPane(actionsListPan);
|
||||||
|
|
||||||
JLabel titre = new JLabel("Actions de "+personnage.getNom(),JLabel.CENTER);
|
JLabel titre = new JLabel("Actions de "+personnage.getNom(),JLabel.CENTER);
|
||||||
titre.setFont(Parametres.minielTitleFont);
|
titre.setFont(Parametres.instance.minielTitleFont);
|
||||||
titre.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
|
titre.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
|
||||||
|
|
||||||
globalPan.add(titre,BorderLayout.NORTH);
|
globalPan.add(titre,BorderLayout.NORTH);
|
||||||
|
|||||||
@ -54,7 +54,7 @@ public class InventaireMinel extends Minel {
|
|||||||
titre = new JLabel(inv.getInventoryName(),JLabel.CENTER);
|
titre = new JLabel(inv.getInventoryName(),JLabel.CENTER);
|
||||||
else
|
else
|
||||||
titre = new JLabel("Inventaire",JLabel.CENTER);
|
titre = new JLabel("Inventaire",JLabel.CENTER);
|
||||||
titre.setFont(Parametres.minielTitleFont);
|
titre.setFont(Parametres.instance.minielTitleFont);
|
||||||
titre.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
|
titre.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
|
||||||
globalpan.add(titre, BorderLayout.NORTH);
|
globalpan.add(titre, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
|||||||
@ -23,12 +23,12 @@ import com.amihaiemil.eoyaml.YamlMapping;
|
|||||||
import com.amihaiemil.eoyaml.YamlMappingBuilder;
|
import com.amihaiemil.eoyaml.YamlMappingBuilder;
|
||||||
import com.amihaiemil.eoyaml.YamlNode;
|
import com.amihaiemil.eoyaml.YamlNode;
|
||||||
import com.bernard.murder.Parametres;
|
import com.bernard.murder.Parametres;
|
||||||
import com.bernard.murder.ParseUtils;
|
|
||||||
import com.bernard.murder.YamlUtils;
|
|
||||||
import com.bernard.murder.game.GameManager;
|
import com.bernard.murder.game.GameManager;
|
||||||
import com.bernard.murder.model.Inventaire;
|
import com.bernard.murder.model.Inventaire;
|
||||||
import com.bernard.murder.model.Objet;
|
import com.bernard.murder.model.Objet;
|
||||||
import com.bernard.murder.util.view.SimpleDocumentListener;
|
import com.bernard.murder.util.view.SimpleDocumentListener;
|
||||||
|
import com.bernard.util.ParseUtils;
|
||||||
|
import com.bernard.util.YamlUtils;
|
||||||
|
|
||||||
public class ObjetSearchMinel extends Minel {
|
public class ObjetSearchMinel extends Minel {
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ public class ObjetSearchMinel extends Minel {
|
|||||||
JPanel globalPan = new JPanel(new BorderLayout());
|
JPanel globalPan = new JPanel(new BorderLayout());
|
||||||
|
|
||||||
JLabel titre = new JLabel("Recherche d'objets",JLabel.CENTER);
|
JLabel titre = new JLabel("Recherche d'objets",JLabel.CENTER);
|
||||||
titre.setFont(Parametres.minielTitleFont);
|
titre.setFont(Parametres.instance.minielTitleFont);
|
||||||
|
|
||||||
JPanel panel = new JPanel(new BorderLayout());
|
JPanel panel = new JPanel(new BorderLayout());
|
||||||
panel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
|
panel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
|
||||||
|
|||||||
@ -54,7 +54,7 @@ public class ServeurMinel extends Minel {
|
|||||||
JPanel panel = new JPanel(new BorderLayout());
|
JPanel panel = new JPanel(new BorderLayout());
|
||||||
|
|
||||||
JLabel titre = new JLabel("Status du serveur",JLabel.CENTER);
|
JLabel titre = new JLabel("Status du serveur",JLabel.CENTER);
|
||||||
titre.setFont(Parametres.minielTitleFont);
|
titre.setFont(Parametres.instance.minielTitleFont);
|
||||||
titre.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
|
titre.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
|
||||||
|
|
||||||
micListe = new JList<>();
|
micListe = new JList<>();
|
||||||
|
|||||||
@ -33,7 +33,7 @@ public class TextPanMinel extends Minel {
|
|||||||
JPanel globalPan = new JPanel(new BorderLayout());
|
JPanel globalPan = new JPanel(new BorderLayout());
|
||||||
|
|
||||||
JLabel titre = new JLabel("Notes",JLabel.CENTER);
|
JLabel titre = new JLabel("Notes",JLabel.CENTER);
|
||||||
titre.setFont(Parametres.minielTitleFont);
|
titre.setFont(Parametres.instance.minielTitleFont);
|
||||||
titre.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
|
titre.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
|
||||||
|
|
||||||
|
|
||||||
@ -42,8 +42,8 @@ public class TextPanMinel extends Minel {
|
|||||||
textArea.setText("");
|
textArea.setText("");
|
||||||
textArea.setLineWrap(true);
|
textArea.setLineWrap(true);
|
||||||
|
|
||||||
textArea.setBackground(Parametres.textPanMinielBackgroundColor);
|
textArea.setBackground(Parametres.instance.textPanMinielBackgroundColor);
|
||||||
textArea.setForeground(Parametres.textPanMinielTextColor);
|
textArea.setForeground(Parametres.instance.textPanMinielTextColor);
|
||||||
|
|
||||||
globalPan.add(titre,BorderLayout.NORTH);
|
globalPan.add(titre,BorderLayout.NORTH);
|
||||||
globalPan.add(new JScrollPane(textArea),BorderLayout.CENTER);
|
globalPan.add(new JScrollPane(textArea),BorderLayout.CENTER);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user