I seem to be having some issues when using the JOptionPane.showMessageDialog() method.
When I use the method the only thing that is set up correctly is the dialogs title. It doesn't want to display the text that I provide.
Here's the code that I'm using to try and create an alert:
JOptionPane.showMessageDialog(null, "alert", "alert", JOptionPane.ERROR_MESSAGE);
The code above provides the image below:
If someone could tell me what I'm doing wrong or if there is a different method that I'm supposed to be using, I would much appreciate it.
Edit:
My main class:
This creates a GUI where the user enters information "Host" and "DisplayName". When they click "Connect" a new thread is created (the ClientConnectSocket).
public class Main extends JFrame {
public static JPanel contentPane;
private JTextField hostTxt;
public static JTextField displayNameTxt;
JLabel lblDisplayName = new JLabel("Display Name:");
JButton btnConnect = new JButton("Connect");
JLabel lblHost = new JLabel("Host:");
public static String username = "None :(";
public static String host = "localhost";
public static boolean connected = false;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main frame = new Main();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Main() {
setType(Type.UTILITY);
setTitle("Java Chat Client - v0.1");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 390, 200);
contentPane = new JPanel();
this.setResizable(false);
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
lblHost.setBounds(60, 11, 56, 19);
contentPane.add(lblHost);
hostTxt = new JTextField();
hostTxt.setBounds(165, 10, 103, 20);
contentPane.add(hostTxt);
hostTxt.setColumns(10);
btnConnect.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (hostTxt.getText() == null || displayNameTxt.getText() == null){
}else{
Thread ccs = new ClientConnectSocket(hostTxt.getText(), displayNameTxt.getText());
ccs.start();
while (!connected){
//System.out.println("Not connected yet..");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Yey, connected");
username = displayNameTxt.getText();
host = hostTxt.getText();
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Chat frame = new Chat();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
dispose();
}
}
});
btnConnect.setBounds((this.getWidth()/2)- 70, 76, 89, 23);
contentPane.add(btnConnect);
displayNameTxt = new JTextField();
displayNameTxt.setColumns(10);
displayNameTxt.setBounds(165, 45, 103, 20);
contentPane.add(displayNameTxt);
lblDisplayName.setBounds(60, 41, 95, 29);
contentPane.add(lblDisplayName);
this.getRootPane().setDefaultButton(btnConnect);
}
ClientConnectSocket class:
public class ClientConnectSocket extends Thread{
String host;
String name;
public ClientConnectSocket(String host, String displayName){
this.host = host;
this.name = displayName;
}
boolean b = true;
public void run(){
try{
while (b){
Socket server = new Socket(host, 6969);
System.out.println("Sending info to try and connect.");
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(server.getOutputStream()));
out.write("method=connect:displayName="+ name);
out.flush();
Thread.sleep(500);
InputStream in = server.getInputStream();
StringBuffer sb = new StringBuffer();
byte[] buffer = new byte[1024];
int buf;
while ((buf = in.read(buffer)) != -1){
String line = new String(buffer, 0, buf);
sb.append(line);
}
in.close();
System.out.println(sb.toString() + " || " + sb.toString().equalsIgnoreCase("connect"));
if (sb.toString().equalsIgnoreCase("connect")){
//Allow them to connect
Main.connected = true;
}else if(sb.toString().equalsIgnoreCase("invalid:Username")){
//Tell them they have username already taken;
JOptionPane.showMessageDialog(null, "alert", "alert", JOptionPane.ERROR_MESSAGE);
b = false;
}
server.close();
out.close();
in.close();
b = false;
}
}catch (Exception e){
System.exit(2);
e.printStackTrace();
}
}
Your posted code snippet suggests that you're running into a Swing threading issue. If your program is a Swing GUI, then most of the above code needs to be called off of the Swing EDT or Event Dispatch Thread, while any Swing calls, including displaying the JOptionPane should be called on the EDT. For more specific help, consider telling and showing more about your code and your use of background threading.
Edit
OK, so that code is in a background thread. So now you must take care to show your JOptionPane on the EDT. Consider making these changes:
} else if(sb.toString().equalsIgnoreCase("invalid:Username")) {
b = false;
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JOptionPane.showMessageDialog(null, "alert", "alert",
JOptionPane.ERROR_MESSAGE);
}
});
}
Note: code not tested by compiling or by running. Please be wary of typos.
Edit 2
As an aside, you've got other issues including that the connected variable should not be static. You also have threading issues:
btnConnect.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (hostTxt.getText() == null || displayNameTxt.getText() == null) {
} else {
// .........
// ********** you should not have this type of code on the EDT
while (!connected) {
// ........
}
// ...............
}
}
});
Related
I am creating a basic Java Visual Novel of sorts. It reads a text file and each line in the file is inserted into an ArrayList. By pressing the previous and next buttons, it changes the JTextArea into the next line or previous line.
Now, I want to use a timer so that it does the prev-next thing automatically. How do I go about doing that?
Here is my code:
public class FormativeAss1 {
URL ahaha = getClass().getClassLoader().getResource("ahaha.wav");
URL horror = getClass().getClassLoader().getResource("horror.wav");
URL clash = getClass().getClassLoader().getResource("clash.wav");
URL goriri = getClass().getClassLoader().getResource("goriri.wav");
URL impact = getClass().getClassLoader().getResource("impact.wav");
URL hakushu = getClass().getClassLoader().getResource("hakushu.wav");
JTextArea dialogue_label;
int secondsToWait = 5;
JButton nextButton, prevButton;
Timer tm;
private JFrame frame;
int IntegerQueue = -1;
JLabel Background;
int startedchecker = 0;
public void playSound(URL soundFile) {
try {
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundFile);
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
} catch (Exception ex) {
System.out.println("Error with playing sound.");
ex.printStackTrace();
}
}
public void IntegerQueueSound(int integer) {
switch (integer){
case 0:
playSound(clash);
break;
case 1:
playSound(horror);
break;
case 2:
playSound(ahaha);
break;
case 3:
playSound(impact);
break;
case 4:
playSound(hakushu);
break;
case 5:
playSound(goriri);
break;
case 6:
playSound(ahaha);
break;
}
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
FormativeAss1 window = new FormativeAss1();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public FormativeAss1() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 944, 595);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
frame.getContentPane().setFocusable(true);
frame.getContentPane().requestFocusInWindow();
JPanel panel = new JPanel();
panel.setBorder(UIManager.getBorder("DesktopIcon.border"));
panel.setBounds(10, 309, 908, 236);
frame.getContentPane().add(panel);
panel.setLayout(null);
dialogue_label = new JTextArea("Press \"Start Dialogue\" to start the novel.");
dialogue_label.setLineWrap(true);
dialogue_label.setWrapStyleWord(true);
dialogue_label.setColumns(1);
dialogue_label.setRows(4);
dialogue_label.setFont(new Font("Yu Gothic UI Semibold", Font.PLAIN, 20));
dialogue_label.setBounds(10, 11, 888, 214);
panel.add(dialogue_label);
JButton StartDialogueButton = new JButton("Start Dialogue");
StartDialogueButton.setBounds(10, 276, 142, 21);
frame.getContentPane().add(StartDialogueButton);
prevButton = new JButton("Previous");
prevButton.setBounds(162, 276, 85, 21);
frame.getContentPane().add(prevButton);
nextButton = new JButton("Next");
nextButton.setBounds(257, 276, 85, 21);
frame.getContentPane().add(nextButton);
JLabel Background = new JLabel("New label");
Background.setBounds(-381, -72, 1257, 1000);
frame.getContentPane().add(Background);
String strLine = "";
ArrayList < String > dialogue_List = new ArrayList < String > ();
ArrayList < String > scenery_List = new ArrayList < String > (Arrays.asList("images/bea.png",
"images/lam.png","images/but.png","images/enj.png","images/ros.png","images/eva.png"
,"images/ber.png", "images/kir.png"));
try {
BufferedReader br = new BufferedReader(new FileReader("C:\\Users\\Miko\\eclipse-workspace\\Fourth Quarter\\src\\FourthQuarter\\Script.txt"));
while (strLine != null) {
strLine = br.readLine();
if (strLine == null) {
break;
}
dialogue_List.add(strLine);}
br.close();
} catch (IOException e) {
System.err.println("Unable to read the file.");
}
ListIterator<String> it = dialogue_List.listIterator();
frame.getContentPane().setFocusable(true);
frame.getContentPane().requestFocusInWindow();
frame.getContentPane().addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
if(startedchecker==1){
int keyCode = e.getKeyCode();
if(keyCode == 37) {
IntegerQueue = IntegerQueue - 1;
if(IntegerQueue < 0) {
IntegerQueue = 0;
}
} else if(keyCode == 39) {
if (it.hasNext()) {
IntegerQueue = IntegerQueue + 1;}
dialogue_label.setText(dialogue_List.get(IntegerQueue));
Background.setIcon(new ImageIcon (scenery_List.get(IntegerQueue)));
IntegerQueueSound(IntegerQueue);
}
}
}
});
StartDialogueButton.addActionListener(new ActionListener() {
//depending on the IntegerQueue number, certain music or backgrounds will play at different intervals.
public void actionPerformed(ActionEvent arg0) {
startedchecker=1;
}
});
nextButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if(startedchecker==1) {
if (it.hasNext()) {
IntegerQueue = IntegerQueue + 1;
dialogue_label.setText(dialogue_List.get(IntegerQueue));
//IntegerQueue = IntegerQueue - 1;
System.out.println(IntegerQueue);
Background.setIcon(new ImageIcon (scenery_List.get(IntegerQueue)));
IntegerQueueSound(IntegerQueue);
}
}
}
});
prevButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg1) {
if(startedchecker==1&&IntegerQueue>0) {
IntegerQueue = IntegerQueue - 1;
dialogue_label.setText(dialogue_List.get(IntegerQueue));
System.out.println(IntegerQueue);
Background.setIcon(new ImageIcon (scenery_List.get(IntegerQueue)));
IntegerQueueSound(IntegerQueue);
}
}
});
}
}
if(keyCode == 37) {
...
} else if(keyCode == 39) {
Don't use "magic numbers". We don't know what a key code of 37 or 39 is. Instead use variable provided by the KeyEvent class like KeyEvent.VK_UP, KeyEvent.VK_DOWN. This makes the code self documenting so we know what keys you are listening for.
I want to use a timer so that it does the prev-next thing automatically
You need to refactor your code.
Your "next" and "previous" listeners need to be refactored into an Action. An Action is essentially the same as your ActionListener since it just implements the actionPerformed(...) method.
The benefit of the Action is that is can now be used by your JButton and by the Swing Timer and by using Key Bindings (which will replace your KeyListener).
Read the Swing tutorial. The following sections will help you solve your problem:
How to Use Actions
How to Use Key Bindings
How to Use Swing Timers
Hey all I am at a loss as to why its doing this. If I just run the server and standalone client it works just fine. However, once I use my code for the client it seems to get stuck...
static JTextField textField = null;
static JTextArea messageArea = null;
static String serverAddress = "localhost";
static UFTtrack window = null;
public static JFrame frame;
public ImageIcon[] images;
static JTable table;
Date lastUpdate;
static Timer timer;
static Scanner in;
static PrintWriter out;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#SuppressWarnings({ "static-access" })
public void run() {
try {
UIManager.setLookAndFeel(new MaterialLookAndFeel());
} catch (UnsupportedLookAndFeelException e1) {
e1.printStackTrace();
}
try {
window = new UFTtrack();
placeChatOnScreen();
createTable();
SystemTrayz.createTray();
centreWindow(frame);
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public UFTtrack() {
initialize();
}
private void initialize() {
frame = new JFrame("UFTtrack");
frame.setTitle("UFT Tracker");
frame.setResizable(false);
frame.setLocationByPlatform(true);
frame.setSize(1308, 900);
frame.setBounds(100, 100, 450, 300);
frame.setMinimumSize(new Dimension(1308, 900));
frame.setPreferredSize(new Dimension(1308, 900));
frame.setLayout(null);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}
#SuppressWarnings({ "resource", "unused" })
private static void placeChatOnScreen() {
try {
textField = new JTextField();
textField.setFont(new Font("Segoe UI", Font.PLAIN, 13));
textField.setDragEnabled(true);
textField.setBorder(new MatteBorder(1, 1, 1, 1, (Color) new Color(0, 0, 0)));
textField.setBounds(338, 838, 954, 22);
frame.getContentPane().add(textField);
messageArea = new JTextArea();
messageArea.setEditable(false);
messageArea.setFont(new Font("Segoe UI", Font.PLAIN, 13));
messageArea.setBorder(new MatteBorder(1, 1, 1, 1, (Color) new Color(0, 0, 0)));
messageArea.setDragEnabled(true);
messageArea.setName("chatArea");
messageArea.setWrapStyleWord(true);
messageArea.setBounds(338, 648, 954, 181);
frame.getContentPane().add(messageArea);
textField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
out.println(textField.getText());
textField.setText("");
}
});
Socket socket = new Socket("localhost", 8877);
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream(), true);
while (in.hasNextLine()) {
String line = in.nextLine();
if (line.startsWith("SUBMITNAME")) {
out.println(getName());
} else if (line.startsWith("NAMEACCEPTED")) {
textField.setEditable(true);
} else if (line.startsWith("MESSAGE")) {
messageArea.append(line.substring(8) + "\n");
}
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
It does fine until it gets to the "NAMEACCEPTED" else if condition and it just steps out of the while loop and then nothing happens. No error of any kind. It just doesn't how the swing frame!
If I comment out:
/*while (in.hasNextLine()) {
String line = in.nextLine();
if (line.startsWith("SUBMITNAME")) {
out.println(getName());
} else if (line.startsWith("NAMEACCEPTED")) {
textField.setEditable(true);
} else if (line.startsWith("MESSAGE")) {
messageArea.append(line.substring(8) + "\n");
}
}*/
and run it the swing frame loads up just fine. But my Socket (which I am wanting in my swing app) keeps it for some reason passing.
window = new UFTtrack();
placeChatOnScreen();
createTable();
SystemTrayz.createTray();
centreWindow(frame);
window.frame.setVisible(true);
To sum all this up - the above code hits the window = new UFTtrack(); and placeChatOnScreen() but after it exits the While loop in the placeChatOnScreen() it never continues to createTable(); What's the deal???
Also posted here:
http://www.javaprogrammingforums.com/whats-wrong-my-code/41820-java-socket-not-allowing-swing-frame-show-up.html#post165295
https://coderanch.com/t/708072/java/Java-Socket-allowing-swing-frame
https://www.dreamincode.net/forums/topic/415549-java-socket-not-allowing-swing-frame-to-show-up/
Java Socket not allowing swing frame to show up
As mentioned in the comments read and accept operations typically block on a Socket.
You could create an own Thread which is waiting for Message from your Socket and then modify the GUI. Keep in mind that Swing is not Thread safe.
If I need to create an own Thread, I use the Runnable interface. You could achieve it like this:
public class MySocketListener implements Runnable {
private final GUIClass guiClass;
private final ServerSocket serverSocket;
private Socket clientSocket;
public MySocketListener(GUIClass guiClass, ServerSocket serverSocket) {
this.guiClass = guiClass;
this.serverSocket = serverSocket;
}
/* Everything that happens in this method, is done on another Thread. */
#Override
public void run() {
try{
this.clientSocket = this.serverSocket.accept();
Scanner sc = new Scanner(this.clientSocket.getInputStream());
while(true) {
/* Blocking operations */
this.guiClass.doSomething();
}
} catch(IOException ex) {
ex.printStackTrace();
}
}
}
The Thread can then be started easily:
Thread socketListenerThread = new Thread(new MySocketListener(this, serverSocket));
socketListenerThread.start();
For more information have a look at the Thread and Socket documentation.
I want to know how my console output can be save in a notepad file?
import java.awt.EventQueue;
public class HLS1 {
private JFrame frmHttpsLiveStreaming;
private JTextField textField;
// file is accessed to the whole class
private File file;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
HLS1 window = new HLS1();
window.frmHttpsLiveStreaming.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public HLS1() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frmHttpsLiveStreaming = new JFrame();
frmHttpsLiveStreaming.setTitle("HTTPS Live Streaming");
frmHttpsLiveStreaming.setBounds(100, 100, 494, 112);
frmHttpsLiveStreaming.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmHttpsLiveStreaming.getContentPane().setLayout(null);
JButton btnBrowse = new JButton("Open File");
btnBrowse.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
System.out.println("Argument:" + arg0);
JFileChooser fs = new JFileChooser(new File("c:\\"));
fs.setDialogTitle("Open a file");
fs.setFileFilter(new FileTypeFilter(".m3u8", ""));
fs.setFileFilter(new FileTypeFilter(".m3u", ""));
fs.showOpenDialog(null);
file = fs.getSelectedFile();
textField.setText(file.getAbsolutePath());
}
});
btnBrowse.setBounds(336, 7, 89, 23);
frmHttpsLiveStreaming.getContentPane().add(btnBrowse);
JButton btnNewButton_1 = new JButton("Clear");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
textField.setText("");
}
});
btnNewButton_1.setBounds(237, 39, 89, 23);
frmHttpsLiveStreaming.getContentPane().add(btnNewButton_1);
JLabel lblUrl = new JLabel("URL");
lblUrl.setBounds(83, 11, 24, 14);
frmHttpsLiveStreaming.getContentPane().add(lblUrl);
textField = new JTextField();
textField.setBounds(116, 11, 210, 19);
frmHttpsLiveStreaming.getContentPane().add(textField);
textField.setColumns(10);
JButton btnNewButton = new JButton("Check");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
List<String> fileArray = new ArrayList<String>();
List<String> errors = new ArrayList<String>();
String regex = "^(https?|ftp|file)://[-a-zA-Z0-9+&##/%?=~_|!:,.;]*[-a-zA-Z0-9+&##/%=~_|]";
Scanner s = null;
if(textField.getText().matches(regex)){
URL url = new URL(textField.getText());
s= new Scanner(url.openStream());
}else{
s = new Scanner(new BufferedReader(new FileReader(file)));
}
if(s != null){
while(s.hasNextLine()){
String line = s.nextLine();
if(!line.isEmpty()){
fileArray.add(line);
}
System.out.println(line);
}
}
s.close();
errors.addAll(validateEXTM3U(fileArray));
for (String error : errors) {
System.out.println(error);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
btnNewButton.setBounds(126, 39, 89, 23);
frmHttpsLiveStreaming.getContentPane().add(btnNewButton);
}
private List<String> validateEXTM3U(List<String> fileArray){
List<String> errors = new ArrayList<String>();
String tag = fileArray.get(0);
if(!tag.equals("#EXTM3U")){
errors.add("First line in the menifest file is not #EXTM3U");
}
return errors;
}
}
It could be a hacky solution , but if you are running in windows or linux then you can pipe / redirect it.
java HLS1 > notepad.txt
if not what you are looking for , then why not using something called log4j ?
Why don't you write your own utility that has an public static void output(String output) method. Then instead of using System.out.println("...") you call output("...") then in your output(String output) method you can do anything with the output, like first write to the file, then print to the console.
Hope this helps.
try {
project.fireBuildStarted();
project.init();
ProjectHelper projectHelper = ProjectHelper.getProjectHelper();
project.addReference("ant.projectHelper", projectHelper);
projectHelper.parse(project, buildFile);
// If no target specified then default target will be executed.
String targetToExecute = (target != null && target.trim().length() > 0) ? target
.trim() : project.getDefaultTarget();
project.executeTarget(targetToExecute);
project.fireBuildFinished(null);
success = true;
} catch (BuildException buildException) {
project.fireBuildFinished(buildException);
JOptionPane.showMessageDialog(null, buildException, "Warning",
JOptionPane.WARNING_MESSAGE);
throw new RuntimeException(
"!!! Unable to restart the IEHS App !!!", buildException);
}
Above methods are giving some output on the console, but I need them in the dialog boxes. How can I do that ?
I think you are trying to capture the console logs to a UI component, if that is the case, here is the sample which will create output stream and capture console output and show it in UI component. You can try this.
public class Console extends JDialog {
JTextArea textArea = null;
/**
* Launch the application.
*/
public static void main(String[] args) {
try {
Console dialog = new Console();
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
private void updateTextPane(final String text) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
textArea.append(text);
}
});
}
/**
* Create the dialog.
*/
public Console() {
//Creating a stream to move consle output to anything else
OutputStream out = new OutputStream() {
#Override
public void write(final int b) throws IOException {
updateTextPane(String.valueOf((char) b));
}
#Override
public void write(byte[] b, int off, int len) throws IOException {
updateTextPane(new String(b, off, len));
}
#Override
public void write(byte[] b) throws IOException {
write(b, 0, b.length);
}
};
System.setOut(new PrintStream(out, true));
System.setErr(new PrintStream(out, true));
setBounds(100, 100, 450, 300);
getContentPane().setLayout(null);
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("hello");
}
});
btnNewButton.setBounds(91, 192, 91, 23);
getContentPane().add(btnNewButton);
textArea = new JTextArea();
textArea.setBounds(30, 11, 241, 136);
getContentPane().add(textArea);
}
}
Maybe you need this snippet:
JOptionPane.showMessageDialog(null, "Your Text");
On the other Hand if project.fireBuildFinished(buildException); gives output to the console then you have to enter a return value of this output and enter this in the "Your Text" spot or enter this MessageDialog into your method.
I've been working on building a chat server to learn about threading and using sockets. I used head first java as a guide (and I'm still confused about a couple of things, which is why I have this question probably :D) and the code below is what I have.
If you read my code, you'll see that I have clients connect to the server by clicking on a "connect" button. When they do that, a new jframe pops up that asks for their preferred name for the chat session. When they input that, it's saved in a String in the client code. My question is, how do I get this name over to the server, and make it so that every time the client sends a message, their name is displayed before their message?
Thank you for the help!!!
(ALSO, if anyone knows a good link that can explain sockets and how socket/client interaction occurs through threads, that would be great!)
server code:
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class GameServerOne {
ArrayList clientOutputStreams;
String clientName;
private class ClientThreadHandler implements Runnable {
BufferedReader clientIncomingReader;
Socket socket1;
public ClientThreadHandler(Socket clientSocket2) {
try {
socket1 = clientSocket2;
InputStreamReader clientInputReader = new InputStreamReader(socket1.getInputStream());
clientIncomingReader = new BufferedReader(clientInputReader);
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() {
String message;
try {
while ((message = clientIncomingReader.readLine()) != null) {
tellEveryone(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void tellEveryone(String message) {
Iterator it = clientOutputStreams.iterator();
while(it.hasNext()) {
try {
PrintWriter writer = (PrintWriter) it.next();
writer.println(message);
writer.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void setUpServer() {
clientOutputStreams = new ArrayList();
try {
ServerSocket gameSocket = new ServerSocket(5151);
//System.out.println("Server Connected");
while (true) {
Socket clientSocket = gameSocket.accept();
PrintWriter writer = new PrintWriter(clientSocket.getOutputStream());
writer.println("User connected");
writer.flush();
clientOutputStreams.add(writer);
Thread t = new Thread(new ClientThreadHandler(clientSocket));
t.start();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
new GameServerOne().setUpServer();
}
}
Client code:
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GameClientOne {
Socket gameSocket;
JFrame inputNameFrame;
JFrame clientFrame;
JTextArea chatArea;
JTextField messageInput;
BufferedReader gameChatReader;
PrintWriter gameChatWriter;
JTextField nameField;
boolean sessionNamePicked = false;
String userSessionName;
BufferedReader gameBufferedReader;
public GameClientOne () {
setUpGUI();
}
public void setUpGUI() {
clientFrame = new JFrame("Game Window");
JPanel mainPanel = new JPanel(new BorderLayout());
JPanel southPanel = new JPanel(new BorderLayout());
JPanel centerPanel = new JPanel(new BorderLayout());
chatArea = new JTextArea();
chatArea.setWrapStyleWord(true);
chatArea.setLineWrap(true);
chatArea.setEditable(false);
JScrollPane chatScroller = new JScrollPane(chatArea);
messageInput = new JTextField();
messageInput.addKeyListener(new MessageInputFieldListener());
JButton sendButton = new JButton("Send");
sendButton.addActionListener(new SendButtonListener());
JPanel westPanel = new JPanel(/*new GridLayout(20, 1)*/);
JPanel eastPanel = new JPanel();
JButton connectButton = new JButton("Connect");
connectButton.addActionListener(new ConnectButtonListener());
connectButton.setPreferredSize(new Dimension(100, 28));
JPanel northPanel = new JPanel(new FlowLayout());
JLabel northTitleLabel = new JLabel("Game Screen");
westPanel.add(connectButton);
chatScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS) ;
chatScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
northPanel.add(northTitleLabel);
centerPanel.add(BorderLayout.CENTER, chatScroller);
southPanel.add(BorderLayout.CENTER, messageInput);
southPanel.add(BorderLayout.EAST, sendButton);
mainPanel.add(BorderLayout.SOUTH, southPanel);
mainPanel.add(BorderLayout.CENTER, centerPanel);
mainPanel.add(BorderLayout.WEST, westPanel);
mainPanel.add(BorderLayout.EAST, eastPanel);
mainPanel.add(BorderLayout.NORTH, northPanel);
clientFrame.add(mainPanel);
clientFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
clientFrame.setSize(450, 600);
clientFrame.setVisible(true);
messageInput.requestFocusInWindow();
}
public void setUpInputNameFrame() {
inputNameFrame = new JFrame("Insert Name");
JPanel mainPanel = new JPanel(new BorderLayout());
nameField = new JTextField();
nameField.addKeyListener(new NameFieldListener());
JButton submitButton = new JButton("Submit");
submitButton.addActionListener(new SubmitButtonListener());
JLabel inputNameLabel = new JLabel("Please pick a name for the chat session");
JPanel northPanel = new JPanel(new FlowLayout());
JPanel southPanel = new JPanel(new BorderLayout());
northPanel.add(inputNameLabel);
southPanel.add(BorderLayout.CENTER, nameField);
southPanel.add(BorderLayout.EAST, submitButton);
mainPanel.add(BorderLayout.NORTH, northPanel);
mainPanel.add(BorderLayout.SOUTH, southPanel);
inputNameFrame.add(mainPanel);
inputNameFrame.setSize(300, 150);
inputNameFrame.setVisible(true);
nameField.requestFocusInWindow();
}
public void connectToGameServer() {
try {
gameSocket = new Socket("127.0.0.1", 5151);
InputStreamReader gameSocketReader = new InputStreamReader(gameSocket.getInputStream());
gameBufferedReader = new BufferedReader(gameSocketReader);
gameChatWriter = new PrintWriter(gameSocket.getOutputStream());
chatArea.append("Connected with name: " + userSessionName + "\n");
Thread incomingTextThread = new Thread(new IncomingTextReader());
incomingTextThread.start();
//System.out.println("Connected to Game");
} catch (Exception e) {
System.out.println("Could not connect to game...");
e.printStackTrace();
}
}
//ALL LISTENER CLASSES BELOW HERE
//main chat page listeners
private class ConnectButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (!sessionNamePicked) {
setUpInputNameFrame();
} else {
chatArea.append("You already connected!\n");
}
}
}
private class SendButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (!sessionNamePicked) {
chatArea.append("Please connect first\n");
messageInput.setText("");
messageInput.requestFocusInWindow();
} else {
try {
gameChatWriter.println(messageInput.getText());
gameChatWriter.flush();
} catch (Exception ex2) {
ex2.printStackTrace();
}
//chatArea.append(userSessionName + ": " + messageInput.getText() + "\n");
messageInput.setText("");
messageInput.requestFocusInWindow();
}
}
}
private class MessageInputFieldListener implements KeyListener {
public void keyPressed(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
if (!sessionNamePicked) {
chatArea.append("Please connect first\n");
messageInput.setText("");
} else {
try {
gameChatWriter.println(messageInput.getText());
gameChatWriter.flush();
} catch (Exception ex2) {
ex2.printStackTrace();
}
//chatArea.append(userSessionName + ": " + messageInput.getText() + "\n");
messageInput.setText("");
}
}
}
}
//pick chat session name listeners: nameField/submitButton
private class NameFieldListener implements KeyListener {
public void keyPressed(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
if (!nameField.getText().isEmpty() && e.getKeyCode() == KeyEvent.VK_ENTER) {
userSessionName = nameField.getText();
sessionNamePicked = true;
connectToGameServer();
inputNameFrame.dispose();
messageInput.requestFocusInWindow();
}
}
}
private class SubmitButtonListener implements ActionListener {
public void actionPerformed (ActionEvent e) {
if (!nameField.getText().isEmpty()) {
userSessionName = nameField.getText();
sessionNamePicked = true;
connectToGameServer();
inputNameFrame.dispose();
messageInput.requestFocusInWindow();
}
}
}
//Runnable implementation for threads
private class IncomingTextReader implements Runnable {
public void run() {
String incomingMessage;
try {
while ((incomingMessage = gameBufferedReader.readLine()) != null) {
chatArea.append(incomingMessage + "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
GameClientOne gameClient = new GameClientOne();
}
}
If you want to send more than just a message as you are now, you are going to need a protocol to decide what to do with the string you receive, instead of just sending it to all the other clients.
For example, on the client side to send the client's name you might write NAME:(client's name), and then on the server you would split the string at the : and check if the first part is NAME, and if so set the clients name to the rest of the string. You should think about what other types of data you might want to send aswell and design a protocol that works for it.
Here's an example of how to do the above:
On the client you could add the line gameChatWriter.write("NAME:"+name) (create name first of course) imediatly after the connection is made. Then on the server, instead of calling tellEveryone(message) when the message is recieved create a method called processInput and call it, which might look like this:
private void processInput(String message){
String[] commands=message.split(':');
if(commands[0].equals("NAME")){
clientName=commands[1];
}
else{
tellEveryone(message);
}
}
Right now you only have one String clientName and you will obviously need more for the other clients you want to talk to so I would recommend making the thread handler into a seperate class which you would instantiate for each client and could hold things like that.
After you get this to work you could also create a seperate method to write other things that you want to send to either the client or server and a method to process input on the client side as well. Hope this helps.