Wednesday 19 September 2012

How to create or initialize Generic Type Array


  • solution 1





  • Limitation: It's not work if input array is null.

    public static <T> T[] subarray(T[] array, int startIndexInclusive, int endIndexExclusive) {
            if (array == null) {
                return null;
            }
    
            if (startIndexInclusive < 0) {
                startIndexInclusive = 0;
            }
            if (endIndexExclusive > array.length) {
                endIndexExclusive = array.length;
            }
    
            Class<?> type = array.getClass().getComponentType();
            int newSize = endIndexExclusive - startIndexInclusive;
            if (newSize < 0) {
                final T[] emptyArray = (T[]) Array.newInstance(type, 0);
                return emptyArray;
            }
    
            T[] subarray = (T[]) Array.newInstance(type, newSize);
            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
            return subarray;
        }
    
  • solution 2
  • It's work if input array is null. But it's more verbose for invoking.
    public static <T> T[] subarray(T[] array, int startIndexInclusive, int endIndexExclusive, Class<T>> clazz) {
         T[] emptyArray = (T[]) Array.newInstance(clazz, 0);
    
            if (array == null) {
                return emptyArray;
            }
    
            if (startIndexInclusive < 0) {
                startIndexInclusive = 0;
            }
            if (endIndexExclusive > array.length) {
                endIndexExclusive = array.length;
            }
    
            if (newSize < 0) {
                return emptyArray;
            }
    
            T[] subarray = (T[]) Array.newInstance(clazz, newSize);
            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
            return subarray;
        }
    

    Tuesday 18 September 2012

    Java Swing JTextField: Number only and give length



  • Solution 1

  • Simple but It can't work for "CTRL + V" scenario
    private class NumberOnlyAdapter extends KeyAdapter {
    
            private final int maxLength;
    
            private NumberOnlyAdapter(int maxLength) {
                this.maxLength = maxLength;
            }
    
            @Override
            public void keyTyped(KeyEvent e) {
                char typed = e.getKeyChar();
                CharMatcher notDigit = noneOf("0123456789").and(isNot((char) VK_BACK_SPACE)).and(isNot((char) VK_DELETE));
                JTextField textField = (JTextField) e.getComponent();
                if (notDigit.apply(typed) || textField.getText().length() >= maxLength) {
                    e.consume();
                }
            }
    
        }
    
    ...
    int maxLength = 8;
    JTextField textField = new JTextField();
    textField.addKeyListener(new NumberOnlyAdapter(maxLength));
    
  • Solution 2

  • It's work for all conditions
    import static org.apache.commons.lang3.StringUtils.*;
    
    import javax.swing.text.AttributeSet;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.DocumentFilter;
    
    public class NumericOnlyAndMaxLengthFilter extends DocumentFilter {
        private int maxLength = 0;
    
    
        public NumericOnlyAndMaxLengthFilter() {
           // allow any length of numeric
        }
    
        public NumericOnlyAndMaxLengthFilter(int maxLength) {
            this.maxLength = maxLength;
        }
    
        @Override
        public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
            if (isNumeric(string)) {
                if (isExceedMaxLength(fb, string)) {
                    return;
                }
                super.insertString(fb, offset, string, attr);
            }
        }
    
        @Override
        public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
            if (isNumeric(text)) {
                if (isExceedMaxLength(fb, text)) {
                    return;
                }
                super.insertString(fb, offset, text, attrs);
            }
        }
    
        private boolean isExceedMaxLength(FilterBypass fb, String text) {
            return maxLength > 0 && (fb.getDocument().getLength() + text.length()) > maxLength;
        }
    }
    
    ...
    int maxLength = 8;
    JTextField textField = new JTextField();
    ((AbstractDocument)textField .getDocument()).setDocumentFilter(new NumericOnlyAndMaxLengthFilter(maxLength));
    

    Thursday 13 September 2012

    Maven generate HTML Junit report

    • add to pom.xml
    • 
          org.apache.maven.plugins
          maven-surefire-plugin
          
              true
          
      
      
      
          org.jvnet.maven-antrun-extended-plugin
          maven-antrun-extended-plugin
          
              
                  test-reports
                  test
                  
                      
                          
                              
                                  
                              
                              
                          
                      
                  
                  
                      run
                  
              
          
          
              
                  org.apache.ant
                  ant-junit
                  1.8.4
              
              
                  org.apache.ant
                  ant-trax
                  1.8.0
              
          
      
      
    • Don't bind the AntRun plugin to the test phase, move the configuration outside the execution and call mvn antrun:run on the command line to generate the reports when wanted.
    • Or use the testFailureIgnore option of the test mojo and set it to true in the surefire plugin
    • Use maven command arguments
    • $mvn test -Dmaven.test.failure.ignore=true
      

    Wednesday 5 September 2012

    Java - better performance String formatter

    /**
         * Substitutes each {@code %s} in {@code template} with an argument. These
         * are matched by position - the first {@code %s} gets {@code args[0]}, etc.
         * If there are more arguments than placeholders, the unmatched arguments will
         * be appended to the end of the formatted message in square braces.
         *
         * @param template a non-null string containing 0 or more {@code %s}
         *     placeholders.
         * @param args the arguments to be substituted into the message
         *     template. Arguments are converted to strings using
         *     {@link String#valueOf(Object)}. Arguments can be null.
         */
        public static String format(String template, Object... args) {
            template = String.valueOf(template); // null -> "null"
            // start substituting the arguments into the '%s' placeholders
            StringBuilder builder = new StringBuilder(template.length() + 16 * args.length);
            int templateStart = 0;
            int i = 0;
            while (i < args.length) {
                int placeholderStart = template.indexOf("%s", templateStart);
                if (placeholderStart == -1) {
                    break;
                }
                builder.append(template.substring(templateStart, placeholderStart));
                builder.append(args[i++]);
                templateStart = placeholderStart + 2;
            }
            builder.append(template.substring(templateStart));
    
            // if we run out of placeholders, append the extra args in square braces
            if (i < args.length) {
                builder.append(" [");
                builder.append(args[i++]);
                while (i < args.length) {
                    builder.append(", ");
                    builder.append(args[i++]);
                }
                builder.append(']');
            }
    
            return builder.toString();
        }
    
       public static void main(String[] args) {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.start();
            String result = Formatter.format("My name is: %s. I was start from: %s. ", "Sean", "25/05/2012", "another value here");
            stopwatch.stop();
            System.out.println(stopwatch.elapsedTime(TimeUnit.NANOSECONDS));
            System.out.println(result);
            stopwatch.reset();
            stopwatch.start();
            result = String.format("My name is: %s. I was start from: %s.", "Sean", "25/05/2012", "another value here");
            stopwatch.stop();
            System.out.println(stopwatch.elapsedTime(TimeUnit.NANOSECONDS));
            System.out.println(result);
        }