javaperformanceimageiconimage-scalingcrossword

More efficient/faster way to perform ImageIcon scaling?


I'm working on an application to create and edit crossword puzzles, the code for which I've posted at the end if it helps. I'm currently trying to sort out an issue that has cropped up in this portion of the code.

public void componentResized(ComponentEvent e) {
    // TODO Auto-generated method stub
    for(int i=0; i<width; i++) {
        for(int j=0; j<height; j++) {
            if(e.getSource()==crosswordSquare[i][j]){
                blackSquare = new ImageIcon(blackSquare.getImage().getScaledInstance(
                        crosswordSquare[i][j].getWidth(), crosswordSquare[i][j].getHeight(), 1));
                crosswordSquare[i][j].setIcon(blackSquare);
            }

        }
    }

}

Basically I'm trying to resize the ImageIcons for the JButtons to the dimensions of the JButtons after they are resize to compensate for their change in size due to the GridLayout I'm using. However, the result of this code doesn't quite meet my expectations for 2 reasons.

  1. It takes a long time to resize all 225 squares, which I'm guessing isn't a typical crossword size. I do want to make a size editing feature later, so I probably want to be able to handle more squares.
  2. It sometimes works, but other times the squares get really narrow when enlarged, and I'm not sure why that's happening.

Essentially I need to find a faster approach. Any ideas on how to modify/improve upon it? Would it make any difference to do the updates via a paint method?

    public class CrosswordInterface extends JFrame 
            implements ComponentListener, ActionListener{

    //private ArrayList<ArrayList<JButton>> squares= new ArrayList<ArrayList<JButton>>();

    private JButton[][] crosswordSquare = new JButton[15][15];

    private ImageIcon blackSquare = new ImageIcon(
        CrosswordInterface.class.getResource("BlackSquare.png"));

    private JPanel panel = new JPanel();

    //stores default width and height of square array
    //initial value of 15 (225 squares)
    private int width = 15;
    private int height = 15;

    public CrosswordInterface() {
    CreateCrosswordGrid(); 
        setSize(width *blackSquare.getIconWidth(), height*blackSquare.getIconHeight());
    setVisible(true);
    setResizable(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public int getWidth() {
    return width;
    }



    public int getHeight() {
    return height;
    }

    private void CreateCrosswordGrid() {


    panel.setLayout(new GridLayout(width, height));
    for(int i=0; i<width; i++) {

        for(int j=0; j<height; j++) {
            JButton b = new JButton();
            b.setIcon(blackSquare);
            //b.setText(text);
            //b.setIconTextGap()
            //b.setIco;

            b.setSize(blackSquare.getIconWidth(), blackSquare.getIconHeight());
            crosswordSquare[i][j]=b;
            crosswordSquare[i][j].addComponentListener(this);
            panel.add(crosswordSquare[i][j]);
        }
    }
    panel.setSize(width * blackSquare.getIconWidth(), height * blackSquare.getIconHeight());
    setSize(height * blackSquare.getIconWidth(), width * blackSquare.getIconHeight());
    //panel.set
    add(panel);
}

public void actionPerformed(ActionEvent e) {


    for(int i=0; i<width; i++) {
        for(int j=0; j<height; j++) {
            if(e.getSource()==crosswordSquare[i][j]){

            }

        }
    }

}

    public void componentHidden(ComponentEvent e) {
    // TODO Auto-generated method stub

    }

public void componentMoved(ComponentEvent e) {
    // TODO Auto-generated method stub

}

public void componentResized(ComponentEvent e) {
    // TODO Auto-generated method stub
    for(int i=0; i<width; i++) {
        for(int j=0; j<height; j++) {
            if(e.getSource()==crosswordSquare[i][j]){
                blackSquare = new ImageIcon(blackSquare.getImage().getScaledInstance(
                        crosswordSquare[i][j].getWidth(), crosswordSquare[i][j].getHeight(), 1));
                crosswordSquare[i][j].setIcon(blackSquare);
            }

        }
    }

}

public void componentShown(ComponentEvent e) {
    // TODO Auto-generated method stub

}


}

Solution

  • echoing what bdares said in his comment above. I would use a limited set (2 ?) of icons that can be placed at the right spots when the grid is resized. No reason why you should need to resize similar looking images for every square (assuming they are similar!).