I don't know much about sounds digitalization. I am trying to represent the instant profile of the mic input. I know how to get the bits from the mic, but I don't know how to interpret it into a profile. Can anyone help me filling the blank?
package test;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.io.OutputStream;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/**
*
* #author François Billioud
*/
public class SoundRecorder extends JFrame {
/** JFrame for the GUI **/
public SoundRecorder() {
super("Sound Recorder");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container pane = getContentPane();
pane.setLayout(new BorderLayout());
pane.add(wavePane = new WavePane(), BorderLayout.CENTER);
pane.add(new JButton(new AbstractAction("ok") {
#Override
public void actionPerformed(ActionEvent e) {
dispose();
}
}), BorderLayout.SOUTH);
setSize(300,300);
setLocationRelativeTo(null);
}
/** Just displays the frame and starts listening **/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
SoundRecorder rec = new SoundRecorder();
rec.setVisible(true);
rec.listenToMic();
}
});
}
/** Draws the sound read from the mic **/
private static class WavePane extends JPanel {
private final int[] x = new int[0];
private int[] y = new int[0];
private WavePane() {
setOpaque(true);
setBackground(Color.WHITE);
}
/** updates the data to be displayed **/
public void setData(int[] y) {
this.y = y;
int n = y.length;
this.x = new int[n];
float pas = getWidth()/(float)(n-1);
float xCurrent = 0;
for(int i=0; i<n; i++) {
this.x[i] = Math.round(xCurrent);
xCurrent+=pas;
}
repaint();
}
/** Draws a line that represent the mic profile **/
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2D = (Graphics2D) g;
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2D.drawPolyline(x, y, x.length);
}
}
/** Defines the audio format to be used.
* I know nothing about that and am open to suggestions if needed
*/
private static final AudioFormat format = new AudioFormat(
16000, //Sample rate
16, //SampleSizeInBits
2, //Channels
true,//Signed
true //BigEndian
);
/** Creates a thread that will read data from
* the mic and send it to the WavePane
* in order to be painted.
* We should be using a SwingWorker, but it will do
* for the sake of this demo.
**/
private void listenToMic() {
new Thread(new Runnable() {
#Override
public void run() {
try {
//Open the line and read
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
//checks if system supports the data line
if (!AudioSystem.isLineSupported(info)) {
System.err.print("Line not supported");
}
//starts listening
TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format);
line.start();
//sends the stream to the interpreter
AudioInputStream ais = new AudioInputStream(line);
AudioSystem.write(ais, AudioFileFormat.Type.AU, new Interpreter());
} catch (LineUnavailableException | IOException ex) {
System.err.println(ex.getLocalizedMessage());
}
}
}).start();
}
private final WavePane wavePane;
private class Interpreter extends OutputStream {
private int[] y;
#Override
public void write(int b) throws IOException {
//TBD
//Fill y array
}
#Override
public void flush() throws IOException {
//Sends the values found to the panel for drawing
wavePane.setData(y);
}
}
}
I found this link but it didn't help me...
Edit: Ok, from what I understand, each 16 bits is the amplitude for one frequency. I have 2 channels, so I have to read 16 bits every 32 to get the first channel. Now I need to know how many frequencies I am going to read for each frame. Then I think I can draw the profile. Any hint?
If you want to draw the spectrum (energy per frequency over time) of the signal that is coming from the microphone then you might want to read this. Maybe a bit more that you wanted to know but it has the maths you need.
If you want to draw the amplitude (the pressure over time) then check, for instance, this.
The contents of the audio stream, based on your specification of the audio format, will be a PCM stream. PCM stream means that every frame is a value of sound pressure at that moment of time. Each frame will consist of four bytes, two bytes per channel. The first two bytes will be channel 0, the other two -- channel 1. The two bytes will be in big endian format (the more significant byte will come before the less significant byte). The fact that you specified signed as True means that you should interpret the values as being in the range from -32768 to 32767.
Related
I use this class for my school app projects. It is how I set the application up and it extends JFrame and implements Runnable. Now whenever I use this in school on a Windows computer and everything works and the screen updates, but at home on a Mac it doesn't. I use Eclipse neon with JDK 1.8.0_101
Please help me out, I can't test any projects at home cause of this.
import java.awt.Graphics;
import javax.swing.JFrame;
public abstract class GUIApplication extends JFrame implements Runnable{
private Screen currentScreen;
//no main, cant instentiate an abstract class
public GUIApplication(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int x=40;
int y=40;
int width=1000;
int height=640;
setBounds(x,y,width,height);
initScreen();
setVisible(true);
}
//this is a method for creating the starting screen
protected abstract void initScreen();
public void setScreen(Screen screen){
//stop controls from previous screen
removeListeners();
setCurrentScreen(screen);
//add new controls
addListeners();
}
private void removeListeners(){
if(getCurrentScreen() != null){
if(getCurrentScreen().getMouseListener() != null) removeMouseListener(getCurrentScreen().getMouseListener());
if(getCurrentScreen().getMouseMotionListener() != null) removeMouseMotionListener(getCurrentScreen().getMouseMotionListener());
if(getCurrentScreen().getKeyListener() != null) removeKeyListener(getCurrentScreen().getKeyListener());
// if(currentScreen.getMouseWheelListener() != null) removeMouseWheelListener(currentScreen.getMouseWheelListener());
}
}
private void addListeners(){
if(getCurrentScreen() != null){
if(getCurrentScreen().getMouseListener() != null)addMouseListener(getCurrentScreen().getMouseListener());
if(getCurrentScreen().getMouseMotionListener() != null) addMouseMotionListener(getCurrentScreen().getMouseMotionListener());
if(getCurrentScreen().getKeyListener() != null){
addKeyListener(getCurrentScreen().getKeyListener());
}
// if(currentScreen.getMouseWheelListener() != null) addMouseWheelListener(currentScreen.getMouseWheelListener());
}
}
public void paint(Graphics g){
g.drawImage(getCurrentScreen().getImage(), 0, 0, null);
}
public void run(){
while(true){
getCurrentScreen().update();
repaint();
try {
Thread.sleep(30);
repaint();
revalidate();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public Screen getCurrentScreen() {
return currentScreen;
}
public void setCurrentScreen(Screen currentScreen) {
this.currentScreen = currentScreen;
}
}
This is how a game would start:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.ArrayList;
import javax.swing.JFrame;
import game.mainScreenTeam.Dragon;
import game.mainScreenTeam.HomeScreen;
import game.miniGameTeam.GameInstructions;
import game.miniGameTeam.GameScreen;
import game.miniGameTeam.HighScoreScreen;
import game.shopScreen.BuyScreenWendy;
import game.shopScreen.HomeShopScreen;
import game.shopScreen.SellShopZheng;
import guiPractice.GUIApplication;
import guiPractice.Screen;
import guiPractice.components.AnimatedComponent;
/**
* #author Kat
*
*/
public class DragonLand extends GUIApplication {
public static DragonLand game;
public static int coins = 1500;
public static HomeScreen homeScreen;
public static Screen shopMain; // shop 1
public static Screen sellScreen; // shop 2
public static Screen buyScreen; // shop 3
public static Screen highscoreScreen; // high score
public static GameScreen miniGameScreen; // minigame
public static Screen gameInstructionsScreen;
public static Screen HelpScreen;
public static Color NAVY;
public static Color BRIGHT_PINK;
public static Color LIGHT_PINK;
public static Color LIGHT_NUDE;
public static Color DARKER_NUDE;
/**
*
*/
// public static void addDragon(AnimatedComponent a){
// dragonList.add(a);
// }
public DragonLand() {
}
/* (non-Javadoc)
* #see guiPractice.GUIApplication#initScreen()
*/
#Override
protected void initScreen() {
initColors();
miniGameScreen = new GameScreen(getWidth(),getHeight());
shopMain = new HomeShopScreen(getWidth(),getHeight());
sellScreen = new SellShopZheng(getWidth(),getHeight());
homeScreen = new HomeScreen(getWidth(),getHeight());
buyScreen = new BuyScreenWendy(getWidth(),getHeight());
highscoreScreen = new HighScoreScreen(getWidth(),getHeight());
HomeScreen.jenCode = new game.mainScreenTeam.HomeJenniber();
gameInstructionsScreen = new GameInstructions(getWidth(), getHeight());
setScreen(homeScreen);
}
private void initColors() {
NAVY = new Color(62,74,99);
BRIGHT_PINK = new Color(224,102,102);
LIGHT_PINK = new Color(248,186,182);
LIGHT_NUDE = new Color(244,215,183);
DARKER_NUDE = new Color(230,195,147);
}
/**
* #param args
*/
public static void main(String[] args) {
game = new DragonLand();
Thread go = new Thread(game);
go.start();
}
//public coin getter + setter
public void setCoins(int x){
coins = x;
}
public int getCoins(){
return coins;
}
}
This is the home screen
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import game.DragonLand;
import guiPractice.ClickableScreen;
import guiPractice.components.Action;
import guiPractice.components.AnimatedComponent;
import guiPractice.components.Button;
import guiPractice.components.Graphic;
import guiPractice.components.TextLabel;
import guiPractice.components.Visible;
import guiPractice.sampleGames.MouseFollower;
/**
* #author Kat
* #author Jenniber
*
*/
public class HomeScreen extends ClickableScreen implements Runnable{
private Graphic background;
public static HomeJenniber jenCode;
public HomeScreen(int width, int height) {
super(width, height);
Thread play = new Thread(this);
play.start();
}
#Override
public void initAllObjects(ArrayList<Visible> viewObjects) {
background=new Graphic(0,0,getWidth(),getHeight(),"img/Grassland.png");
viewObjects.add(background);
HomeKat katCode=new HomeKat(viewObjects, getWidth(), getHeight());
}
#Override
public void run() {
}
}
katCode adds buttons to the screen and image annimations
public void paint(Graphics g){
g.drawImage(getCurrentScreen().getImage(), 0, 0, null);
}
Don't override paint() on a JFrame.
The proper way to do custom painting is to override paintComponent(...) on a JPanel (or JComponent) and then you can set the content pane of the frame to this panel. And don't forget to invoke super.paintComponent(...) as the first statement in the method. Read the section from the Swing tutorial on Custom Painting for more information and working examples.
However if you do get lazy, then at minimum you need to invoke super.paint(...) as the first statement in the paint(...) method.
Also, I doubt you need the revalidate(), since you don't appear to be adding/removing components from the frame.
But in general the order should be:
revalidate(); // to invoke the layout manager
repaint(); // paint components in new location.
I also don't know why you are invoking the update() method. That seems like old AWT code which you don't use in Swing. I suggest you take a look at the tutorial link I gave you and look at the table of contents for other Swing basics.
I have a list of files that I'm going to copy over to another location and I want to use a JProgressBar to monitor the progress of the transfer.
The JProgressBar constructor only takes an int for the bounds and File.length returns a long. I know I can cast the long to an int and lose some accuracy, but is this the correct way to do it?
I didn't include any code because it's not really a syntax or coding issue, I'm just not sure if casting a long to an int for use in a progress bar is the correct or accurate enough for my purposes.
I don't really see a problem about progress bar bounds just because actual progress is a percentual value from 0 to 100. You should always be capable to calculate the proportion between processed bytes and the total amount of bytes and that's the actual progress.
I think the right question would be something like: how do I properly update the progress of my progress bar based on files length and total of bytes to be transferred?
Consider this example:
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class Demo {
private void createAndShowGUI() {
final JProgressBar progressBar = new JProgressBar();
progressBar.setStringPainted(true);
progressBar.setString("");
final SwingWorker<Void,String> worker = new SwingWorker<Void, String>() {
#Override
protected Void doInBackground() throws Exception {
long totalSize = 0l;
File[] files = new File(System.getProperty("user.dir")).listFiles();
for (File file : files) {
totalSize += file.length();
}
long transferred = 0l;
for (File file : files) {
Thread.sleep(250); // Just for animation purpose
transferred += file.length();
int progress = (int) (transferred * 100l / totalSize);
setProgress(progress);
String text = String.format("%1s%%: %2s / %3s bytes", progress, transferred, totalSize);
publish(text);
}
return null;
}
#Override
protected void process(List<String> chunks) {
progressBar.setString(chunks.get(chunks.size() - 1));
}
};
worker.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setValue((Integer)evt.getNewValue());
}
}
});
Action startAction = new AbstractAction("Start") {
#Override
public void actionPerformed(ActionEvent e) {
worker.execute();
setEnabled(false);
}
};
JPanel content = new JPanel();
content.add(progressBar);
content.add(new JButton(startAction));
JFrame frame = new JFrame("Demo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(content);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Demo().createAndShowGUI();
}
});
}
}
Because transferred * 100l / totalSize will be always a value between 0 and 100, you maybe will lose a decimal point accuracy but you definitely won't lose precision casting it to int in order to set progress bar value.
I've been taking AP Computer Science this year as a sophomore in high school and we mainly cover material like loops, classes, methods, general CS logic, and some math stuff. I am missing what I really loved about coding in the first place, making games. Now every game I have made had some sort of way to manage it whether it was using timers in visual basic or a XNA plugin for c# that setup a update method for me. The problem is I have not learned how to do this for java in my course. I've read up a little on threads and implements runnable but i'm not really sure where I'm going with it.
Class 1
import java.awt.FlowLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class GFXScreen extends JFrame
{
/**
* #param screenHeigth
* #param screenHeigth
* #param The file name of the image. Make sure to include the extension type also
* #param The title at the top of the running screen
* #param The height of the screen
* #param The width of the screen
*/
public GFXScreen(String fileName, String screenTitle, int screenHeight, int screenWidth)
{
setLayout(new FlowLayout());
image1 = new ImageIcon(getClass().getResource(fileName));
label1 = new JLabel(image1);
this.add(label1);
//Set up JFrame
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
this.setTitle(screenTitle);
this.setSize(screenWidth, screenHeight);
}
/**
* #param desired amount to move picture
*/
public void updatePic(int increment)
{
//update pos
label1.setBounds(label1.bounds().x, label1.bounds().y - increment,
label1.bounds().width, label1.bounds().height);
}
private ImageIcon image1;
private JLabel label1;
}
Class 2
public class MainClass implements Runnable {
public static void main(String[] args)
{
(new Thread(new MainClass())).start();
GFXScreen gfx = new GFXScreen("pixel_man.png", "pixel_Man", 1000, 1000);
}
public void run()
{
gfx.updatePic(1);
}
}
In this instance what I want to happen is, I want a picture that starts in the top to slowly move down smoothly to the bottom. How would i do this?
Suggestions:
Again, a Swing Timer works well for simple Swing animations or simple game loops. It may not be the greatest choice for complex or rigorous tame loops as its timing is not precise.
Most game loops will not be absolutely precise with time slices
And so your game model should take this into consideration and should note absolute time slices and use that information in its physics engine or animation.
If you must use background threading, do take care that most all Swing calls are made on the Swing event thread. To do otherwise will invite pernicious infrequent and difficult to debug program-ending exceptions. For more details on this, please read Concurrency in Swing.
I avoid using null layouts, except when animating components, as this will allow my animation engine to place the component absolutely.
When posting code here for us to test, it's best to avoid code that uses local images. Either have the code use an image easily available to all as a URL or create your own image in your code (see below for a simple example).
Your compiler should be complaining to you about your using deprecated methods, such as bounds(...), and more importantly, you should heed those complaints as they're there for a reason and suggest increased risk and danger if you use them. So don't use those methods, but instead check the Java API for better substitutes.
Just my own personal pet peeve -- please indicate that you've at least read our comments. No one likes putting effort and consideration into trying to help, only to be ignored. I almost didn't post this answer because of this.
For example:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
#SuppressWarnings("serial")
public class GfxPanel extends JPanel {
private static final int BI_WIDTH = 26;
private static final int BI_HEIGHT = BI_WIDTH;
private static final int GAP = 6;
private static final Point INITIAL_LOCATION = new Point(0, 0);
private static final int TIMER_DELAY = 40;
public static final int STEP = 1;
private ImageIcon image1;
private JLabel label1;
private Point labelLocation = INITIAL_LOCATION;
private int prefW;
private int prefH;
private Timer timer;
public GfxPanel(int width, int height) {
// the only time I use null layouts is for component animation.
setLayout(null);
this.prefW = width;
this.prefH = height;
// My program creates its image so you can run it without an image file
image1 = new ImageIcon(createMyImage());
label1 = new JLabel(image1);
label1.setSize(label1.getPreferredSize());
label1.setLocation(labelLocation);
this.add(label1);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(prefW, prefH);
}
public void startAnimation() {
if (timer != null && timer.isRunning()) {
timer.stop();
}
labelLocation = INITIAL_LOCATION;
timer = new Timer(TIMER_DELAY, new TimerListener());
timer.start();
}
// My program creates its image so you can run it without an image file
private Image createMyImage() {
BufferedImage bi = new BufferedImage(BI_WIDTH, BI_HEIGHT,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = bi.createGraphics();
g2.setColor(Color.red);
g2.fillRect(0, 0, BI_WIDTH, BI_HEIGHT);
g2.setColor(Color.blue);
int x = GAP;
int y = x;
int width = BI_WIDTH - 2 * GAP;
int height = BI_HEIGHT - 2 * GAP;
g2.fillRect(x, y, width, height);
g2.dispose();
return bi;
}
private class TimerListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
int x = labelLocation.x + STEP;
int y = labelLocation.y + STEP;
labelLocation = new Point(x, y);
label1.setLocation(labelLocation);
repaint();
if (x + BI_WIDTH > getWidth() || y + BI_HEIGHT > getHeight()) {
System.out.println("Stopping Timer");
((Timer) e.getSource()).stop();
}
}
}
private static void createAndShowGui() {
final GfxPanel gfxPanel = new GfxPanel(900, 750);
JButton button = new JButton(new AbstractAction("Animate") {
#Override
public void actionPerformed(ActionEvent arg0) {
gfxPanel.startAnimation();
}
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(button);
JFrame frame = new JFrame("GFXScreen");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(gfxPanel);
frame.getContentPane().add(buttonPanel, BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
What I always use is an infinite loop that calls an update method each iteration, in that method, you would do whatever was required to update the state of the game or render a GUI.
Example
public static void main(String[] args){
// Initialise game
while(true){
updateGame();
}
}
public static void updateGame(){
// Update things here.
}
What I also do ,which is a little more complex, is create and interface called IUpdateListener and have certain classes that are specialised for a certain element of the game. I would example have an InputListener, an AIListener, each handling a certain element of game updating.
public interface IUpdateListener{
public void update();
}
public class Main{
public static ArrayList<IUpdateListener> listeners = new ArrayList<IUpdateListener>();
public static void main(String[] args){
listeners.add(new InputListener());
while(true){
for(IUpdateListener listener : listeners){
listener.update();
}
}
}
}
public class InputListener implements IUpdateListener{
public void update(){
// Handle user input here etc
}
}
I just want to run two frames concurrently, one contains drag and drop feature which i am using to write file to ftp server and other one to display the progress bar to show how much file is written(uploaded you can say).
But the problem is my progress bar frame remains white i.e, GUI is not done on it.why???
please give me a solution.
here is my first class which is a homePage frame which calls another class called ProgressSample which writes data to the output stream and also updates the progress bar simultaneously.
FTPConnect.java
SwingWorker<Void , Integer> worker = new SwingWorker<Void , Integer>(){
#Override
protected Void doInBackground() throws Exception {
ProgressSample.main(secondLocalFile , bytesIn , inputStream , outputStream);
return null;
}
protected void done(){
ProgressSample.frame.dispose();
}
};
worker.execute();
this is the second class ...
when i call its main(......) method just a frame with white color on it appears nothing is added on it plz plz plz help me with ur suggestions as soon as possible...
ProgressSample.java
package encdec;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
public class ProgressSample
{
static JFrame frame;
JProgressBar progressBar;
public static void main(File file , byte[] bytesIn, InputStream inputStream , OutputStream outputStream)throws IOException
{
ProgressSample obj=new ProgressSample();
obj.redfile(file , bytesIn , inputStream , outputStream);
}
public ProgressSample()
{
frame = new JFrame();
frame.setBounds(100, 100, 400, 200);
frame.getContentPane().setLayout(null);
progressBar = new JProgressBar();
progressBar.setBounds(102, 40, 150, 16);
frame.getContentPane().add(progressBar);
progressBar.setStringPainted(true);
frame.setVisible(true);
}
public void redfile(File f , byte[] bytesIn, InputStream inputStream , OutputStream outputStream)
{
try {
long totalLength = f.length();
double lengthPerPercent = 100.0 / totalLength;
long readLength = 0;
int read;
System.out.println(totalLength);
while ((read = inputStream.read(bytesIn)) != -1) {
readLength += read;
progressBar.setValue((int) Math.round(lengthPerPercent * readLength));
outputStream.write(bytesIn, 0, read);
}
progressBar.setValue(100);
frame.dispose();
JOptionPane.showMessageDialog(null, "Upload Successful");
} catch (Exception e) {
}
}
}
Can someone help me how can I include emoticons in this code.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
* A simple Swing-based client for the chat server. Graphically
* it is a frame with a text field for entering messages and a
* textarea to see the whole dialog.
*
* The client follows the Chat Protocol which is as follows.
* When the server sends "SUBMITNAME" the client replies with the
* desired screen name. The server will keep sending "SUBMITNAME"
* requests as long as the client submits screen names that are
* already in use. When the server sends a line beginning
* with "NAMEACCEPTED" the client is now allowed to start
* sending the server arbitrary strings to be broadcast to all
* chatters connected to the server. When the server sends a
* line beginning with "MESSAGE " then all characters following
* this string should be displayed in its message area.
*/
public class ChatClient {
BufferedReader in;
PrintWriter out;
JFrame frame = new JFrame("Chatter");
JTextField textField = new JTextField(40);
JTextArea messageArea = new JTextArea(8, 40);
/**
* Constructs the client by laying out the GUI and registering a
* listener with the textfield so that pressing Return in the
* listener sends the textfield contents to the server. Note
* however that the textfield is initially NOT editable, and
* only becomes editable AFTER the client receives the NAMEACCEPTED
* message from the server.
*/
public ChatClient() {
// Layout GUI
textField.setEditable(false);
messageArea.setEditable(false);
frame.getContentPane().add(textField, "North");
frame.getContentPane().add(new JScrollPane(messageArea), "Center");
frame.pack();
// Add Listeners
textField.addActionListener(new ActionListener() {
/**
* Responds to pressing the enter key in the textfield by sending
* the contents of the text field to the server. Then clear
* the text area in preparation for the next message.
*/
public void actionPerformed(ActionEvent e) {
out.println(textField.getText());
textField.setText("");
}
});
}
/**
* Prompt for and return the address of the server.
*/
private String getServerAddress() {
return JOptionPane.showInputDialog(
frame,
"Enter IP Address of the Server:",
"Welcome to the Chatter",
JOptionPane.QUESTION_MESSAGE);
}
/**
* Prompt for and return the desired screen name.
*/
private String getName() {
return JOptionPane.showInputDialog(
frame,
"Choose a screen name:",
"Screen name selection",
JOptionPane.PLAIN_MESSAGE);
}
/**
* Connects to the server then enters the processing loop.
*/
private void run() throws IOException {
// Make connection and initialize streams
String serverAddress = getServerAddress();
Socket socket = new Socket(serverAddress, 9001);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
// Process all messages from server, according to the protocol.
while (true) {
String line = in.readLine();
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");
}
}
}
/**
* Runs the client as an application with a closeable frame.
*/
public static void main(String[] args) throws Exception {
ChatClient client = new ChatClient();
client.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
client.frame.setVisible(true);
client.run();
}
}
First of all, I didn't look your code to be honest (sry about that), but what you are asking is something very simple. Have you noticed that all emoticons have a sequence of characters?
Skype Example: :* :) (y) ... and so on
When compiling the message, a simple replaceAll takes place.
String message = "Of course :)";
// in this place here you will make a loop for all your emoticons or just
// match it by regex.
message = message.replaceAll(":)", imageToAdd);
sendMessage(message);
That is basically what happens in the chat when you add an emoticon. You can use a HashMap to, where the id would be the char sequence and the value would be the path or image component of that emoticon. (It is much faster if you have several)
Didnt bashed my head in your code but what i have used in my chatbox is this:
Autoreplace smiles text with appropriate images in JEditorPane.
To support the autoreplacing we need a JEditorPane with StyledEditorKit (or extension class) to provide images in text. We just add a DocumentListener to process text insert events. After inserting we check whether the changed text contains smiles string - the ":)". If it contains we replace the smile text with an appropriate image.
The example provides only one smile support - the ":)" string but can be easy extended.
NOTE: We should surround our code with SwingUtilities.invokeLater() because we cannot change document during mutation intercepted in the listener.
The example code is below:
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.*;
import java.awt.image.BufferedImage;
import java.awt.*;
public class AutoreplaceSmiles extends JEditorPane {
static ImageIcon SMILE_IMG=createImage();
public static void main(String[] args) {
JFrame frame = new JFrame("Autoreplace :) with Smiles images example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final AutoreplaceSmiles app = new AutoreplaceSmiles();
app.setEditorKit(new StyledEditorKit());
app.initListener();
JScrollPane scroll = new JScrollPane(app);
frame.getContentPane().add(scroll);
frame.setSize(400, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public AutoreplaceSmiles() {
super();
}
private void initListener() {
getDocument().addDocumentListener(new DocumentListener(){
public void insertUpdate(DocumentEvent event) {
final DocumentEvent e=event;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (e.getDocument() instanceof StyledDocument) {
try {
StyledDocument doc=(StyledDocument)e.getDocument();
int start= Utilities.getRowStart(AutoreplaceSmiles.this,Math.max(0,e.getOffset()-1));
int end=Utilities.getWordStart(AutoreplaceSmiles.this,e.getOffset()+e.getLength());
String text=doc.getText(start, end-start);
int i=text.indexOf(":)");
while(i>=0) {
final SimpleAttributeSet attrs=new SimpleAttributeSet(
doc.getCharacterElement(start+i).getAttributes());
if (StyleConstants.getIcon(attrs)==null) {
StyleConstants.setIcon(attrs, SMILE_IMG);
doc.remove(start+i, 2);
doc.insertString(start+i,":)", attrs);
}
i=text.indexOf(":)", i+2);
}
} catch (BadLocationException e1) {
e1.printStackTrace();
}
}
}
});
}
public void removeUpdate(DocumentEvent e) {
}
public void changedUpdate(DocumentEvent e) {
}
});
}
static ImageIcon createImage() {
BufferedImage res=new BufferedImage(17, 17, BufferedImage.TYPE_INT_ARGB);
Graphics g=res.getGraphics();
((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.yellow);
g.fillOval(0,0,16,16);
g.setColor(Color.black);
g.drawOval(0,0,16,16);
g.drawLine(4,5, 6,5);
g.drawLine(4,6, 6,6);
g.drawLine(11,5, 9,5);
g.drawLine(11,6, 9,6);
g.drawLine(4,10, 8,12);
g.drawLine(8,12, 12,10);
g.dispose();
return new ImageIcon(res);
}
}