Java, write once, run away!

This blog is mainly about Java...

Thursday, September 10, 2015

20 tips to reach your goals!

Here is my talk on #JavaZone with the title "20 tips to reach your golas". Hope you benefit from it!

20 tips to reach your goals! from JavaZone on Vimeo.

Tuesday, March 17, 2015

Get Location headers from response in AngularJS and Dropwizard

You have googled and found out that
 headers('Location')  
is the method to use to get the location?
But you always get undefined?
But in your developer tools you can see the Location in the header?

Perhaps you are using CORS (Cross Origin Resource Sharing)?
Enabling CORS only exposes a small number of the available headers by default and if you want more you have to expose them your self.

Use the ExposedHeaders
 // Enable CORS headers  
 FilterRegistration.Dynamic cors = environment.servlets().addFilter("CORS", CrossOriginFilter.class);  
 // Configure CORS parameters  
 cors.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");  
 cors.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "Content-Type,Authorization,X-Requested-With,Content-Length,Accept,Origin");  
 cors.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "OPTIONS,GET,PUT,POST,DELETE,HEAD");  
 cors.setInitParameter(CrossOriginFilter.ALLOW_CREDENTIALS_PARAM, "true");  
 cors.setInitParameter(CrossOriginFilter.EXPOSED_HEADERS_PARAM, "Content-Type,Authorization,X-Requested-With,Content-Length,Accept,Origin,Location")
 // Add URL mapping  
 cors.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");  

Note the highlighted line. That did the trick!

Thursday, July 19, 2012

Unit testing with JOptionPane

If you are like me, you would still like to be able to unit test your swing applications.

However, its difficult to do this when you have a JOptionPane.showConfirmationDialog, and the user needs to type in yes or no.

In this blog post I will show you how you can accomplish this without needing the user to add anything, or changing your domain code too much.


Lets say you have a simple JFrame you want to test that contains a JOptionPane.


public class SimpleFrame extends JFrame {

  public boolean simpleMethod() {
    int showConfirmDialog = JOptionPane.showConfirmDialog(this, "Can we write test for this?", "Question", JOptionPane.YES_NO_OPTION);
    return showConfirmDialog == JOptionPane.YES_OPTION;
  }
}


Now if you create a JUnit test for this, and run it, you will get a JOptionPane and you need to press the YES or NO button.

To avoid this we can change the code to use an interface and then we can create a mock OptionPane for you tests.



/*
* Note you can add all the methods you use in your application
*/
public interface OptionPane {

      /**
       *  @see JOptionPane#showConfirmDialog(Component, Object, String, int, int);
       */
      int showConfirmDialog(Component parentComponent, Object message, String title, int optionType, int messageType);
}


Create three implementations of this interface. One that is delegating to JOptionPane, and the others that will be our mock. One of the mocks will return yes, the other no.


public class DefaultOptionPane implements OptionPane {

      public int showConfirmDialog(Component parentComponent, Object message, String title, int optionType, int messageType) {
         return JOptionPane.showConfirmDialog(parentComponent,message,title,optionType,messageType);
      }
}

public class YesMockOptionPane extends MockOptionPane {

        @Override
 public int showConfirmDialog(Component parentComponent, Object message, String title, int optionType, int messageType) {
   return JOptionPane.YES_OPTION;
 }
}


public class NoMockOptionPane extends MockOptionPane {

        @Override
 public int showConfirmDialog(Component parentComponent, Object message, String title, int optionType, int messageType) {
   return JOptionPane.NO_OPTION;
 }
}



Now change your application and add the OptionPane


public class SimpleFrame extends JFrame {
  private OptionPane optionPane = DefaultOptionPane();
  
  public boolean simpleMethod() {
    int showConfirmDialog = optionPane.showConfirmDialog(this, "Can we write test for this?", "Question", JOptionPane.YES_NO_OPTION);
    return showConfirmDialog == JOptionPane.YES_OPTION;
  }

  public void setOptionPane(OptionPane o) { this.optionPane = o; }
}


Now in your tests you use the appropriate MockOptionPane.



@Test
public void test() throws Exception {
  SimpleFrame s = new SimpleFrame()
  s.setOptionPane(new YesMockOptionPane());
  Assert.assertTrue(s.simpleMethod());
}

Thursday, June 7, 2012

Always use unique passwords!

Recently we found out that LinkedIn has managed to loose our passwords, so that they encourage people to create new passwords.

And if you are like many others, you have the same password for other sites. With a very easy trick you can guarantee a unique password for all your sites, and its quite easy.
All you have to do is remember an easy formula which you decide.

The formula is:
followed by the first three (or last three) letters in the url. You can combine this to put it before or after your password.

So for LinkedIn for instance it would be: lin or din or lin or din

By doing this, you don't have to login to all the other sites and change your password if your password ever gets compromised.

Tuesday, May 15, 2012

Add custom Font to your Java Swing application

This task was not that trivial as one might think.

It seems that you need to manually set the Font for each of the UI types.
To find out which one that was supported in my System, I did the following:


java.util.Enumeration<Object> keys = UIManager.getDefaults().keys();
        while (keys.hasMoreElements()) {
            Object key = keys.nextElement();
            Object value = UIManager.get(key);
            if (value instanceof FontUIResource) {
                System.out.println(key.toString());
            }
        }

Which printed out the following:


OptionPane.buttonFont
List.font
TableHeader.font
Panel.font
TextArea.font
ToggleButton.font
ComboBox.font
ScrollPane.font
Spinner.font
RadioButtonMenuItem.font
Slider.font
EditorPane.font
OptionPane.font
ToolBar.font
Tree.font
CheckBoxMenuItem.font
TitledBorder.font
FileChooser.listFont
Table.font
MenuBar.font
PopupMenu.font
Label.font
MenuItem.font
MenuItem.acceleratorFont
TextField.font
TextPane.font
CheckBox.font
ProgressBar.font
FormattedTextField.font
CheckBoxMenuItem.acceleratorFont
Menu.acceleratorFont
ColorChooser.font
Menu.font
PasswordField.font
InternalFrame.titleFont
OptionPane.messageFont
RadioButtonMenuItem.acceleratorFont
Viewport.font
TabbedPane.font
RadioButton.font
ToolTip.font
Button.font


Next, I had to set each one of these values manually:

 final Font TAHOMA_PLAIN_11 = new Font("Tahoma", Font.PLAIN, 11);
 final Font MONOSPACED_PLAIN_13 = new Font("Monospaced", Font.PLAIN, 13);
 final Font SEGOE_UI_PLAIN_12 = new Font("Segoe UI", Font.PLAIN, 12);
 final Font DIALOG_PLAIN_12 = new Font("Dialog", Font.PLAIN, 12);


        UIManager.put("OptionPane.buttonFont", SwingUtils.SEGOE_UI_PLAIN_12);
        UIManager.put("List.font", TAHOMA_PLAIN_11);
        UIManager.put("TableHeader.font", TAHOMA_PLAIN_11);
        UIManager.put("Panel.font", TAHOMA_PLAIN_11);
        UIManager.put("TextArea.font", MONOSPACED_PLAIN_13);
        UIManager.put("ToggleButton.font", TAHOMA_PLAIN_11);
        UIManager.put("ComboBox.font", TAHOMA_PLAIN_11);
        UIManager.put("ScrollPane.font", TAHOMA_PLAIN_11);
        UIManager.put("Spinner.font", TAHOMA_PLAIN_11);
        UIManager.put("RadioButtonMenuItem.font", SwingUtils.SEGOE_UI_PLAIN_12);
        UIManager.put("Slider.font", TAHOMA_PLAIN_11);
        UIManager.put("EditorPane.font", TAHOMA_PLAIN_11);
        UIManager.put("OptionPane.font", SwingUtils.SEGOE_UI_PLAIN_12);
        UIManager.put("ToolBar.font", SwingUtils.SEGOE_UI_PLAIN_12);
        UIManager.put("Tree.font", TAHOMA_PLAIN_11);
        UIManager.put("CheckBoxMenuItem.font", SwingUtils.SEGOE_UI_PLAIN_12);
        UIManager.put("TitledBorder.font", TAHOMA_PLAIN_11);
        UIManager.put("FileChooser.listFont", SwingUtils.SEGOE_UI_PLAIN_12);
        UIManager.put("Table.font", TAHOMA_PLAIN_11);
        UIManager.put("MenuBar.font", SwingUtils.SEGOE_UI_PLAIN_12);
        UIManager.put("PopupMenu.font", SwingUtils.SEGOE_UI_PLAIN_12);
        UIManager.put("Label.font", TAHOMA_PLAIN_11);
        UIManager.put("MenuItem.font", SwingUtils.SEGOE_UI_PLAIN_12);
        UIManager.put("MenuItem.acceleratorFont", SwingUtils.SEGOE_UI_PLAIN_12);
        UIManager.put("TextField.font", TAHOMA_PLAIN_11);
        UIManager.put("TextPane.font", TAHOMA_PLAIN_11);
        UIManager.put("CheckBox.font", TAHOMA_PLAIN_11);
        UIManager.put("ProgressBar.font", TAHOMA_PLAIN_11);
        UIManager.put("FormattedTextField.font", TAHOMA_PLAIN_11);
        UIManager.put("CheckBoxMenuItem.acceleratorFont", SwingUtils.DIALOG_PLAIN_12);
        UIManager.put("Menu.acceleratorFont", SwingUtils.DIALOG_PLAIN_12);
        UIManager.put("ColorChooser.font", SwingUtils.DIALOG_PLAIN_12);
        UIManager.put("Menu.font", SwingUtils.SEGOE_UI_PLAIN_12);
        UIManager.put("PasswordField.font", TAHOMA_PLAIN_11);
        UIManager.put("InternalFrame.titleFont", SwingUtils.SEGOE_UI_PLAIN_12);
        UIManager.put("OptionPane.messageFont", SwingUtils.SEGOE_UI_PLAIN_12);
        UIManager.put("RadioButtonMenuItem.acceleratorFont", SwingUtils.DIALOG_PLAIN_12);
        UIManager.put("Viewport.font", TAHOMA_PLAIN_11);
        UIManager.put("TabbedPane.font", TAHOMA_PLAIN_11);
        UIManager.put("RadioButton.font", TAHOMA_PLAIN_11);
        UIManager.put("ToolTip.font", SwingUtils.SEGOE_UI_PLAIN_12);
        UIManager.put("Button.font", TAHOMA_PLAIN_11);

Running these different JUnit tests proved it worked:

@Test
    public void testFindJavaDefaultFonts() throws Exception {
        java.util.Enumeration<Object> keys = UIManager.getDefaults().keys();
        while (keys.hasMoreElements()) {
            Object key = keys.nextElement();
            Object value = UIManager.get(key);
            if (value instanceof FontUIResource) {
                Assert.assertEquals("Dialog", ((Font)value).getFamily());
            }
        }
    }
    
    @Test
    public void testFindSystemDefaultFonts() throws Exception {
        final Font font = new Font("Arial", Font.PLAIN, 12);
        UIManager.put("TextField.font", font);
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        UIManager.put("List.font", font);

        java.util.Enumeration<Object> keys = UIManager.getDefaults().keys();
        while (keys.hasMoreElements()) {
            Object key = keys.nextElement();
            Object value = UIManager.get(key);
            if (value instanceof FontUIResource) {
                Assert.assertFalse(key.toString().equals("TextField.font"));
                Assert.assertFalse(key.toString().equals("List.font"));
                
            }
        }
        
        Font font2 = UIManager.getFont("TextField.font");
        Assert.assertNotNull(font2);
        Assert.assertSame(font, font2);

        Font font3 = UIManager.getFont("List.font");
        Assert.assertNotNull(font3);
        Assert.assertSame(font, font3);
    }
    
    @Test
    public void testCustomFonts() throws Exception {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtils.updateDefaultFonts(); //Where I put all my UIManager.put(...) lines
        java.util.Enumeration<Object> keys = UIManager.getDefaults().keys();
        while (keys.hasMoreElements()) {
            Object key = keys.nextElement();
            Object value = UIManager.get(key);
            if (value instanceof FontUIResource) {
                //This should fail if it comes here since we have set everything manually
                Assert.fail();
            }
        }
        
        Font font = UIManager.getFont("List.font");
        Assert.assertNotNull(font);
        Assert.assertEquals(font.getFamily(), "Tahoma");
    }

If there is an easier way to do this, please do share!

Labels