Commit 0b6ac1b7 authored by fpeterfalvi's avatar fpeterfalvi
Browse files

Observer displays multiple choice questions

parent 41c1b120
......@@ -5,3 +5,4 @@
/KvizServer/.idea/codeStyles/Project.xml
/KvizServer/.idea/caches/build_file_checksums.ser
/KvizClient/.idea/codeStyles/Project.xml
/KvizClient/app/src/main/java/onlab/kvizclient/LobbyActivity.java.orig
......@@ -169,13 +169,15 @@ public class MultipleChoiceFragment extends Fragment {
LinearLayout multipleChoiceFragmentLinearLayout = (LinearLayout) getView().findViewById(R.id.MultipleChoiceFragmentLinearLayout);
for (int i=0;i<playerAnswers.size();i++) {
if (i != own_index) {
final TextView playerAnswerTextView = new TextView(getActivity());
PlayerAnswer answer = playerAnswers.get(i);
playerAnswerTextView.setText(answer.getPlayerName() + ": "
+ answers[answer.getValue()]);
playerAnswerTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
playerAnswerTextView.setPadding(20,30,20,0);
multipleChoiceFragmentLinearLayout.addView(playerAnswerTextView);
if (answer.getValue() > -1) {
final TextView playerAnswerTextView = new TextView(getActivity());
playerAnswerTextView.setText(answer.getPlayerName() + ": "
+ answers[answer.getValue()]);
playerAnswerTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
playerAnswerTextView.setPadding(20,30,20,0);
multipleChoiceFragmentLinearLayout.addView(playerAnswerTextView);
}
}
}
}
......
......@@ -66,6 +66,11 @@ The project was originally started in December 2002 by Arthur van Hoff at Strang
<version>3.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.3</version>
</dependency>
</dependencies>
<build>
<resources>
......
public interface FontResizable {
public void setFontSize(int fontSize);
}
......@@ -10,9 +10,6 @@ import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import javax.jmdns.JmDNS;
import javax.jmdns.ServiceEvent;
......@@ -21,8 +18,12 @@ import javax.jmdns.ServiceListener;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import com.google.gson.Gson;
import model.PlayerAnswer;
import model.ServerModel;
import java.util.List;
public class Main {
private String TAG = "Client";
......@@ -49,6 +50,7 @@ public class Main {
private static JFrame frame;
private static JPanel mainPanel;
private static JPanel serverListPanel;
private static FontResizable actualFontResizable = null;
private static class SampleListener implements ServiceListener {
@Override
......@@ -113,71 +115,65 @@ public class Main {
threads = new ArrayList<Thread>();
frame = new JFrame("KvizObserver");
mainPanel = new JPanel(new CardLayout());
mainPanel = new JPanel(new BorderLayout());
JPanel observerNamePanel = new JPanel();
observerNamePanel.setBorder(new EmptyBorder(20, 20, 20, 20));
observerNamePanel.setLayout(new BoxLayout(observerNamePanel, BoxLayout.Y_AXIS));
JLabel observerNameLabel = new JLabel("Observer name:");
observerNamePanel.add(observerNameLabel);
JTextField observerNameTextField = new JTextField();
observerNameTextField.setMaximumSize(new Dimension(200, 100));
observerNamePanel.add(observerNameTextField);
JButton startSearchingButton = new JButton("Start searching servers");
startSearchingButton.addActionListener(new StartSearchingButtonListener(observerNameTextField));
observerNamePanel.add(startSearchingButton);
mainPanel.add(observerNamePanel, "OBSERVER_NAME_PANEL");
mainPanel.add(observerNamePanel);
serverListPanel = new JPanel();
serverListPanel.setLayout(new BoxLayout(serverListPanel, BoxLayout.Y_AXIS));
mainPanel.add(serverListPanel, "SERVER_LIST_PANEL");
JMenuItem fontSizeMenuItem = new JMenuItem("Font size");
fontSizeMenuItem.addActionListener(new setFontSizeButtonListener()); // adding listener
JMenu menu = new JMenu("Menu");
menu.add(fontSizeMenuItem);
JMenuBar bar = new JMenuBar();
bar.add(menu);
frame.setJMenuBar(bar);
frame.add(mainPanel, BorderLayout.NORTH);
frame.setPreferredSize(new Dimension(300, 200));
frame.setPreferredSize(new Dimension(600, 400));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
//try {
//System.out.println("Set The ObserverName:");
//Scanner s = new Scanner(System.in);
//CLIENT_NAME = s.nextLine();
// Create a JmDNS instance
//JmDNS jmdns = JmDNS.create(InetAddress.getLocalHost());
// Add a service listener
//jmdns.addServiceListener("_http._tcp.local.", new SampleListener());
// Wait a bit
//Thread.sleep(3000);
//String msg = "";
/*Scanner s = new Scanner(System.in);
System.out.println("Type 'Connect' to Connect:");
msg = s.nextLine();
if(msg.equals("Connect"))
{
onConnect(0);
}
System.out.println("Type 'Disconnect' to Disconnect:");
msg = s.nextLine();
if(msg.equals("Disconnect"))
{
onDisconnect();
}*/
/*} catch (UnknownHostException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());*/
//}
//teszteléshez
/*
PlayerAnswer pla = new PlayerAnswer("játékos");
pla.setValue(2);
pla.setTime(3.3);
PlayerAnswer pla2 = new PlayerAnswer("játékos2");
pla2.setValue(2);
pla2.setTime(3.3);
PlayerAnswer pla3 = new PlayerAnswer("játékos3");
pla3.setValue(2);
pla3.setTime(3.3);
List<PlayerAnswer> plalist = new ArrayList<>();
plalist.add(pla);
plalist.add(pla2);
plalist.add(pla3);
Gson gson = new Gson();
MultipleChoiceQuestionPanel mcqp = new MultipleChoiceQuestionPanel("Melyik a leghosszabb szó? Melyik? Melyik? Melyik? Melyik?", "alma",
"paradicsom", "görögdinnye", "őszibarack", gson.toJson(plalist), 1, -1);
actualFontResizable = mcqp;
mainPanel.removeAll();
mainPanel.add(mcqp);
mainPanel.revalidate();
mainPanel.repaint();
*/
}
final static class StartSearchingButtonListener implements ActionListener {
......@@ -187,8 +183,10 @@ public class Main {
}
public void actionPerformed(ActionEvent ae) {
CLIENT_NAME = tf.getText();
CardLayout cl = (CardLayout)(mainPanel.getLayout());
cl.show(mainPanel, "SERVER_LIST_PANEL");
mainPanel.removeAll();
mainPanel.add(serverListPanel);
mainPanel.revalidate();
mainPanel.repaint();
try {
// Create a JmDNS instance
......@@ -260,6 +258,25 @@ public class Main {
}
}
static class setFontSizeButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String s = (String) JOptionPane.showInputDialog(
frame,
"Font size: ",
"Set font size",
JOptionPane.PLAIN_MESSAGE,
null,
null,null);
if (s != null) {
actualFontResizable.setFontSize(Integer.parseInt(s));
System.out.println("Új betűméret: " + s);
return;
}
}
}
class CommunicationThread implements Runnable {
private ServerModel serverModel;
......@@ -328,6 +345,17 @@ public class Main {
exit = false;
//majd
break;
case "questionMC":
case "answerMC":
MultipleChoiceQuestionPanel mcqp = new MultipleChoiceQuestionPanel(params[1], params[2],
params[3], params[4], params[5], params[6], Integer.parseInt(params[7]),
Integer.parseInt(params[8]));
actualFontResizable = mcqp;
mainPanel.removeAll();
mainPanel.add(mcqp);
mainPanel.revalidate();
mainPanel.repaint();
break;
case "Disconnect":
break;
default:
......
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import javafx.scene.control.ProgressBar;
import model.PlayerAnswer;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
public class MultipleChoiceQuestionPanel extends JPanel implements FontResizable {
private static final String LEFT_ARROW_PATH = "src/images/arrow_left.png";
private static final String RIGHT_ARROW_PATH = "src/images/arrow_right.png";
private JProgressBar progressBar;
private static float fontSize = 60.0f;
private int arrowSize;
private String question;
private String answer1;
private String answer2;
private String answer3;
private String answer4;
private String playerAnswersString;
private int correctAnswer;
private int timeOut;
public MultipleChoiceQuestionPanel(String question, String answer1, String answer2, String answer3, String answer4,
String playerAnswersString, int correctAnswer, int timeOut) {
this.question = question;
this.answer1 = answer1;
this.answer2 = answer2;
this.answer3 = answer3;
this.answer4 = answer4;
this.playerAnswersString = playerAnswersString;
this.correctAnswer = correctAnswer;
this.timeOut = timeOut;
initialize();
if (timeOut > -1) {
ProgressBarThread pbt = new ProgressBarThread();
Thread progressBarThread = new Thread(pbt);
progressBarThread.start();
}
}
class ProgressBarThread implements Runnable {
private long startTime;
public ProgressBarThread() {
startTime = new Date().getTime();
}
@Override
public void run() {
long currentTime = new Date().getTime();
while (currentTime - startTime < timeOut) {
progressBar.setValue((int) (timeOut - currentTime + startTime));
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
currentTime = new Date().getTime();
}
}
}
private void initialize() {
this.removeAll();
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
if (timeOut > -1) {
progressBar = new JProgressBar(0, timeOut);
this.add(progressBar);
}
JTextArea questionTextArea = new JTextArea(question);
questionTextArea.setBackground(this.getBackground());
questionTextArea.setBorder(new EmptyBorder(20,20,20,20));
questionTextArea.setEditable(false);
questionTextArea.setWrapStyleWord(true);
questionTextArea.setLineWrap(true);
Font bigFont = questionTextArea.getFont().deriveFont(fontSize);
questionTextArea.setFont(bigFont);
questionTextArea.setAlignmentX(Component.LEFT_ALIGNMENT);
this.add(questionTextArea);
JLabel[] answerLabels = new JLabel[4];
JLabel[] leftArrows = new JLabel[4];
JLabel[] rightArrows = new JLabel[4];
String[] answers = new String[4];
answers[0] = answer1;
answers[1] = answer2;
answers[2] = answer3;
answers[3] = answer4;
arrowSize = (int) (192 * fontSize / 200);
for (int i=0;i<4;i++) {
JPanel answerPanel = new JPanel(new FlowLayout());
answerPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
leftArrows[i] = new JLabel();
leftArrows[i].setPreferredSize(new Dimension(arrowSize, arrowSize));
answerLabels[i] = new JLabel(answers[i]);
answerLabels[i].setFont(bigFont);
answerLabels[i].setMinimumSize(new Dimension((int) (10 * fontSize), (int) (1.1 * fontSize)));
answerLabels[i].setPreferredSize(new Dimension((int) (10 * fontSize), (int) (1.1 * fontSize)));
answerLabels[i].setMaximumSize(new Dimension((int) (10 * fontSize), (int) (1.1 * fontSize)));
answerLabels[i].setHorizontalAlignment(JLabel.CENTER);
rightArrows[i] = new JLabel();
rightArrows[i].setPreferredSize(new Dimension(arrowSize, arrowSize));
answerPanel.add(leftArrows[i]);
answerPanel.add(answerLabels[i]);
answerPanel.add(rightArrows[i]);
this.add(answerPanel);
}
Gson gson = new Gson();
Type collectionType = new TypeToken<Collection<PlayerAnswer>>(){}.getType();
Collection<PlayerAnswer> playerAnswerCollection = gson.fromJson(playerAnswersString, collectionType);
List<PlayerAnswer> playerAnswers = new ArrayList<PlayerAnswer>(playerAnswerCollection);
if (correctAnswer > -1) {
answerLabels[correctAnswer].setBackground(Color.GREEN);
answerLabels[correctAnswer].setOpaque(true);
}
if (playerAnswers.size() <= 2) {
int firstPlayerAnswer = playerAnswers.get(0).getValue();
if (firstPlayerAnswer > -1) {
try {
BufferedImage img = null;
img = ImageIO.read(new File(RIGHT_ARROW_PATH));
img = resizeImage(img, arrowSize, arrowSize);
ImageIcon icon = new ImageIcon(img);
leftArrows[firstPlayerAnswer].setIcon(icon);
} catch (IOException e) {
e.printStackTrace();
}
if (firstPlayerAnswer != correctAnswer) {
answerLabels[firstPlayerAnswer].setBackground(Color.RED);
answerLabels[firstPlayerAnswer].setOpaque(true);
}
}
if (playerAnswers.size() == 2) {
int secondPlayerAnswer = playerAnswers.get(1).getValue();
if (secondPlayerAnswer > -1) {
try {
BufferedImage img = null;
img = ImageIO.read(new File(LEFT_ARROW_PATH));
img = resizeImage(img, arrowSize, arrowSize);
ImageIcon icon = new ImageIcon(img);
rightArrows[secondPlayerAnswer].setIcon(icon);
} catch (IOException e) {
e.printStackTrace();
}
if (firstPlayerAnswer != correctAnswer) {
answerLabels[secondPlayerAnswer].setBackground(Color.RED);
answerLabels[secondPlayerAnswer].setOpaque(true);
}
}
}
}
if (playerAnswers.size() > 2) {
for (int i=0;i<playerAnswers.size();i++) {
JLabel playerAnswerLabel = new JLabel();
playerAnswerLabel.setFont(bigFont);
playerAnswerLabel.setMinimumSize(new Dimension((int) (10 * fontSize), (int) (1.1 * fontSize)));
playerAnswerLabel.setPreferredSize(new Dimension((int) (10 * fontSize), (int) (1.1 * fontSize)));
playerAnswerLabel.setMaximumSize(new Dimension((int) (10 * fontSize), (int) (1.1 * fontSize)));
playerAnswerLabel.setHorizontalAlignment(JLabel.CENTER);
PlayerAnswer answer = playerAnswers.get(i);
if (answer.getValue() > -1) {
playerAnswerLabel.setText(answer.getPlayerName() + ": "
+ answers[answer.getValue()]);
this.add(playerAnswerLabel);
}
}
}
}
public static BufferedImage resizeImage(BufferedImage img, int width, int height) {
Image tmp = img.getScaledInstance(width, height, Image.SCALE_SMOOTH);
BufferedImage dimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = dimg.createGraphics();
g2d.drawImage(tmp, 0, 0, null);
g2d.dispose();
return dimg;
}
@Override
public void setFontSize(int fontSize) {
this.fontSize = (float) fontSize;
initialize();
this.revalidate();
this.repaint();
}
}
package model;
public class PlayerAnswer {
private String playerName;
private int value = -1;
private double time = 0;
private boolean winner = false;
public PlayerAnswer(String playerName) {
this.playerName = playerName;
}
public String getPlayerName() {
return playerName;
}
public void setPlayerName(String playerName) {
this.playerName = playerName;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public double getTime() {
return time;
}
public void setTime(double time) {
this.time = time;
}
public boolean isWinner() {
return winner;
}
public void setWinner(boolean winner) {
this.winner = winner;
}
}
......@@ -78,6 +78,11 @@ public class GameActivity extends AppCompatActivity implements GameControlFragme
new OutputStreamWriter(ClientHolder.get(i).getClientsocket().getOutputStream())), true);
outputs.add(output);
}
for (int i=0;i<ObserverHolder.size();i++) {
PrintWriter output = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(ObserverHolder.get(i).getClientsocket().getOutputStream())), true);
outputs.add(output);
}
} catch (IOException e) {
e.printStackTrace();
}
......@@ -201,7 +206,7 @@ public class GameActivity extends AppCompatActivity implements GameControlFragme
}
String playerAnswersString = gson.toJson(playerAnswers);
for (int i=0;i<outputs.size();i++) {
for (int i=0;i<numberOfPlayers;i++) {
gameControlFragment.displayAnswerOfPlayer(i,"The answer of " + playerAnswers[i].getPlayerName() + ": ");
if (question.getType() == Question.MULTIPLE_CHOICE) {
String message = "questionMC##" + questionString + "##" + answers.get(0) + "##" + answers.get(1)
......@@ -213,6 +218,14 @@ public class GameActivity extends AppCompatActivity implements GameControlFragme
new SendMessageToClientTask().execute(Integer.toString(i), message);
}
}
for (int i=numberOfPlayers;i<outputs.size();i++) { //observerek
if (question.getType() == Question.MULTIPLE_CHOICE) {
String message = "questionMC##" + questionString + "##" + answers.get(0) + "##" + answers.get(1)
+ "##" + answers.get(2) + "##" + answers.get(3) + "##" + playerAnswersString
+ "##-1##" + Integer.toString(timeLimit);
new SendMessageToClientTask().execute(Integer.toString(i), message);
}
}
/*
gameControlFragment.displayEndOfGame();
......@@ -225,7 +238,7 @@ public class GameActivity extends AppCompatActivity implements GameControlFragme
@Override
public void correctAnswerButtonClicked() {
gameControlFragment.setCorrectAnswerButtonEnabled(false);
for (int i=0;i<outputs.size();i++) {
for (int i=0;i<numberOfPlayers;i++) {
if (answers.size() == 4) {
String playerAnswersString = gson.toJson(playerAnswers);
String message = "answerMC##" + questionString + "##" + answers.get(0) + "##" + answers.get(1)
......@@ -240,6 +253,16 @@ public class GameActivity extends AppCompatActivity implements GameControlFragme
new SendMessageToClientTask().execute(Integer.toString(i), message);
}
}
for (int i=numberOfPlayers;i<outputs.size();i++) { //observerek
if (question.getType() == Question.MULTIPLE_CHOICE) {
String playerAnswersString = gson.toJson(playerAnswers);
String message = "answerMC##" + questionString + "##" + answers.get(0) + "##" + answers.get(1)
+ "##" + answers.get(2) + "##" + answers.get(3) + "##" + playerAnswersString
+ "##" + Integer.toString(correctAnswer) + "##-1";
new SendMessageToClientTask().execute(Integer.toString(i), message);
}
}
}
@Override
......
......@@ -111,6 +111,7 @@ public class LobbyActivity extends AppCompatActivity {
commThread.interrupt();
}
ClientHolder.addAll(clients);
ObserverHolder.addAll(observers);
Intent intent;
if (gameMode.equals("normal")) {
intent = new Intent(getApplicationContext(), GameActivity.class);
......
package onlab.kvizserver;
import java.util.ArrayList;
import java.util.List;
import onlab.kvizserver.model.ClientModel;
public class ObserverHolder {
private static List<ClientModel> observers = new ArrayList<>();
public static void add(ClientModel clientModel) {
observers.add(clientModel);