0

So I took it upon myself to learn Java. A decision I regret more with every crash of Elipse. Fortunately I have actually managed to get this block of my self inflicted project to actually 'work' but obviously being self taught I am quite sure I have made a lot of errors in my layout and

In total, the program will create a JFrame then stick a JscrollPane inside that into which it inserts a a JPanel (wrapPage). It then loops through a process that generates an array of TMTile Objects which are extended JPanels containing the tile images which are drawn from a source folder of jpg images. Once that has finished it places that array as a grid using the GridBagLayout within the wrapPage Jpanel resulting in a nice little perfect maze.

That all works perfectly, but the big let down is that the size of the image used to create the tiles is dictating everything. I can't for the life of me figure out how to scale the image and efforts to find a suitable process have only got me methods of creating new image files or alternating between stretching and tiling images to fit a within their containing component or suggestions I just couldn't follow to save my life.

Fortunately. The image handling is part of the TMTile class file! This means I can show you the entire relevant bit of script;

The following are imported for use in this file

from java.awt: Color, GridBagConstraints, GridBagLayout, Insets
from javax.swing: ImageIcon, JLabel, JPanel

public class TMTile extends JPanel
{
private static final long serialVersionUID = 1L;

private int paths; // values 0 to 15, uses bitwise & | to set or check open paths

private JLabel tileWrap; // to contain the ImageIcon
private ImageIcon tileImg; // the image to be used

GridBagConstraints bag;

public TMTile( int inDir ) // called by maze constructor
{
    paths = inDir;
    this.setBackground( Color.RED ); // so I can tell if the image didn't load right
    this.setLayout( new GridBagLayout() ); // GridBagLayout is probably overkill but it what I am most familiar with now.

    bag = new GridBagConstraints();
    bag.insets = new Insets( 0, 0, 0, 0 );

    tileImg = tileImage( paths );

    tileWrap = new JLabel( "", tileImg, JLabel.CENTER );

    this.add( tileWrap, bag );
}


public void open( int inDir ) // called by maze constructor when tile value changes resulting from the perfect maze backtrack method
{
    paths = paths | inDir;

    tileImg = tileImage( paths );

    tileWrap.setIcon( tileImg );
}


private ImageIcon tileImage( int paths ) // created to cut down on duplicate code and make updating easier
{
    String inEnd;

    if(paths < 10)
    {
        inEnd = "0"+ paths;
    }
    else
    {
        inEnd = ""+ paths;
    }

    ImageIcon tileImg = new ImageIcon( "imgs/MAZE_"+ inEnd +".jpg" );

    System.out.println( "imgs/MAZE_"+ inEnd +".jpg" );

    Image newimg = tileImg.getImage().getScaledInstance( 40, 40, java.awt.Image.SCALE_DEFAULT );

    tileImg = new ImageIcon( newimg );

    return tileImg;
}


public int getOpen()
{
    return paths;
}
}

Thanks to nachokk and MadProgrammer I now once again have a working maze program and the maze tiles are scalable. That just leaves the final goal of doing away with individual tile .jpgs and switching to a single image file with all 16 stored within in.

What I would love to have is the ability to utilize a single large image file which is divided into 16 sections, 1 section for each tile value. I started out working toward this goal but had to abandon it fairly quickly as I couldn’t figure out how to only display the section of the image needed which would also need to be scaled in the way described above.

Since I am very much still learning Java advice on any alternatives is welcome but ideally I would love to know how to accomplish this as planned.

  • http://stackoverflow.com/questions/14548808/scale-the-imageicon-automatically-to-label-size this may help you! – nachokk Sep 01 '13 at 19:08
  • also see my question may help you http://stackoverflow.com/questions/18468169/is-there-any-way-to-fit-an-image-in-a-tab-component `ImageIcon icon = new ImageIcon("images/itemtexto-off.png"); Image img = icon.getImage() ; Image newimg = img.getScaledInstance( 50, 25, java.awt.Image.SCALE_DEFAULT ) ;` – nachokk Sep 01 '13 at 19:11
  • You might like to take a look at [this example](http://stackoverflow.com/questions/11959758/java-maintaining-aspect-ratio-of-jpanel-background-image/11959928#11959928) – MadProgrammer Sep 01 '13 at 20:13
  • @nachokk You might like to have a read of [The perils of Image#getScaledInstance](http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html) – MadProgrammer Sep 01 '13 at 20:15
  • @MadProgrammer nice article thanks! glad to learn with people like you! – nachokk Sep 01 '13 at 20:36
  • Actually, one step closer!!! and then two steps back. I actually did find some of the information posted in nachokk's links useful and my tiles do now scale! Unfortunately I somehow broke the update method so the tiles are now stuck with whatever original image they are set with. I could work around that by altering the maze builder but I think I can handle this. At the very least it is a new problem to work on rather than the same brick wall I was beating my head against. – Lost Cause Sep 01 '13 at 20:44
  • Using layout managers and individual panels like this seems a bit complicated for a maze or game. If you did the [drawing yourself](http://docs.oracle.com/javase/tutorial/2d/basic2d/) you could do a lot of what you require pretty easily by overriding the paintComponent method of some subclass of JComponent or JPanel, and calling one of the [Graphics.drawImage](http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html#drawImage%28java.awt.Image,%20int,%20int,%20int,%20int,%20int,%20int,%20int,%20int,%20java.awt.image.ImageObserver%29) methods. – sgbj Sep 01 '13 at 22:57
  • @sbat I have no doubt that I am missing many ways this could be made better. This seemed like the best way to accomplish my ends at the time since I also planned for scripting 3 pathfinders to wander and solve the mazes in their own ways plus it gave me the ability to update and change individual tiles on the fly. – Lost Cause Sep 01 '13 at 23:04
  • @LostCause If realtime scaling is important, I'd use custom painting of a `JPanel` instead of a `JLabel`. That way you could maintain a reference to the original image and scale it as required. – MadProgrammer Sep 01 '13 at 23:35

0 Answers0