Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

9-patch like image scaling for Java?

Tags:

java

swing

I'm not sure if this is the right place to ask, but I'm wondering if there is something like 9 patch images on android, but for Java, like Oracle, PC java. All my google searches only show me android because people call that Java, but it's not really the same.

I've found LibGdx but it's quite hefty for the single nine-patch ability that I'm looking for.

A nine patch image is one that has '9' areas, with the corners being 'not scaled' typically while the side walls and the center area stretched to fit the screen. An example from Android: http://developer.android.com/tools/help/draw9patch.html

Does anyone know anything that can scale like this? I need something that can support PNG.

like image 472
Mgamerz Avatar asked Nov 23 '13 06:11

Mgamerz


People also ask

How do I create a 9 patch image?

In Android Studio, right-click the PNG image you'd like to create a NinePatch image from, then click Create 9-patch file. Type a file name for your NinePatch image, and click OK. Your image will be created with the . 9.

What is the difference between a regular .PNG and a nine patch image?

The nine patch images have extension as. 9. png. It allows extension in 9 ways, i.e. 4 corners that are unscaled, 4 edges that are scaled in 1 axis, and the middle one that can be scaled into both axes.

How do I create a 9 patch image in Photoshop?

Creating 9 patch background image using Photoshop:Draw the images in a regular way as you use to do in Photoshop. Make the 1px spacing around the image from all sides. And also make sure that the image doesn't have anything in this 1px area & has 100% transparency. Otherwise 9patch image will not work.

What is a 9 patch?

`A 9-patch image is a standard PNG image that includes an extra 1-pixel-wide border and must be saved with the extension . 9. png. When creating 9-patch images, designers can indicate which areas can and cannot be stretched.


1 Answers

If you are searching a way to use a 9-patch image on a Java component I asked the same question here: How use a 9-patch image as background on a JPanel? and the short answer is no, you can not.

The long one is: You can if you split the image in the 9 images (borders, corners and center) and create a component that when is repainted moves and resizes the images.

The example that follows is adapted for my case where:

  • The component is a JPanel.
  • The center of the panel has to be transparent, so I need one image less.
  • The component is not going to be smaller than the given images.
  • Images have transparences, this explains the setOpaque(false) calls in the code.
  • The code is a rough draft.

Here the code:

public class NinePatchLikePanel extends JPanel{
private JPanel corner_top_l;
private JPanel corner_top_r;
private JPanel corner_bot_l;
private JPanel corner_bot_r;

private JPanel border_ver_l;
private JPanel border_ver_r;
private JPanel border_hoz_t;
private JPanel border_hoz_b;

private int min_width, min_height;

private int corners_width;
private int corners_height;
private int borders_width;
private int borders_height;


public NinePatchLikePanel (String[] urls) {

    if(urls.length != 8) {
        throw new UnsupportedOperationException("Exception to be managed!");
    } else {
        corner_top_l = new JPanelWithBackground (urls [0]);
        corner_top_r = new JPanelWithBackground (urls [1]);
        corner_bot_r = new JPanelWithBackground (urls [2]);
        corner_bot_l = new JPanelWithBackground (urls [3]);

        border_hoz_t = new JPanelWithBackground (urls [4]);
        border_ver_r = new JPanelWithBackground (urls [5]);
        border_hoz_b = new JPanelWithBackground (urls [6]);
        border_ver_l = new JPanelWithBackground (urls [7]);

        corners_width   = corner_top_l.getWidth();
        corners_height  = corner_top_l.getHeight();

        borders_width   = border_hoz_t.getWidth();  
        borders_height  = border_ver_l.getHeight();

        min_width   = 2 * corners_width  + borders_width;
        min_height  = 2 * corners_height + borders_height;

        this.setSize (min_width, min_height );
        this.setMinimumSize ( new Dimension (min_width, min_height) );
        this.setOpaque(false);
        this.setLayout(null);
        this.add(corner_top_l);
        this.add(corner_top_r);
        this.add(corner_bot_l);
        this.add(corner_bot_r);

        this.add(border_hoz_t);
        this.add(border_ver_r);
        this.add(border_hoz_b);
        this.add(border_ver_l);
    }
}

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

    int actual_width = this.getWidth();
    int actual_height = this.getHeight();

    int _x = actual_width - corners_width;
    int _y = actual_height - corners_height;

    corner_top_l.setLocation(0, 0);
    corner_top_r.setLocation(_x, 0);
    corner_bot_l.setLocation(0, _y);
    corner_bot_r.setLocation(_x, _y);

    int new_borders_width  = _x - corners_width;
    int new_borders_height = _y - corners_height;


    border_hoz_t.setLocation(corners_width, 0);
    border_hoz_t.setSize(new_borders_width, border_hoz_t.getHeight());

    border_ver_r.setLocation(_x, corners_height);
    border_ver_r.setSize(border_ver_r.getWidth(), new_borders_height);

    border_hoz_b.setLocation(corners_width, _y);
    border_hoz_b.setSize(new_borders_width, border_hoz_b.getHeight());

    border_ver_l.setLocation(0, corners_height);
    border_ver_l.setSize(border_ver_l.getWidth(), new_borders_height);
}

}

Here the code for the JPanelWithBackground class:

public class JPanelWithBackground extends JPanel { 
Image bg = null; 

public JPanelWithBackground(String url) { 
    try{
        bg = ImageIO.read(getClass().getResourceAsStream(url));
        int height = bg.getHeight(null);
        int width  = bg.getWidth(null);
        Dimension d = new Dimension(width,height);
        this.setSize (width, height);
        this.setMinimumSize ( d );
        this.setOpaque(false); 
    } catch (IOException ex) {
        //TODO: Manage this exception in a better way
            System.err.println(ex);
            System.exit(1);
    }  
} 

@Override
public void paintComponent(Graphics g) { 
    super.paintComponent(g);
    if (bg != null)
        g.drawImage(bg, 0, 0, this.getWidth(), this.getHeight(), null);
}
} 
like image 131
2 revs Avatar answered Oct 21 '22 12:10

2 revs