Friday, 31 July 2015

Amazon Appstore Features for Android Developers

Leave a Comment
Amazon Appstore has a number of unique features compared with the more well-established Android Market, other competing Android app stores, and even other platforms. It's some of these same unique features and practices that have recently come under fire. Will they help or hurt you, the app developer, and the greater Android application marketplace in general? What about users? When do the unique features of Amazon Appstore work to our advantage, and when can they backfire?
Amazon Appstore has a number of unique features compared with the more well-established Android Market, Amazon Appstore Features for Android Developers

Special Amazon Appstore Features for Android

So, what are some of these unique features we're talking about?

  • The ability to try apps before buying them
  • Various app discovery mechanisms including referrals and sophisticated app categories
  • Testing and trust
  • No officially listed return policy (or one that's easy to find)
  • Amazon-controlled customer pricing and the free daily paid app promotion
  • We'll cover each of these below. While this list isn't complete, it includes some of the most intriguing features of Amazon Appstore that are causing a bit of stir in the development community.

Feature #1: Trying Apps Before Buying Them

The online storefront for Amazon Appstore has a feature where you can use an app right in your browser. They currently do this in an emulated environment running Android 2.2.1. This is a great way for users to try out games and applications before they buy them.




Naturally, not all applications can be demonstrated in this way. Games, for example, may not perform as well or have as natural of controls. As such, not all apps are available in this way. Many free and paid apps, however, are.

The applications that are available, however, can be used in full for 30 minutes. To get more time, users can simply reload it. Data isn't saved, but maybe the users will get all they need out of this. This isn't unlike Android Market's return policy of 15 minutes, except it's not just one-time. In fact, it's more like when the return policy was 24 hours; many apps and games could be completed in that time. It's unclear who has ultimate control over what apps are available for Test Drive. Apps with advertising, or other usage based monetization, will do great.
Why not let the user download the app to their device and try it? Well, this didn't work well on Android Market. Users often used the app and then returned it for a full refund. This messed with developer's statistics and royalties. It was incredibly frustrating and developers felt exploited with no recourse. This is what makes the test drive feature of Amazon Appstore unique.

Feature #2: Discovering Apps, Everywhere

Amazon is a very large online retail store with a diverse set of products for sale. As such, they have a sophisticated system for displaying related items to shoppers. Apps are now part of these item offerings. When a shopper is browsing various physical product categories, related apps may be shown. This puts the apps in front of the hundreds of millions of shoppers who use the Amazon site every month, regardless of whether they have an Android device yet, or not.

The apps are also organized into many more categories than they are on other markets. For example, Android Market has about eight categories of games (including Widgets and Live Wallpapers), whereas Amazon Appstore has sixteen categories.

In addition to a more precise level of organization, there are several sections for apps that are either created by the system or curated and edited by real people. These include lists of popular apps, featured apps and categories, and so on.

Feature #3:Trust and Testing

Amazon has been around long enough, and has enough regular customers, that they've got loyal users. They've gained a level of trust and brand recognition. In order to continue to meet the desires of their customers, Amazon doesn't just let any app onto their app store. In fact, listing apps on the app store is not free; there's a $99 annual fee. This is similar to other competing mobile platforms, and is still a lower bar than older, legacy platforms required.

This aspect alone filters the applications available to users. However, Amazon also tests all apps they host in their store. According to their website, the tests include basic checks for malware, application usability, verification that the app doesn't interfere with the functionality of the device and does what it claims to do. This doesn't guarantee that accepted apps are bug free, but it does mean they have been reviewed before users get to download them.

However, looking through the reviews of many popular Android apps available on Amazon Appstore, there are often a very large percent of reviews that claim the app doesn't work on a particular user's device. This will often be consistent for a particular model. While we can't claim to know what's going on here, the testing doesn't seem to exhaustively check every Android device or platform that the Amazon Appstore supports. In addition, the controls for limiting which devices can download which apps either don't exist or isn't working as it should.

Feature #4:Application Return Policy

What if you were one of the people to download a paid app that didn't work on your phone? Can you return it quickly and easily? Is it worth the effort if you only paid 99 cents?

Like most large retailers, Amazon has many different return policies, depending on the product in question. Strangely lacking, however, is a quick way to find the return policy for apps. It's not included in the digital goods section.

This likely means that whatever policy is followed is unofficial, at best. Our guess would be that they're still trying to figure out how to best structure a return policy that gives users some recourse when an app is just plain bad without inviting policy abuse.

Also along these lines, there's no good way for a developer to contact customers directly through Amazon. If users don't go to the developer's site and support mechanisms, there's not much a developer can do to avoid negative ratings.

Feature #5: Application Pricing Policy

Amazon adjusts prices regularly on physical products. Anyone who has ever had a whole bunch of "save for later" items in their cart will have seen that product prices change on occasion. While we're not sure if this same system is in play with the app store pricing (yet), Amazon clearly retains final control over the price to customers. The initial agreement for paid apps says that the developer will always get some minimum amount, but there's no way for the developer to control the exact amount they get or what the customer pays. What this means for a developer is that if their margins are very low, or they have a fixed licensing fee for some technology they use, guaranteeing that each sale is above this amount may be difficult.

Then there's the "free app of the day" program. This is an opt-in program where Amazon chooses one premium app each day to provide for free. All apps provided in this way are usually paid apps. It's a highly visible promotion and is a great way for consumers to get apps they wouldn't otherwise have paid for. It's also a great for consumers to see what's available quality-wise if they had spent some money on apps. Finally, it's good for application developers in that it can give them a big boost in users if they are trying to build momentum.




For an app that has advertising or usage based monetization, this is great. The exposure brings in tons of app downloads in just one day. According to a couple of sources, this is often in excess of 100,000 downloads in the 24-hour period of the promotion. The concept is that your app then will garner more attention and reviews, rank higher on the best selling lists, rank higher in the ratings with more ratings, get better word of mouth promotion, and provide your service with more users.

Does that really happen? It depends on the app. For a truly well designed app, the free app of the day promotion can really capture the attention of consumers. An app heavily dependent on social features that needs more users may reach critical mass due to this sort of promotion.

What if the app, though, has a minor bug or doesn't work on some handset models? This sort of promotion can also backfire in a big way. Negative ratings are hard to overcome once they're logged. Amazon Appstore doesn't yet list ratings for different versions of an app, which may help those who suffer from this problem.

Perhaps even worse, if an app ends up on this promotion in the hopes of increasing sales dramatically, but has some problem or just isn't particularly interesting to that many users, the developer may find themselves with thousands of new users to support that haven't, and never will, paid a dime. And what if each of those users is using resources that cost money, such as server storage or bandwidth, but the app or service doesn't have any alternative methods of monetization? You could end up losing money on the whole deal.

But wait, you might be thinking. Doesn't Amazon owe the developer a certain minimum amount? Perhaps you've even heard of people downloading free apps simply to support the developer. Well, you'd be right on both counts. Except for one small wrinkle that has come to light recently: the daily free app promotion appears to be done under a separate agreement where the app developer doesn't actually make any money.

As an app developer, you'll want to think carefully about the big picture before jumping on seemingly "too good to be true" promotions: it just might be too good to be true for your business.

And finally, read the developer agreements very closely.

Conclusion

We're happy to see such a well respected company as Amazon supporting the Android platform not just by selling numerous Android devices, but with their own app store platform, the Amazon Appstore. While Amazon Appstore has many unique features compared to other Android application marketplaces, developers need to be aware of the ramifications of publishing through this channel. The good news is, Amazon Appstore is still relatively young, and likely to respond to developer and user feedback. Android Market remains the most popular marketplace for Android apps, but of all of the alternate markets we've seen arise, Amazon Appstore is the one you shouldn't ignore.
Read More

Thursday, 30 July 2015

Make Snake Game In Swing

Leave a Comment
Snake is an older classic video game. It was first created in late 70s. Later it was brought to PCs. In this game the player controls a snake. The objective is to eat as many apples as possible. Each time the snake eats an apple, its body grows. The snake must avoid the walls and its own body. This game is sometimes called Nibbles.
How to Make Snake Game In Swing,Make Snake Game In Swing,Snake Game In Swing,Game In Swing,

Development

The size of each of the joints of a snake is 10px. The snake is controlled with the cursor keys. Initially, the snake has three joints. If the game is finished, the "Game Over" message is displayed in the middle of the board.

Board.java

package com.blogspot.geekonjava;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Board extends JPanel implements ActionListener {

    private final int B_WIDTH = 300;
    private final int B_HEIGHT = 300;
    private final int DOT_SIZE = 10;
    private final int ALL_DOTS = 900;
    private final int RAND_POS = 29;
    private final int DELAY = 140;

    private final int x[] = new int[ALL_DOTS];
    private final int y[] = new int[ALL_DOTS];

    private int dots;
    private int apple_x;
    private int apple_y;

    private boolean leftDirection = false;
    private boolean rightDirection = true;
    private boolean upDirection = false;
    private boolean downDirection = false;
    private boolean inGame = true;

    private Timer timer;
    private Image ball;
    private Image apple;
    private Image head;

    public Board() {

        addKeyListener(new TAdapter());
        setBackground(Color.black);
        setFocusable(true);

        setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
        loadImages();
        initGame();
    }

    private void loadImages() {

        ImageIcon iid = new ImageIcon("dot.png");
        ball = iid.getImage();

        ImageIcon iia = new ImageIcon("apple.png");
        apple = iia.getImage();

        ImageIcon iih = new ImageIcon("head.png");
        head = iih.getImage();
    }

    private void initGame() {

        dots = 3;

        for (int z = 0; z < dots; z++) {
            x[z] = 50 - z * 10;
            y[z] = 50;
        }

        locateApple();

        timer = new Timer(DELAY, this);
        timer.start();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        doDrawing(g);
    }
    
    private void doDrawing(Graphics g) {
        
        if (inGame) {

            g.drawImage(apple, apple_x, apple_y, this);

            for (int z = 0; z < dots; z++) {
                if (z == 0) {
                    g.drawImage(head, x[z], y[z], this);
                } else {
                    g.drawImage(ball, x[z], y[z], this);
                }
            }

            Toolkit.getDefaultToolkit().sync();

        } else {

            gameOver(g);
        }        
    }

    private void gameOver(Graphics g) {
        
        String msg = "Game Over";
        Font small = new Font("Helvetica", Font.BOLD, 14);
        FontMetrics metr = getFontMetrics(small);

        g.setColor(Color.white);
        g.setFont(small);
        g.drawString(msg, (B_WIDTH - metr.stringWidth(msg)) / 2, B_HEIGHT / 2);
    }

    private void checkApple() {

        if ((x[0] == apple_x) && (y[0] == apple_y)) {

            dots++;
            locateApple();
        }
    }

    private void move() {

        for (int z = dots; z > 0; z--) {
            x[z] = x[(z - 1)];
            y[z] = y[(z - 1)];
        }

        if (leftDirection) {
            x[0] -= DOT_SIZE;
        }

        if (rightDirection) {
            x[0] += DOT_SIZE;
        }

        if (upDirection) {
            y[0] -= DOT_SIZE;
        }

        if (downDirection) {
            y[0] += DOT_SIZE;
        }
    }

    private void checkCollision() {

        for (int z = dots; z > 0; z--) {

            if ((z > 4) && (x[0] == x[z]) && (y[0] == y[z])) {
                inGame = false;
            }
        }

        if (y[0] >= B_HEIGHT) {
            inGame = false;
        }

        if (y[0] < 0) {
            inGame = false;
        }

        if (x[0] >= B_WIDTH) {
            inGame = false;
        }

        if (x[0] < 0) {
            inGame = false;
        }
        
        if(!inGame) {
            timer.stop();
        }
    }

    private void locateApple() {

        int r = (int) (Math.random() * RAND_POS);
        apple_x = ((r * DOT_SIZE));

        r = (int) (Math.random() * RAND_POS);
        apple_y = ((r * DOT_SIZE));
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        if (inGame) {

            checkApple();
            checkCollision();
            move();
        }

        repaint();
    }

    private class TAdapter extends KeyAdapter {

        @Override
        public void keyPressed(KeyEvent e) {

            int key = e.getKeyCode();

            if ((key == KeyEvent.VK_LEFT) && (!rightDirection)) {
                leftDirection = true;
                upDirection = false;
                downDirection = false;
            }

            if ((key == KeyEvent.VK_RIGHT) && (!leftDirection)) {
                rightDirection = true;
                upDirection = false;
                downDirection = false;
            }

            if ((key == KeyEvent.VK_UP) && (!downDirection)) {
                upDirection = true;
                rightDirection = false;
                leftDirection = false;
            }

            if ((key == KeyEvent.VK_DOWN) && (!upDirection)) {
                downDirection = true;
                rightDirection = false;
                leftDirection = false;
            }
        }
    }
}
First we will define the constants used in our game.
private final int B_WIDTH = 300;
private final int B_HEIGHT = 300;
private final int DOT_SIZE = 10;
private final int ALL_DOTS = 900;
private final int RAND_POS = 29;
private final int DELAY = 140;
The B_WIDTH and B_HEIGHT constants determine the size of the board. The DOT_SIZE is the size of the apple and the dot of the snake. The ALL_DOTS constant defines the maximum number of possible dots on the board (900 = (300*300)/(10*10)). The RAND_POS constant is used to calculate a random position for an apple. The DELAY constant determines the speed of the game.
private final int x[] = new int[ALL_DOTS];
private final int y[] = new int[ALL_DOTS];
These two arrays store the x and y coordinates of all joints of a snake.
private void loadImages() {

    ImageIcon iid = new ImageIcon("dot.png");
    ball = iid.getImage();

    ImageIcon iia = new ImageIcon("apple.png");
    apple = iia.getImage();

    ImageIcon iih = new ImageIcon("head.png");
    head = iih.getImage();
}
In the loadImages() method we get the images for the game. The ImageIcon class is used for displaying PNG images.
private void initGame() {

    dots = 3;

    for (int z = 0; z < dots; z++) {
        x[z] = 50 - z * 10;
        y[z] = 50;
    }

    locateApple();

    timer = new Timer(DELAY, this);
    timer.start();
}
In the initGame() method we create the snake, randomly locate an apple on the board, and start the timer.
private void checkApple() {

    if ((x[0] == apple_x) && (y[0] == apple_y)) {

        dots++;
        locateApple();
    }
}
If the apple collides with the head, we increase the number of joints of the snake. We call the locateApple() method which randomly positions a new apple object.

In the move() method we have the key algorithm of the game. To understand it, look at how the snake is moving. We control the head of the snake. We can change its direction with the cursor keys. The rest of the joints move one position up the chain. The second joint moves where the first was, the third joint where the second was etc.
for (int z = dots; z > 0; z--) {
    x[z] = x[(z - 1)];
    y[z] = y[(z - 1)];
}
This code moves the joints up the chain.
if (leftDirection) {
    x[0] -= DOT_SIZE;
}
This line moves the head to the left.
In the checkCollision() method, we determine if the snake has hit itself or one of the walls.
for (int z = dots; z > 0; z--) {

    if ((z > 4) && (x[0] == x[z]) && (y[0] == y[z])) {
        inGame = false;
    }
}
If the snake hits one of its joints with its head the game is over.
if (y[0] >= B_HEIGHT) {
    inGame = false;
}
The game is finished if the snake hits the bottom of the board.


Snake.java

package com.blogspot.geekonjava;

import java.awt.EventQueue;
import javax.swing.JFrame;


public class Snake extends JFrame {

    public Snake() {

        add(new Board());
        
        setResizable(false);
        pack();
        
        setTitle("Snake");
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    

    public static void main(String[] args) {
        
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {                
                JFrame ex = new Snake();
                ex.setVisible(true);                
            }
        });
    }
}
This is the main class.
setResizable(false);
pack();
The setResizable() method affects the insets of the JFrame container on some platforms. Therefore, it is important to call it before the pack() method. Otherwise, the collision of the snake's head with the right and bottom borders might not work correctly.
Read More

Wednesday, 29 July 2015

Create Round JButton in Swing

Leave a Comment
Any Shape using the image that set the transparent color to its shape JButton to create.

how to Create Round JButton in Swing, Create Round JButton in Swing, Round JButton in Swing, JButton in Swing, create round image JButton,round image JButton,image JButton

Runnable Jar File
Source Code
Repository

Sample Code

class RoundButton extends JButton {
  public RoundButton () {
    this (null, null);
  }
  public RoundButton (Icon icon) {
    this (null, icon);
  }
  public RoundButton (String text) {
    this (text, null);
  }
  public RoundButton (Action a) {
    this ();
    setAction (a);
  }
  public RoundButton (String text, Icon icon) {
    setModel (new DefaultButtonModel ());
    init (text, icon);
    if (icon == null) {
      return;
    }
    setBorder (BorderFactory.createEmptyBorder (1, 1, 1, 1));
    setBackground (Color.BLACK);
    setContentAreaFilled (false);
    setFocusPainted (false);
    //setVerticalAlignment(SwingConstants.TOP);
    setAlignmentY (Component.TOP_ALIGNMENT);
    initShape ();
  }
  protected Shape shape, base;
  protected void initShape () {
    if (! getBounds (). equals (base)) {
      Dimension s = getPreferredSize ();
      base = getBounds ();
      shape = new Ellipse2D.Float (0, 0, s.width - 1, s.height - 1);
    }
  }
  Override Public Dimension getPreferredSize () {
    Icon icon = getIcon ();
    Insets i = getInsets ();
    int iw = Math.max (icon.getIconWidth (), icon.getIconHeight ());
    return new Dimension (iw + i.right + i.left, iw + i.top + i.bottom);
  }
  Override Protected void paintBorder (Graphics g) {
    initShape ();
    Graphics2D g2 = (Graphics2D) g.create ();
    g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setColor (getBackground ());
    //g2.setStroke(new BasicStroke (1f));
    g2.draw (shape);
    g2.dispose ();
  }
  Override Public boolean contains (int x, int y) {
    initShape ();
    return shape.contains (x, y);
    // Following, example of a case in which the transparent color is to click No 0
    // Or return super.contains (x, y) && ((image.getRGB (x, y) >> 24) & 0xff)> 0;
  }
}
Did you try this ever ? Auto Complete Text Field in Swing
In the above sample, JButton creates a button by pasting a circular image.

  • Circular, the same size of PNG is an image (outside of the circle is transparent color) providing three types JButton set to


  1. setIcon
  2. setPressedIcon
  3. setRolloverIcon
  4. setContentAreaFilled (false) Set the like, it does not draw the button itself


  • Recommended, to match the minimum, maximum size to the size of the image


  1. However, to draw a line edge, from vertical and horizontal image size 1px larger as EmptyBorder has set


  • It contains Override, if you click on the outside of the circle button so as not to react


  1. In this sample, and not necessarily that is generating the circle from the transmission color of the image, and prepares separate circular shapes the size of the image
  2. From the image of the transparent color, to set a clickable area, change the shape definition of the JComponent see


  • paintBorder Override, original edge to draw your own circle with a line of its width without drawing


  1. It contains and utilizes a figure used in the
Do you know ? Bad features of Java

In order to change the alignment of the button, JPanel instead, Box Since you are using a, JDK 5 even JDK 6 to draw in the same way as, Box # paintComponent we override as follows.
private final Box box = // JDK 6 Box.createHorizontalBox ();
  // JDK 5
  new Box (BoxLayout.X_AXIS) {
    Override Protected void paintComponent (Graphics g) {
      if (ui! = null) {
        super.paintComponent (g);
      } Else if (isOpaque ()) {
        g.setColor (getBackground ());
        g.fillRect (0, 0, getWidth (), getHeight ());
      }
    }
  };
Happy Coding

Read More

Sunday, 26 July 2015

Auto Complete Text Field in Swing

Leave a Comment
Have a lot of items in combo box makes user irritated when running the program, especially when fast input is needed, manual search by scrolling down the scroll bar is so time consuming but can be avoided if we can get what item we want to choose by just write first or second letter of it.

In another case you maybe want to make a text field with some suggestion input like search engine text field. To make something like that, we need JTextField and JComboBox together as one.
How to Make Auto Complete Text Field in Swing, Make Auto Complete Text Field in Swing, Auto Complete Text Field in Swing, Complete Text Field in Swing, Text Field in Swing,

Custom JComboBox :

import java.awt.event.ItemEvent;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.plaf.basic.BasicComboBoxEditor;
 
public class AutoComboBox extends JComboBox {
private class AutoTextFieldEditor extends BasicComboBoxEditor {
 
private AutoTextField getAutoTextFieldEditor() {
return (AutoTextField) editor;
}
 
AutoTextFieldEditor(java.util.List list) {
editor = new AutoTextField(list, AutoComboBox.this);
}
}
 
public AutoComboBox(java.util.List list) {
isFired = false;
autoTextFieldEditor = new AutoTextFieldEditor(list);
setEditable(true);
setModel(new DefaultComboBoxModel(list.toArray()) {
 
protected void fireContentsChanged(Object obj, int i, int j) {
if (!isFired)
super.fireContentsChanged(obj, i, j);
}
 
});
setEditor(autoTextFieldEditor);
}
 
public boolean isCaseSensitive() {
return autoTextFieldEditor.getAutoTextFieldEditor().isCaseSensitive();
}
 
public void setCaseSensitive(boolean flag) {
autoTextFieldEditor.getAutoTextFieldEditor().setCaseSensitive(flag);
}
 
public boolean isStrict() {
return autoTextFieldEditor.getAutoTextFieldEditor().isStrict();
}
 
public void setStrict(boolean flag) {
autoTextFieldEditor.getAutoTextFieldEditor().setStrict(flag);
}
 
public java.util.List getDataList() {
return autoTextFieldEditor.getAutoTextFieldEditor().getDataList();
}
 
public void setDataList(java.util.List list) {
autoTextFieldEditor.getAutoTextFieldEditor().setDataList(list);
setModel(new DefaultComboBoxModel(list.toArray()));
}
 
void setSelectedValue(Object obj) {
if (isFired) {
return;
} else {
isFired = true;
setSelectedItem(obj);
fireItemStateChanged(new ItemEvent(this, 701, selectedItemReminder,1));
isFired = false;
return;
}
}
 
@Override
protected void fireActionEvent() {
if (!isFired)
super.fireActionEvent();
}
 
private AutoTextFieldEditor autoTextFieldEditor;
 
private boolean isFired;
 
}

Custom JTextField :

import java.util.List;
import javax.swing.JTextField;
import javax.swing.text.*;
 
public class AutoTextField extends JTextField {
 class AutoDocument extends PlainDocument {
 
public void replace(int i, int j, String s, AttributeSet attributeset)
 throws BadLocationException {
 super.remove(i, j);
 insertString(i, s, attributeset);
 }
 
public void insertString(int i, String s, AttributeSet attributeset)
 throws BadLocationException {
 if (s == null || "".equals(s))
 return;
 String s1 = getText(0, i);
 String s2 = getMatch(s1 + s);
 int j = (i + s.length()) - 1;
 if (isStrict && s2 == null) {
 s2 = getMatch(s1);
 j--;
 } else if (!isStrict && s2 == null) {
 super.insertString(i, s, attributeset);
 return;
 }
 if (autoComboBox != null && s2 != null)
 autoComboBox.setSelectedValue(s2);
 super.remove(0, getLength());
 super.insertString(0, s2, attributeset);
 setSelectionStart(j + 1);
 setSelectionEnd(getLength());
 }
 
public void remove(int i, int j) throws BadLocationException {
 int k = getSelectionStart();
 if (k > 0)
 k--;
 String s = getMatch(getText(0, k));
 if (!isStrict && s == null) {
 super.remove(i, j);
 } else {
 super.remove(0, getLength());
 super.insertString(0, s, null);
 }
 if (autoComboBox != null && s != null)
 autoComboBox.setSelectedValue(s);
 try {
 setSelectionStart(k);
 setSelectionEnd(getLength());
 } catch (Exception exception) {
 }
 }
 
}
 
public AutoTextField(List list) {
 isCaseSensitive = false;
 isStrict = true;
 autoComboBox = null;
 if (list == null) {
 throw new IllegalArgumentException("values can not be null");
 } else {
 dataList = list;
 init();
 return;
 }
 }
 
AutoTextField(List list, AutoComboBox b) {
 isCaseSensitive = false;
 isStrict = true;
 autoComboBox = null;
 if (list == null) {
 throw new IllegalArgumentException("values can not be null");
 } else {
 dataList = list;
 autoComboBox = b;
 init();
 return;
 }
 }
 
private void init() {
 setDocument(new AutoDocument());
 if (isStrict && dataList.size() > 0)
 setText(dataList.get(0).toString());
 }
 
private String getMatch(String s) {
 for (int i = 0; i < dataList.size(); i++) {
 String s1 = dataList.get(i).toString();
 if (s1 != null) {
 if (!isCaseSensitive
 && s1.toLowerCase().startsWith(s.toLowerCase()))
 return s1;
 if (isCaseSensitive && s1.startsWith(s))
 return s1;
 }
 }
 
return null;
 }
 
public void replaceSelection(String s) {
 AutoDocument _lb = (AutoDocument) getDocument();
 if (_lb != null)
 try {
 int i = Math.min(getCaret().getDot(), getCaret().getMark());
 int j = Math.max(getCaret().getDot(), getCaret().getMark());
 _lb.replace(i, j - i, s, null);
 } catch (Exception exception) {
 }
 }
 
public boolean isCaseSensitive() {
 return isCaseSensitive;
 }
 
public void setCaseSensitive(boolean flag) {
 isCaseSensitive = flag;
 }
 
public boolean isStrict() {
 return isStrict;
 }
 
public void setStrict(boolean flag) {
 isStrict = flag;
 }
 
public List getDataList() {
 return dataList;
 }
 
public void setDataList(List list) {
 if (list == null) {
 throw new IllegalArgumentException("values can not be null");
 } else {
 dataList = list;
 return;
 }
 }
 
private List dataList;
 
private boolean isCaseSensitive;
 
private boolean isStrict;
 
private AutoComboBox autoComboBox;
}

Now here is how to use em :

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.text.*;
 
public class AutoComplete extends JComboBox implements JComboBox.KeySelectionManager
{
 private String searchFor;
 private long lap;
 public class CBDocument extends PlainDocument
 {
 @Override
 public void insertString(int offset, String str, AttributeSet a) throws BadLocationException
 {
 if (str==null) return;
 super.insertString(offset, str, a);
 if(!isPopupVisible() && str.length() != 0) fireActionEvent();
 }
 }
 public AutoComplete(Object[] items)
 {
 super(items);
 lap = new java.util.Date().getTime();
 setKeySelectionManager(this);
 JTextField tf;
 if(getEditor() != null)
 {
 tf = (JTextField)getEditor().getEditorComponent();
 if(tf != null)
 {
 tf.setDocument(new CBDocument());
 addActionListener(new ActionListener()
 {
 public void actionPerformed(ActionEvent evt)
 {
 JTextField tf = (JTextField)getEditor().getEditorComponent();
 String text = tf.getText();
 ComboBoxModel aModel = getModel();
 String current;
 for(int i = 0; i < aModel.getSize(); i++)
 {
 current = aModel.getElementAt(i).toString();
 if(current.toLowerCase().startsWith(text.toLowerCase()))
 {
 tf.setText(current);
 tf.setSelectionStart(text.length());
 tf.setSelectionEnd(current.length());
 break;
 }
 }
 }
 });
 }
 }
 }
 public int selectionForKey(char aKey, ComboBoxModel aModel)
 {
 long now = new java.util.Date().getTime();
 if (searchFor!=null && aKey==KeyEvent.VK_BACK_SPACE && searchFor.length()>0)
 {
 searchFor = searchFor.substring(0, searchFor.length() -1);
 }
 else
 {
 if(lap + 1000 < now)
 searchFor = "" + aKey;
 else
 searchFor = searchFor + aKey;
 }
 lap = now;
 String current;
 for(int i = 0; i < aModel.getSize(); i++)
 {
 current = aModel.getElementAt(i).toString().toLowerCase();
 if (current.toLowerCase().startsWith(searchFor.toLowerCase())) return i;
 }
 return -1;
 }
 
 @Override
 public void fireActionEvent()
 {
 super.fireActionEvent();
 }
 
public static void main(String arg[])
 {
 JFrame f = new JFrame("AutoCompletion");
 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 f.setSize(300,100);
 Container cp= f.getContentPane();
 cp.setLayout(new GridLayout(2, 1));
 
 Locale[] locales = Locale.getAvailableLocales();
 //JComboBox 1 allowing any input
 JComboBox cBox= new AutoComplete(locales);
 
 java.util.List<String> items = new ArrayList<String>(){};
 for (int i = 0; i < locales.length; i++) {
 items.add(locales[i].toString());
 }
 
//JComboBox 2 with strict input
 JComboBox cBox2 = new AutoComboBox(items);
 cBox.setBounds(50,50,100,21);
 cBox.setEditable(true);
 cp.add(cBox);
 cp.add(cBox2);
 f.setVisible(true);
 f.setResizable(false);
 f.setLocationRelativeTo(null);
 }
}
Combo box 1 will become text field like you can found in search engine, when you write something inside of the text field, it will give you suggestion based on item of combo box which have common letter sequence. Combo box 2 also like search engine text field but strictly only allowing write something that exist in combo box item.
Read More

Use String length to compare empty string variables

Leave a Comment
Hello friends sometimes we need to compare String with particular purpose and mostly with empty. And many of use equals() method but you should use length() method. And how you'll do just look below code with explanation.

  • Severity:  High 
  • Rule:  The String.equals() method is overkill to test for an empty string. It is quicker to test if the length of the string is 0. 
  • Reason:  The String.equals() method is overkill to test for an empty string. It is quicker to test if the length of the string is 0.
How to Use String length to compare empty string variables, Use String length to compare empty string variables,String length to compare empty string variables,length to compare empty string variables,compare empty string variables,compare empty string variables in java,string variables in java,


Usage Example: 

package com.rule.one;
class Use_String_length_to_compare_empty_string_violation
{
 public boolean isEmpty(String str)
 {
  return str.equals("");  // VIOLATION
 }
}

Should be written as:

package com.rule.one;
class Use_String_length_to_compare_empty_string_correction
{
 public boolean isEmpty(String str)
 {
  return str.length()==0;  // CORRECTION
 }
}
Read More

Wednesday, 22 July 2015

Multiple File Upload Using Struts 2

Leave a Comment
Based on the tutorial Upload files with Struts 2, this article extends the sample program to be able to upload multiple files at once.

Table of Content

  1. About the upload multiple files example
  2. Write code for upload form
  3. Write code for action class
  4. Write code for result page
  5. Configure struts.xml
  6. Configure web.xml
  7. Download example application

To achieve this, there are some changes required on both client side and server side:
Multiple File Upload Using Struts 2,File Upload Using Struts 2,Upload Using Struts 2,Upload multiple files with Struts 2,multiple files with Struts 2,files with Struts 2,Upload files with Struts 2files with Struts 2

  • Client side: use multiple <s:file> tags that allow user to pick up as many files as needed.
  • Server side: in the action class, modify type of the member variables from single object to an array or a list as follows:
  1.    File X to String[] X or List<File> X
  2.    String XFileName to String[] XFileName or List<String> XFileName
  3.    String XContentType to String[] XContentType or List<String> XContentType

Where X is the name of the <s:file> tags in upload form, for example:
<s:file name="fileUpload" />
then X will be “fileUpload”. Hence in the action class:
File[] fileUpload;
String[] fileUploadFileName;
String[] fileUploadContentType;
or:
List<File> fileUpload;
List<String> fileUploadFileName;
List<String> fileUploadContentType;
And remember to create getters and setters for those variables properly.

1. About the upload multiple files example

The following example program demonstrates how to implement functionality to upload multiple files with Struts 2 framework. The application shows an upload form which allows user to pick up three files to upload at once.
The uploaded files are copied into a location which is configured in application’s struts.xml file.

Let’s see how the example application is coded.

2. Write code for upload form

The upload form is implemented in the upload.jsp page as follows:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags" %>   
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Multiple Files Upload with Struts2</title>
</head>
<body>
    <center>
        <h2>Pick multiple files to upload</h2>
        <s:form action="uploadFile" enctype="multipart/form-data" method="post">
            <s:file name="fileUpload" label="Pick file #1" size="30"/>
            <s:file name="fileUpload" label="Pick file #2" size="30"/>
            <s:file name="fileUpload" label="Pick file #3" size="30"/>
            <br/>
            <s:submit value="Upload All" />
        </s:form>
    </center>
</body>
</html>
When running, the page looks like this:

On submitting of this form, the action uploadFile is invoked.

3. Write code for action class

Implement Struts 2’s action class in MultipleFilesUploadAction.java file as follows:
package com.geekonjava.struts;
 
import java.io.File;
import java.io.IOException;
 
import org.apache.commons.io.FileUtils;
 
public class MultipleFilesUploadAction {
    private File[] fileUpload;
    private String[] fileUploadFileName;
    private String[] fileUploadContentType;
     
    /**
     * This is the path to save uploaded file, which is configured in struts.xml
     */
    private String saveDirectory;
 
    public String doUpload() {
 
        // copy the uploaded files into pre-configured location
        for (int i = 0; i < fileUpload.length; i++) {
            File uploadedFile = fileUpload[i];
            String fileName = fileUploadFileName[i];
            File destFile = new File(saveDirectory + File.separator + fileName);
            try {
                FileUtils.copyFile(uploadedFile, destFile);
            } catch (IOException ex) {
                System.out.println("Could not copy file " + fileName);
                ex.printStackTrace();
            }
        }
         
        return "success";
    }
     
    public File[] getFileUpload() {
        return fileUpload;
    }
 
    public void setFileUpload(File[] fileUploads) {
        this.fileUpload = fileUploads;
    }
 
    public String[] getFileUploadFileName() {
        return fileUploadFileName;
    }
 
    public void setFileUploadFileName(String[] fileUploadFileNames) {
        this.fileUploadFileName = fileUploadFileNames;
    }
 
    public String[] getFileUploadContentType() {
        return fileUploadContentType;
    }
 
    public void setFileUploadContentType(String[] fileUploadContentTypes) {
        this.fileUploadContentType = fileUploadContentTypes;
    }
 
    public String getSaveDirectory() {
        return saveDirectory;
    }
 
    public void setSaveDirectory(String saveDir) {
        this.saveDirectory = saveDir;
    }
}
In this POJO action class, we use three arrays to store uploaded files:
private File[] fileUpload;
private String[] fileUploadFileName;
private String[] fileUploadContentType;

  • Note that the word “fileUpload” matches with value of name attribute of <s:file> tag in the upload.jsp file. Struts 2’s interceptor called fileUpload will fetch data for these variables through setters.
  • Value of the variable saveDirectory is set through corresponding setter by Struts 2’s staticParams interceptor, and this value can be configured in struts.xml file.
  • The action class’ entry method doUpload() copies the uploaded files from temporary directory to the location specified by the saveDirectory variable, then redirect to a “success” view which is the result page.

4. Write code for result page

The result page result.jsp - is pretty simple, which shows a successful message:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Upload result</title>
</head>
<body>
    <center>
        <h2>The files were uploaded successfully</h2>
    </center>
</body>
</html>

5. Configure struts.xml

We connect the upload form page, the action class and the result page through application’s struts.xml file as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
 
<struts>
    <constant name="struts.multipart.maxSize" value="20971520" /> <!-- 20MB -->
     
    <package name="fileUpload" extends="struts-default">
         
        <action name="uploadFile" class="com.geekonjava.struts.MultipleFilesUploadAction"
            method="doUpload">
             
            <param name="saveDirectory">E:/Test/Upload</param>
             
            <interceptor-ref name="fileUpload">
                <param name="allowedTypes">*/*</param>
                <param name="maximumSize">4194304</param> <!-- 4MB -->
            </interceptor-ref>
             
            <interceptor-ref name="staticParams"/>
            <interceptor-ref name="params" />
            <interceptor-ref name="validation" />
            <interceptor-ref name="workflow" />
                                         
            <result name="success" type="redirect">/result.jsp</result>
            <result name="input">/upload.jsp</result>
        </action>
    </package>
 
</struts>

  •  Here, the interceptor fileUpload is configured to allow all file types can be uploaded, and maximum size for an individual file is 4MB.
  • The constant struts.multipart.maxSize restricts maximum size allowed for a multipart request is 20MB. That means the total size of upload files cannot exceed 20MB.
  • The parameter saveDirectory specifies where to copy uploaded files. The interceptor staticParams must be specified to fetch value of the parameter saveDirectory for the action class.   

6. Configure web.xml

To enable Struts 2 framework for the application, the web deployment descriptor file (web.xml) is configured as follows:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>Struts2 Multiple Files Upload</display-name>
 
    <welcome-file-list>
        <welcome-file>upload.jsp</welcome-file>
    </welcome-file-list>
 
    <filter>
        <filter-name>DispatcherFilter</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
 
    <filter-mapping>
        <filter-name>DispatcherFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
 
</web-app>
With this configuration, Struts 2’s dispatcher filter will intercept all requests, and the default page is the upload.jsp page.

7. Download example application

You can download the example application as an Eclipse project in the attachment section. It is tested and working well with Struts version 2.3.4.1.
Read More