Tuesday, July 22, 2014

Allow java swing to send all error messages to a JOptionPane

By default java swing will send error messages to the java console.  This would be ok if the java console would pop up from a runnable java application, but it does not and have not found a way to do so.  If otherwise instructed, java will hide all messages (even fatal ones) from the user during runtime.  This is not acceptable behavior, so I have found a solution.  Route the messages to JOptionPanes like a popup.

During the main(String[] args) procedure, insert the following code:

public static void main(String[] args) {
System.out.println(SwingUtilities.isEventDispatchThread());
SwingUtilities.invokeLater(new Runnable() {
public void run() {
System.out.println(SwingUtilities.isEventDispatchThread());
try {
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
// TODO Auto-generated method stub
JOptionPane.showMessageDialog(null,
   e.toString(),
   "Error",
   JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
}
});
                                        ****START CODE HERE****


System.out.println(SwingUtilities.isEventDispatchThread());

} catch (Exception e) {
e.printStackTrace();
}
}
});
}

Create dynamically loading java swing objects

  I gotta say, java swing isn't the greatest framework for creating interfaces with objects that need to be updated depending on selections.  I came across this issue when I trying to create a panel that would dynamically allocate objects depending on the class that this panel was inheriting by the users choice from a radio button selection.  When a panel was created with the allocated objects, the containing panel would not recognize those changes even after repainting and revalidating.  The trick is knowing how the event driven swing framework works.  Since the objects were not originally created by the event dispatch thread a.k.a. AWT-EventQueue, they will not take effect until an EventQueue owned object "affects" it.  So how would the EventQueue thread "own" the interface objects that were not created in the first place?
  In comes the SwingWorker.  This is an abstract class that allows dynamic background processes to update the object being modified even if the process is a concurrent running process.  The SwingWorker can publish the object at any time even in the middle of a process since it publishes itself to the even dispatch thread which will then take ownership of the object in need of updating.  Now loading bars and live dynamic object allocation are possible.  I've created a class below that extends the SwingWorker class, but it can take any Swing parent component (the one that contains the object needed to be modified) and a method associated with a child Swing component.  Depending on what the child method does, this will update the interface of the parent that will be containing the childs actions.
  For example, I have a Jpanel that contains another Jpanel that will update some JComboBoxes with different values.  The kicker is that depending on the child class, there can different quantities of JComboBoxes.

Sample Code:

public class DocTypeContainPanel extends JPanel{

...

SwingObjectWorker temp1 = null;
SwingObjectWorker temp2 = null;

temp1 = new SwingObjectWorker(pnlSearchPropsContainer, pnlSearchProps.getPropsPanel());
temp1.execute();

temp2 = new SwingObjectWorker(pnlDocPropsContainer, pnlDocProps.getPropsPanel());
temp2.execute();

revalidate();

repaint();

...

}


class SwingObjectWorker extends SwingWorker<JComponent, Void> {
private JComponent parentComp;
private JComponent childComp;

public SwingObjectWorker (JComponent inparentComp, JComponent inchildComp){

parentComp = inparentComp;
childComp = inchildComp;
final SwingObjectWorker temp = this;

this.addPropertyChangeListener(new PropertyChangeListener() {

@Override
public void propertyChange(PropertyChangeEvent arg0) {
if (StateValue.DONE == temp.getState()) {
try {
parentComp.removeAll();
parentComp.add(get(), "cell 0 0,grow");
parentComp.setVisible(true);
parentComp.revalidate();
parentComp.repaint();
System.out.println("Swing Worker Done!");

// TODO: insert code to run on the EDT after move determined


} catch (InterruptedException e) {

e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
});
}


  @Override
  public JComponent doInBackground() {
return childComp;
  }
   
  @Override
  public void done() {
     }
}

Friday, July 11, 2014

Using a TP-Link TL-WN725N USB Wifi Adapter on a Raspberry Pi

For those that purchased a TP-Link TL-WN725N because it was really cheap and didn't bother to check the linux driver support for it... oops

Well here's your fix.

This is been tested on raspbian on the rpi (raspberry pi), your mileage may vary on other operating systems and architectures.

First, in order to compile drivers for linux, we need the linux headers.  Running rpi-update does not provide the headers in with the update since the kernel is precompiled.  What we have to do is find the headers for the current commit of the kernel installed.  We do this by running an awesome tool called rpi-source which downloads the correct headers for your specific kernel version that is currently installed on your rpi.

run in a directory of your choice:
sudo wget https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source -O /usr/bin/rpi-source && sudo chmod +x /usr/bin/rpi-source && /usr/bin/rpi-source -q --tag-update

If you get a message that states "gcc version check: mismatch between gcc (4.6.3) and /proc/version (4.7.2) Skip this check with --skip-gcc", you can simply ignore it by running "rpi-source --skip-gcc"

What this will do is create and install the headers and modules in your /lib/modules/ folder.  Now that you have the kernel headers installed, we can move on to compiling the driver.  The following comes straight from the examples used for the "rpi-source" repository on github.

You may read and follow the directions here:
https://github.com/notro/rpi-source/wiki/Examples-on-how-to-build-various-modules#tp-link-tl-wn725n-version-2-lwfinger

Otherwise just follow the instructions below which is copied and pasted from the repository:
______________________________________________________________________________
$ uname -a
Linux raspberrypi 3.12.21+ #1 PREEMPT Sat Jun 14 13:44:18 CEST 2014 armv6l GNU/Linux

$ git clone https://github.com/lwfinger/rtl8188eu.git
$ cd rtl8188eu

$ make all

$ sudo make install

$ sudo depmod

$ sudo modprobe 8188eu

$ lsmod
Module                  Size  Used by
8188eu                796381  0
______________________________________________________________________________

After that, you should have a working TL-WN725N wifi adapter.

Major props goes to the developer of rpi-source and for the open source 8188eu driver for the wifi adapter.

Enjoy!