I am making a slider puzzle applet. And i have this problem when i display it as an applet my buttons do not seem to act the same was as they did before i made it into an applet by using a JApplet rather than a JFrame as my extension of the class (i'm sure there is terminology for that, im just new at java)

What i want is my images on my buttons to take up the whole button rather than just part of it. Have a look at the attached image for reference.

This is my code:

package Puzzle;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */



import java.awt.BorderLayout;
import javax.swing.JApplet;
import java.awt.Dimension;

import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;

import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;

import javax.swing.JPanel;

import java.util.Random;




/**
 *
 * @author Owner
 */
public class Main extends JApplet implements ActionListener{

    private JPanel centerPanel;
    private JButton button;
    private JLabel label;
    private Image source;
    private Image image;
    private Image[] imlist;
    private JButton[] buttons;
    private Random generator;

    int[][] pos;
    int width, height;

    public Main(){
        generator = new Random();
        imlist = new Image[11];
        buttons = new JButton[11];
        pos = new int[][]{
            {0,1,2},
            {3,4,5},
            {6,7,8},
            {9,10,11}
        };

        centerPanel = new JPanel();
        centerPanel.setLayout((new GridLayout(4,4,0,0)));

        ImageIcon sid = new ImageIcon(Main.class.getResource("Sid.jpg"));
        source = sid.getImage();

        width = sid.getIconWidth();
        height = sid.getIconHeight();

        add(Box.createRigidArea(new Dimension(0,5)), BorderLayout.NORTH);
        add(centerPanel,BorderLayout.CENTER);

        int count = -1;
        for(int i = 0; i<4 ; i++ ){
            for(int j = 0; j<3; j++){
                count ++;
                if(j==2 && i == 3){
                    label = new JLabel("");
                    centerPanel.add(label);
                }
                else{
                    button = new JButton();
                    button.addActionListener(this);
                    centerPanel.add(button);
                    imlist[count] = createImage(new FilteredImageSource(source.getSource(),
                            new CropImageFilter(j*width/3, i*height/4, width/3+1, height/4)));
                    buttons[count]  = button;
                    
                }
            }
        }
        Image im;
        for(int i = 0; i< buttons.length; i++){
            try{ im = imlist[generator.nextInt(imlist.length-1)];}
            catch(Exception e){
                im = imlist[0];
            }
            imlist = remove(im, imlist);

            buttons[i].setIcon(new ImageIcon(im));
        }



        setSize(325, 275);
        //setTitle("Puzzle");
        //setResizable(false);
        //setLocationRelativeTo(null);
        //setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        //setDefaultLookAndFeelDecorated(true);
        setVisible(true);

    }

    /**
     * @param args the command line arguments
     */
    @Override
    public void init() {
        
        new Main();
    }



    public void actionPerformed(ActionEvent e) {
        JButton but = (JButton) e.getSource();

        Dimension size = but.getSize();

        int LabelX = label.getX();
        int LabelY = label.getY();
        int ButtonX = but.getX();
        int ButtonY = but.getY();
        int ButtonPosX = ButtonX/size.width;
        int ButtonPosY = ButtonY / size.height;
        int buttonIndex = pos[ButtonPosY][ButtonPosX];

        if (LabelX == ButtonX && (LabelY - ButtonY) == size.height ) {

             int labelIndex = buttonIndex + 3;

             centerPanel.remove(buttonIndex);
             centerPanel.add(label, buttonIndex);
             centerPanel.add(but,labelIndex);
             centerPanel.validate();
        }

        if(LabelY == ButtonY && (LabelX - ButtonX) == size.width){
            int labelIndex = buttonIndex +1;

            centerPanel.remove(buttonIndex);
            centerPanel.add(label, buttonIndex);
            centerPanel.add(but,labelIndex);
            centerPanel.validate();
        }

        if(LabelY == ButtonY && (LabelX - ButtonX) == -size.width){
            int labelIndex = buttonIndex -1;

            centerPanel.remove(buttonIndex);
            centerPanel.add(label, labelIndex);
            centerPanel.add(but, labelIndex);
            
            centerPanel.validate();

        }

        if (LabelX == ButtonX && (LabelY - ButtonY) == -size.height){
            int labelIndex = buttonIndex - 3;

            centerPanel.remove(labelIndex);
            centerPanel.add(but, labelIndex);
            centerPanel.add(label, buttonIndex);
            centerPanel.validate();
        }
        
    }

    public Image[] remove(Image im, Image[] list){
        Image[] ret = new Image[list.length-1];
        int count = 0;
        for(int i = 0; i < list.length; i++){
            if(list[i]!= im){
                ret[count] = list[i];
                count ++;
            }

        }
        return ret;
    }

}

Dani AI

Generated

The behaviour difference between the JFrame build and the JApplet build is almost always down to two things: the applet’s actual size (the browser/embed determines the displayed size, so setSize can be ignored) and how the button icon is created/painted. is right to suggest scaling the icon; is also correct that button margins/insets matter — but margins alone won’t help if the icon is smaller than the GridLayout cell or if the applet is larger/smaller than expected.

Practical checklist (apply in this order):

  • Stop creating a second Main instance inside init() — the applet instance created by the browser is the one that will be shown. Initialisation should populate that instance (or move UI setup into init()), not new Main().
  • Don’t rely on setSize inside the applet; set the applet dimensions in HTML or use setPreferredSize and read getWidth()/getHeight() after the applet is shown. GridLayout will size cells to the container, so compute cellWidth = panel.getWidth()/cols and cellHeight = panel.getHeight()/rows after layout (ComponentListener/componentResized) and scale icons to those values.
  • Scale each slice to the actual cell size before calling setIcon (use Image.getScaledInstance(...) for a simple approach). To remove leftover gaps, combine scaling with removing button chrome: turn off border/content-area/focus painting and set icon/text gaps to zero. If dynamic resizing is required, rescale on component resize or subclass JButton and draw the image stretched in paintComponent.

Short examples (new code, not from previous posts):

Image scaled = original.getScaledInstance(cellWidth, cellHeight, Image.SCALE_SMOOTH);
button.setIcon(new ImageIcon(scaled));

button.setBorderPainted(false);
button.setContentAreaFilled(false);
button.setFocusPainted(false);
button.setIconTextGap(0);

For a fully flexible solution, override paintComponent in a custom JButton to draw the icon to getWidth()/getHeight(). Reference: Image.getScaledInstance documentation (Java SE) — https://docs.oracle.com/javase/8/docs/api/java/awt/Image.html#getScaledInstance-int-int-int-.

Recommended Answers

All 6 Replies

try setting your button to a certain width and scale the imageIcons by using getScaledInstance() method of the Image class.

You can set the margin on the button with the following

button.setMargin(new Insets(0,0,0,0));

I put that line of code in just before where i set the icon on the button and nothing happened. Is this because i put it in the wrong place? Or do i need a different solution?

I just noticed that when i had this as just a JFrame swing application it worked perfectly and just how i wanted it. So, is there perhaps something about the way that a JApplet displays it that could change how it works?

Well, the look and feel could be different between the two perhaps.

Is there any way that i could change that? Or is that just set for the JApplet and JFrame?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.