Visualizzazione post con etichetta java. Mostra tutti i post
Visualizzazione post con etichetta java. Mostra tutti i post

lunedì 22 dicembre 2014

Jason - A Java autonomous agent based framework

Introduction

During this last year studying computer engineering I started to hear more and more talking about the notion of actor and agent. For what I've learned the notions behind the name "agent" are really confused and they might mean different things based of the technology that uses that term. During the last 3 months I've started studying autonomous system and by that I've encountered the notion of autonomous agent. 
An autonomous agent encapsulate his thread of control, moreover he has the complete control over his course of action, he can perceive the environment where he's situated, he's proactive and has a memory with an accurate representation of information.
Jason is a framework based on java that permits the creation of MAS (Multi Agent System), it encapsulate the notion of agent based on the Belief-Desires-Intention model. Jason is an implementation of AgentSpeak, (actually Jason specific language is an extension of AgentSpeak), by which it is possible to describe the base of knowledge and the behaviour of an agent. Let's see really fast what are the characteristics of a Jason agent, even though they are just an implementation of what an autonomous agent should provide to the programmer.

Base of knowledge
It's the memory of the agent, a place where the agent stores it's Belief, which are used by the agent to evaluate it's course of action.

Cognitive Autonomy
The agent choices what to do. It's choice would be processed and it's his very conviction, it's represented as a belief in the base of knowledge. The cognitive autonomy can be seen when the agent execute a plan and as a result can modify it's beliefs.

Perception Autonomy
The agent can perceive changes in the environment and changes it's base of knowledge about it with the right information. Between the perception and the information there's the agent which take the decision of considering or not what he's perceiving.

Message passing
Message passing is the communication support of the agents, all communications are made with a specific semantic (for example: achive, tell, etc).

Means-end plan actions
The agent's behaviour is expressed by the mean of plans. A plan is formed by actions that can also call the execution of other plans, a plan should provide a recovery plan in case of a failure. An agent act by it's means, he choice what to do by himself based on it's belief, how to act based on this stimuli is described in his plans. A plan should be seen as the action an agent should make to reach a specific state of affairs.

What we just discussed are the basic concepts of an autonomous agent in the BDI architecture, it's obvious that if Jason can provide an implementation for this notion of autonomous agent, then it seems to be the right framework to use for bridging the abstraction gap between OO programming and agent-oriented programming.

Basic knowledge about Jason

As we said before, Jason's language is an implementation of AgentSpeak, which by himself uses prolog notions. At every running cycle an agent perceive changes in it's environment and update with a criteria his belief base. Adding a belief can trigger the execution of a plan, a plan is made by a series of action. An action can be:
  • an internal action: an action that is made by the agent and it's standalone (provided by Jason) or implemented in Java. Examples of internal action: .send(agent1,tell,msg("I'm alive"))
  • an external action: an action that is meant to modify the state of the environment.
  • an addiction/remove of a belief: +likes(flower) -dislike(pop_music)
  • the execution of a plan: !goToTheStore
  • an evaluation, which can make the plan fail at that point: X < 10
  • an assignment or other prolog like operations.
An agent have initials belief and goals that defines it's initial behaviour.

Jason program example

Suppose we have two robots; the first one is a coffee machine and makes a beautiful espresso, the second one takes the coffee cup and brings it to the coffee table. When the coffee machine doesn't have more coffee or water it stops and turn on a led to signal that it needs someone to  take care of it. When the transporter is out of battery it moves towards it's recharger's spot, when it's charged it starts again. This behaviour is made endlessly until we can't make coffee anymore (because coffee is awesome and we want all the coffee cups we can get).

For me first thing to do is to analyze the problem and see what is part of the "physical" agent and what is part of the agent "mind". What is in the agent mind is what we are gonna do in Jason asl file, specifying his plans and base of knowledge. So what is part of the physical agent? We can see what the CoffeeMachine and the Transporter is made of in their respective classes:

  • ICoffeeMachine
  • ITransporterRobot
After we've got the idea of the physical parts of our agents let's start and see what the agent mind should perceive about the environment and it's physical properties. For example, it's logical that the battery level of the transporter can be perceived from it's physical level and brought to it's mind so that he can reason with this knowledge. Now that we've sorted this kind of things let's put it on code by extending the Environment class of Jason, we'll then specify this class in the mas2j file.
public class CoffeeHouseEnv extends Environment {
 // this is the environment of our autonomous system
 public static CoffeeHouseModel model;
 //Literals we are going to use, as belief or for actions
 public static final Literal at_table = Literal.parseLiteral("at(trans,table)");
 //...
 @Override
 public void init(String[] args) {
  model = new CoffeeHouseModel();
  clearAllPercepts();
 }

 void updatePercepts() {
  // Here we update all the perceptions for our agents
  clearPercepts("machine");
  clearPercepts("trans");
  clearAllPercepts();

  //transporter location
  Location tl = model.getAgPos(0);
  if(tl.equals(model.lMachine))
   addPercept(at_machine);
  if(tl.equals(model.lRecharger))
   addPercept(at_recharger);
  if(tl.equals(model.lTable))
   addPercept(at_table);
  
  //Coffee and water level for the machine
  //and battery for transporter
  double cl = model.machine.getCoffeeLelvel();
  //...
 }

 @Override
 public boolean executeAction(String agName, Structure act) {
  boolean result = false;

  //let's map the external action from jason agent to java
  //result = false -> the action failed
  
  if(act.equals(make_coffeeLit)){
   result = model.makeCoffe();
  }

  //...
  // only if action completed successfully, update agents' percepts
  if (result) {
   updatePercepts();
   try {
    Thread.sleep(100);
   } catch (Exception e) {
   }
  }
  return result;
 }
}

This is the common pattern of the extended Environment class, you have to notice:

  • executeAction() method is used to execute agents external actions
  • clearPercepts() clear all the percepts for specified agent
  • addPercept() add the specified belief to the specified (optional) agent
After this you have to specify the mind of the agents, this is done in the asl files. I can't explain all the syntax of the language, however looking at the code and at Jason Manual, I guess you can figure it out.

Download Code


Deeper thoughts

For what I've seen, Jason has it's limitation, even if I think they are kinda meant to be. I don't think Jason's programming language sweets well when developing intelligent agents, also the lack of a stochastic resource doesn't help making an agent that is more human-like.

sabato 21 giugno 2014

Implementing UI callbacks with audio player functionality

In the latest posts we discussed how to create the User Interface of our application and how to wrap all the player audio functionality into one simple AudioPlayer class. Now we are gonna put the two things together, the finishing result should be something that slightly works.

This is the uiBehaviour() procedure we left behind (MainView class).

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
 private void uiBehaviour()
 {
  //File chooser
  fc.setMultiSelectionEnabled(true);
  fc.setFileFilter(new FileFilter() {
   
   @Override
   public String getDescription() {
    return "only supported audio files (mp3, wav)";
   }
   
   @Override
   public boolean accept(File f) {
    if(f.isDirectory())
     return true;
    if(f.getName().endsWith(".mp3"))
     return true;
    if(f.getName().endsWith(".wav"))
     return true;
    return false;
   }
  });
  btnAdd.addActionListener(new ActionListener() {
   
   @Override
   public void actionPerformed(ActionEvent e) {
    int returnVal = fc.showOpenDialog(btnAdd);
    if(returnVal == JFileChooser.APPROVE_OPTION){
     File[] files = fc.getSelectedFiles();
     for(File f : files){
      player.addSong(f.getAbsolutePath());
      songList.addElement(f.getName());
      log("Added file " + f.getName() + " to playlist");
     }
    }
    else{
     log("No file selected");
    }
   }
  });
  //Song List
  jSongList.setModel(songList);
  jSongList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
  jSongList.setLayoutOrientation(JList.VERTICAL);
  //Event that triggers at double click
  jSongList.addMouseListener(new MouseAdapter()
  {
   public void mouseClicked(MouseEvent evt){
    JList list = (JList)evt.getSource();
    if(evt.getClickCount() == 2){
     log("Double click detected, moving to selected item.");
     int index = list.locationToIndex(evt.getPoint());
     player.setIndexSong(index);
     try {
      player.play();
     } catch (BasicPlayerException ev) {
      ev.printStackTrace();
     }
    }
   }
  });
  
  //Btn Delete
  btnDel.addActionListener(new ActionListener() {
   
   @Override
   public void actionPerformed(ActionEvent e) {
    //Executed Outside UI Thread
    BackgroundExecutor.get().execute(new Runnable() {
     
     @Override
     public void run() {
      int[] indexes = jSongList.getSelectedIndices();
      int removed = 0;
      for(int i : indexes)
      {
       log("Removed Song ("+(i-removed)+")" + songList.get(i-removed));
       player.removeSong(i-removed);
       songList.remove(i-removed);
       removed++;
      }
     }
    });
   }
  });
  //Play Btn
  btnPlay.addActionListener(new ActionListener() {
   
   @Override
   public void actionPerformed(ActionEvent e) {
    try {
     tooglePlay();
    } catch (BasicPlayerException e1) {
     e1.printStackTrace();
    }
   }
  });
  //Next and Previous btns
  btnNext.addActionListener(new ActionListener() {
   
   @Override
   public void actionPerformed(ActionEvent arg0) {
    try {
     player.nextSong();
     //seekbar.resetLastSeek();
    } catch (BasicPlayerException e) {
     log("Error calling the next song");
     e.printStackTrace();
    }
   }
  });
  
  btnPrev.addActionListener(new ActionListener() {
   
   @Override
   public void actionPerformed(ActionEvent arg0) {
    try {
     player.prvSong();
     //seekbar.resetLastSeek();
    } catch (BasicPlayerException e) {
     log("Error calling the previous song");
     e.printStackTrace();
    }
   }
  });
  //Player related behaviour
  player.addBasicPlayerListener(new BasicPlayerListener() {
   
   @Override
   public void stateUpdated(BasicPlayerEvent event) {
    if(event.getCode() == BasicPlayerEvent.EOM)
    {
     //seekbar.resetLastSeek();
     try {
      player.nextSong();
     } catch (BasicPlayerException e) {
      e.printStackTrace();
     }
     log("EOM event catched, calling next song.");
    }
    if(event.getCode() == BasicPlayerEvent.PAUSED){
     //btnPlay.setText(">");
     btnPlay.setIcon(playIcon);
    }
    if(event.getCode() == BasicPlayerEvent.RESUMED){
     //btnPlay.setText("||");
     btnPlay.setIcon(pauseIcon);
    }
   }
   
   @Override
   public void setController(BasicController arg0) {}
   
   @Override
   public void progress(int bytesread, long microseconds, byte[] pcmdata, Map properties) {
    //we don't want to use microseconds directly because it gets resetted on seeking
    seekbar.updateSeekBar(player.getProgressMicroseconds(), currentAudioDurationSec);
    if(wff != null)
     wff.updateWave(pcmdata);
    if(fdf != null)
     fdf.updateWave(pcmdata);
   }
   
   @Override
   public void opened(Object arg0, Map arg1) {
    //btnPlay.setText("||");
    btnPlay.setIcon(pauseIcon);
    jSongList.setSelectedIndex(player.getIndexSong());
    lblplaying.setText("Now Playing: " + songList.get(player.getIndexSong()));
    currentAudioDurationSec = player.getAudioDurationSeconds();
   }
  });
  
  //Timers Executor / Every 1 Second
  timersExec.scheduleAtFixedRate(new Runnable() {
   
   @Override
   public void run() {
    updateTimers();
    //updatePlayingText();
   }
  }, 0, 1, TimeUnit.SECONDS);
  
  
  titleExec.scheduleAtFixedRate(new Runnable() {
   
   @Override
   public void run() {
    updatePlayingText();
   }
  }, 0, 1, TimeUnit.SECONDS);
  
  //Btn Waveform
  btnShWf.addActionListener(new ActionListener() {
   
   @Override
   public void actionPerformed(ActionEvent arg0) {
    SwingUtilities.invokeLater(new Runnable(){
     @Override
     public void run()
     {
      wff = new WaveformFrame();
      wff.setVisible(true);
     }
    });
   }
  });
  //Btn that show freq diagram
  btnShDi.addActionListener(new ActionListener() {
   
   @Override
   public void actionPerformed(ActionEvent arg0) {
    fdf = new FreqDiagFrame();
    fdf.setVisible(true);
   }
  });
  //Open status window frame
  btnShSt.addActionListener(new ActionListener() {
   
   @Override
   public void actionPerformed(ActionEvent arg0) {
    //stf = new StatusFrame();
    stf.setVisible(true);
   }
  });
  
 }
 
 /**
  * Used by the Play/Pause button
  */
 private void tooglePlay() throws BasicPlayerException
 {
  if(songList.size() == 0)
   return;
  if(!player.isPaused()){
   player.pause();
   //btnPlay.setText(">");
   btnPlay.setIcon(playIcon);
   }
  else{player.play();}
 }

It's a lot of code so let's analyze it in order:

  • File chooser: It's a swing component that can be used to create an interface to select one or multiple files. I've set a file filter to let it see only files ending with .mp3 or .wav.
  • btnAdd will use the File chooser to get the songs the user selected, adding it to the playlist.
  • Song list: contains visual list of the playlist, I've added a behavior so that when a double click occurs it gets the index clicked and plays the selected song.
  • Btn Delete: delete the selected songs from the playlist
  • Play Btn: a simple play/pause toogle button.
  • Btn Next/ Btn Prev: move to next or previous song.
  • Player related behaviour: this is where all the fun things happens. We add a new event listener to the basic player, this way we can have some things done every time a certain event happens regarding the player.
    • We use progress to update the seekbar
    • We use opened to detect if a new song start playing ( a new audio file has been opened by the BasicPlayer class...)
    • With state update we detect if the streaming has been paused, stopped, resumed, etc.
  • Other: something regarding additional features

There are some concept that we already explained in the previous posts, the code shouldn't be that hard but for problems or anything just let me know in the comments.

martedì 10 giugno 2014

Implementing a seekbar for the audio player

Following the tutorial regarding the mp3 player, let's now focus on how to implement a simple seek bar for skipping music to a certain time. The perfect component for this might seem to be JSlider, however this component listener action is called each time the value of the slider is changed, we don't want to do this, mostly because the value is changed during playing. Let's start making our Seekbar class by extending a JProgressBar then.

public class SeekBar extends JProgressBar {

 private int updatedValue = 0; //sharing between different scopes

 /**
  * Update SeekBar position
  * @param progress in microseconds
  * @param totalVal in seconds
  */
 public void updateSeekBar(long progress, float totalVal)
 {
  BackgroundExecutor.get().execute(new UpdatingTask(progress, totalVal)); //Another thread will calculate the relative position
  setValue(updatedValue);
 }
 
 /**
  * Task used for updating the seek value in another thread.
  * @author Pierluigi
  */
 private class UpdatingTask implements Runnable {

  long progress; float totalVal;
  public UpdatingTask(long progress, float totalVal) {
   this.progress = progress;
   this.totalVal = totalVal;
  }
  
  @Override
  public void run() {
   int lp = (int) (progress / 1000); //progress comes in microseconds
   int seekLenght = getMaximum();
   int n = (int) ((lp/(totalVal*1000))*seekLenght); 
   updatedValue = lastSeekVal+n; 
  }
 }
 ///////////////////////////////////////////////////////////
 
 /**
  * New Constructor, sets a mouseListener
  * (extends JProgressBar)
  */
 public SeekBar()
 {
  super();
  setMaximum(10000); //it's smoother this way
  addMouseListener(new MouseListener() {
   
   @Override
   public void mouseReleased(MouseEvent e) {
   }
   
   @Override
   public void mousePressed(MouseEvent e) {
    float val =  ((float)e.getX()/getWidth()) * getMaximum();
    returnValueToPlayer(val);
    setValue((int)val);
    log("SeekBar pressed: " + val + " x: " + e.getX());
       
   }
   
   @Override
   public void mouseExited(MouseEvent e) {
   }
   
   @Override
   public void mouseEntered(MouseEvent e) {
   }
   
   @Override
   public void mouseClicked(MouseEvent e) {
   }
  });
 }
 
 /**
  * Informs the player about the relative value selected in the seekbar 
  * @throws BasicPlayerException 
  */
 private void returnValueToPlayer(float val){
  //TODO inform our player
 }

 private void log(String str)
 {
  System.out.println("SeekBar] " +str);
 }
}

As you can see I've used a simple MouseListener to implement what the a slider have native, by clicking in a certain x relative to the component I can set a correct value thanks to the power of proportions.
Let's recall that we don't want the swing single thread do math, even when it's this easy, for this we call a new Task executed by one background executor, since I want to have a central use of this class, I've implemented the following singleton:

/**
 * Using this for computing outside swing UI thread
 * @author Pierluigi
 *
 */
public class BackgroundExecutor {
 private static ExecutorService backgroundEx = Executors.newCachedThreadPool(); //UI thread shouldn't do math
 
 public BackgroundExecutor(){}
 
 public static ExecutorService get() { return backgroundEx;}
}

For more information about this see how a thread executor works. Now we can add and test our seekbar, let's add it into init() method from the MainView class like every simple other component.
SeekBar seekbar = new SeekBar();
...
//SeekBar
seekbar.setBounds(5, 10, _W-15, 10);
container.add(seekbar);

domenica 1 giugno 2014

Making a simple UI for the audio player

First thing first, let's make a nice and simple user interface for our audio player in java. For making the UI we'll use java Swing libraries. Swing is a single threaded model for building graphical interfaces in java, it became standard with java 5 (I think), you don't need to download external libs if you are using a recent version of java.
Let's say this is our basic idea, we'll start by defining the MainView.
Let's create a MainView class that extends JFrame, we'll define a main method that instantiate the main view of our program by calling SwingUtilities.invokeLater, this ensure that the component is created inside swing single threaded envoirment.
Important: Every action that modifies the state of the UI must be performed into the swing thread, however same thread is responsable for rendering, we'll see later in the tutorial how to let other thread execute medium-large computation that shouldn't be performed by java swing thread.
public class MainView extends JFrame{
 /**
  * Class/Frame constructor
  */
 public MainView()
 {
  init(); //see later implementation
  //initMenu();
  //uiBehaviour(); We'll define it later
 }

 //MAIN
 public static void main(String[] args){
  SwingUtilities.invokeLater(new Runnable(){
   @Override
   public void run()
   {
    MainView mv = new MainView();
    mv.setVisible(true);
   }
  });
 }
 
 private void log(String line)
 {
  System.out.println("UI-Main] " + line);
 }
}

Now let's define our components, let's not think about the seekbar now and discuss it later.

public class MainView extends JFrame{
 //Other
 DefaultListModel songList = new DefaultListModel();
 //Components
 JPanel container = new JPanel();
 JButton btnPlay = new JButton();
 JButton btnAdd = new JButton();
 JButton btnNext = new JButton();
 JButton btnPrev = new JButton();
 JButton btnShSt = new JButton();
 JButton btnShWf = new JButton();
 JButton btnShDi = new JButton();
 JButton btnDel = new JButton();
 JButton btnDelAll = new JButton();
 JMenuBar topMenu = new JMenuBar();
 JList jSongList = new JList(songList);
 JLabel lblplaying = new JLabel();
 JLabel lblst = new JLabel();
 JLabel lblet = new JLabel();
 JFileChooser fc = new JFileChooser();
...
}

Every component has a common and unique behaviour, if it's your first time with java swing, check component page docs.
Now let's see how to build the UI, for this I've created a single use isolated method, components listeners will be added in another one.
/**
  * Init Swing graphics UI 
  */
 private void init()
 {
  //MainView
  setTitle("Music Player - Java - 1.0");
  int _H = 300;
  int _W = 330;
  setSize(_W,_H);
  setLocationRelativeTo(null);
  setDefaultCloseOperation(EXIT_ON_CLOSE);
  //setResizable(false);
  //Container
  container.setLayout(null);
  getContentPane().add(container);
  //Buttons
  int btn_h = 35;
  int line1 = 80;
  JPanel contBtns = new JPanel();
  contBtns.setBounds(0, line1, 180, btn_h);
  btnPrev.setText("<<");
  btnPrev.setBounds(0, 0, 50, btn_h);
  btnPlay.setText(">");
  btnPlay.setMnemonic(KeyEvent.VK_SPACE);
  btnPlay.setBounds(0, 0, 50, btn_h);
  btnNext.setText(">>");
  btnNext.setBounds(0, 0, 50, btn_h);
  btnAdd.setText("Add Song");
  btnAdd.setBounds(_W-80,line1,70,btn_h);
  contBtns.add(btnPrev);
  contBtns.add(btnPlay);
  contBtns.add(btnNext);
  container.add(contBtns);
  container.add(btnAdd);
  //Now Playing Panel
  JPanel panelNP = new JPanel();
  panelNP.setLayout(new BoxLayout(panelNP, BoxLayout.PAGE_AXIS));
  panelNP.setToolTipText("Now Playing");
  panelNP.setBorder(BorderFactory.createMatteBorder(1, 0, 2, 0, Color.gray));
  panelNP.setBounds(5, line1-25, _W-15, 20);
  //JLabel lblnp = new JLabel("Now Playing:");
  lblplaying.setText("Now Playing: ");
  lblplaying.setBounds(5, 0, 100, 40);
  //panelNP.add(lblnp);
  panelNP.add(lblplaying);
  container.add(panelNP);
  //SongList
  int h_list = 100;
  //jSongList.setBounds(0, line1+50, _W, h_list);
  JScrollPane listScroller = new JScrollPane(jSongList);
  listScroller.setPreferredSize(new Dimension(_W-10,h_list));
  listScroller.setBounds(0, line1+50, _W-10, h_list);
  container.add(listScroller);
  //container.add(jSongList);
  //2Row Buttons
  int line2 = line1+h_list+50;
  JPanel contBtns2 = new JPanel();
  //contBtns2.setLayout(new BoxLayout(contBtns2, BoxLayout.PAGE_AXIS));
  contBtns2.setBounds(0, line2, 220, 50);
  //contBtns2.setBackground(Color.lightGray);
  btnShSt.setText("STAT");
  btnShWf.setText("ShWf");
  btnShDi.setText("ShDi");
  contBtns2.add(btnShSt);
  contBtns2.add(btnShWf);
  contBtns2.add(btnShDi);
  container.add(contBtns2);
  //DelBtns
  btnDel.setBounds(_W-55, line2+5, 45, 30);
  btnDel.setText("X");
  container.add(btnDel);
  //Labels song time
  JPanel contSlbl = new JPanel();
  contSlbl.setBounds(10, 15, _W-20, 20);
  contSlbl.add(lblst);
  contSlbl.add(lblet);
  lblst.setText("00:00");
  lblst.setBorder(new EmptyBorder(0, 0, 0, 200));
  lblet.setText("00:00");
  container.add(contSlbl);
 }

The code should be easy to read, I've used a JPanel as a general container, then by using other panels and setbounds I've created the UI. Pay a closer look about the JList and JScrollPane components though. Also, take a read here if you want to know more about layouts, by default a new Jpanel creates a BoxLayout (that's how I've made the row of buttons).

Next time we'll see how to add some functionality to our UI.

mercoledì 28 maggio 2014

How to make your own audio mp3 player in Java with BasicPlayer & Swing

Introduction

The focus of this and the next articles is to guide the reader thought the making of a simple and small mp3 player with Java. The goal is to give the player it's basic functionality (play, pause, skip, next song, etc), but also more sophisticated and useful features like a waveform visualizer. I can provide code for new missing features in the following lasts articles, I'm open for suggestions, just ask me in the comments or email.
Used technology for the mp3 player are: BasicPlayer API from javazoom and java Swing for making the User Interface.

Index
The project it's quite simple but it requires a lot of code, because it's better to divide the project covering different arguments. I'll add and update articles regarding the player in this section.

Why should I care?
The project should be interesting enough for who's interested in building a media player, for common folks interested in Java and programming it covers some general aspects like the usage of swing libraries, using multi threading in a "real time" model.

Download Project: here
Executable Jar: here

giovedì 3 aprile 2014

Tips and Tricks for improving your work time

There are a lot of tricks and shortcuts that can help you be faster while programming. Most of the time we became tired of doing simple tasks by switching between keyboard and mouse. There are a lot of shortcuts that windows uses, most of them I've learned by friends when I was little, they where common during the time of windows 95/98, but now I don't see so many people using them.
I think it's important to relay on shortcuts and by time starting using them can really improve your work time!

Windows Keyboard Shortcuts 
Win+d Minimize all windows on all Monitors. Press again to restore previous state
Win+m Minimize all windows on current Monitor
Win+Shift+m Restore previously minimized windows on current Monitor
Win+Home Set all windows to Minimized on current Monitor except active
Win+Space Preview Desktop / make windows transparent (May not work with all Settings)
Alt+tab,
alt+Shift+Tab
Cycles through open programs in taskbar. Hold alt and continuously press tab to move forward between applications. Release keys to switch to application selected. Add shift to reverse direction.
Alt+Ctrl+tab, then use arrow keys to select application Cycles through open programs in taskbar without needing to hold alt continuously. Pressalt+ctrl+tab once, then continue with arrow keys and press enter on application.
Win+e Start Windows Explorer (in My Computer)
Win+r Open the Run window
Win+f Open Windows Search. f3 on empty desktop works, too.

A lot more windows keyboard shortcuts can be found here
Eclipse Keyboard Shortcuts 
Since I usually use eclipse as my default editor, I would like to list here more useful shortcuts that I usually like to use while programming.
 
Ctrl+Space Call the auto-complete tool, It's awesome. Just write the first letter of an object/method/anything and then press it.
Crtl+F11 Run the last launched class
Ctrl+1 Quick Fix
Ctrl+Shift+F Format the source code
Ctrl+Shift+O Imports missing classes
Shift+F2 Shows javadoc for selected class/ type or method
Ctrl+3 Quick access to any eclipse command
For a more complete list take a look here.

Eclipse Programming Tips 
 
Still I've a lot to learn about organizing my projects, but I assure you, following these simple tips can save you some time in the future.
  • Always make a local /lib directory in the project to store imports, this way you won't lose reference in the future.
  • Invest in creating static main() methods for the classes you want to test frequently. (Just configure different Runs in Run Configuration).
  • When searching for libraries online just takes too much, take a look to mavent 2 eclipse.
  • Always comment your code, because you will forget everything you have done sooner or later. In eclipse write /* on top of a class definition and then press ctrl+space to autocomplete the class description and specification. This text will appear in eclipse windows when importing/using the class.
  • Add stackoverflow to your browser preferences
***

For last, a lot of people seems to not know the utility of the End and Home key while writing, with these keys you can easily move at the end and begin of the current line.

That's what I daily use, if you can give me some other tips feel free to write a comment.

mercoledì 5 marzo 2014

simple JSON classes in java > Java

Json is a powerful meta-language (if I can call it this way) for storing information in form of a string. It works much like xml, but it's much faster in parsing information, it's common usage in web services, javascript and php. You can find all you need to know about json here and here. There are many json libraries in java, maybe one of the best out there is Gson by google, the only problem with gson tough is that for some really easy work it still require creating specific classes to describe the structures of the object the json string we want to parse/encode rappresents. For this reason I prefer using another java library called json-simple, even tough it requires a massive usage of downcasts. There's really nothing more I can show about this library that isn't already showed in the example page, but I can show you an easy way to iterate trough a JSONArray if you didn't figure this out already. For example let's take this json array:
[
        {
            "id": "ord15",
            "colli": 1
        },
        {
            "id": "ord11",
            "colli": 2
        }
]
Let's create a simple class that generates a list of string containing the ids specified
 private void genOrdIDList(String ordiniArrayStr) throws org.json.simple.parser.ParseException
 {
  List list = new ArrayList();
  JSONParser parser = new JSONParser();
  JSONArray ordini  = (JSONArray) parser.parse(ordiniArrayStr);
  Iterator iter = ordini.iterator();
  while(iter.hasNext())
  {
   JSONObject obj = (JSONObject) iter.next();
   list.add((String) obj.get("id"));
  }
  listIdOrdini= list;
 }
With the Iterator object we get from the JSONARRAY() class we can easly access to every element of the array we are parsing. Again, more explanation and example about encoding and decoding with json-simple can be found here: https://code.google.com/p/json-simple/ I hope you now have a good time with json.