setLocation() and setBounds() method for JButton not working in specific cases

677 views Asked by At

I found similar questions on this forum, but they are not exactly my problem. I have a JPanel with absolute layout and on that panel, I have two JButtons. One is called swapButton, which swaps position of two buttons on the same panel and another is openButton, which opens an image do some processing with that image and with some buttons on the same panel and then calls swapButton.doClick().

Code for action performed by openButton:

private void openButtonActionPerformed(java.awt.event.ActionEvent evt) {                                           
        FileDialog filedialog = new FileDialog(GameFrame.this,"Open File",FileDialog.LOAD);
        filedialog.setVisible(true);
        try{
            if(filedialog.getFile() != null){
                filename = filedialog.getDirectory() + filedialog.getFile();
                file = new File(filename);

                File deleteFile = new File(defaultPath.toString());
                deleteFile.delete();
                Files.copy(file.toPath(),defaultPath);
                file = new File(defaultPath.toString());
                imageSelected = true;
                newGame = true;

                cropImage();
                setImage();
            }
        }
        catch(IOException e){}
        if(imageSelected){
            setCombination();
            swapButton.doClick();
            moves = 0;
            msgLabel.setText("");
        }
    }

Code for action performed by swapButton:

private void swapButtonActionPerformed(java.awt.event.ActionEvent evt) {                                           
        int n = Integer.valueOf(numText.getText()); //gets value from a text area
        swapButton(n);
    }

Code for swapButton method:

void swapButton(int i)
    {
        javax.swing.JButton button1 = buttonList[i], button2 = emptyButton;
        int x1 = button1.getX(), y1 = button1.getY();
        int x2 = button2.getX(), y2 = button2.getY();
        button1.setLocation(x2, y2);
        button2.setLocation(x1, y1);
        int p1 = pos[i], p2 = pos[8];
        pos[i] = p2;
        pos[8] = p1;
        arr[p1] = 8;
        arr[p2] = i;
        moves++;
    }

I coded the action performed by swapButton in a seperate method for a purpose.

The problem is, when I click on openButton, all actions of that button works perfectly and swapButton.doClick() is also called, but the location of the buttons in my JPanel remains the same instead of calling setLocation() method in swapButton() method. But when I click on swapButton, all action in swapButton() method works fine. I also tried calling swapButton.doClick() from other area of the code and it works fine.

I printed the locations of the buttons after calling setLocation() method in swapButton() method using getLocation() method and it shows new locations for those buttons, but there are no changes in locations of those buttons in my JFrame. I also tried using setBounds() and getBounds() method and got the same result.

Is it some bug? Or something wrong done by me?

1

There are 1 answers

0
bitguru On

First of all, absolute layout means no layout manager or null layout manager. This is absolutely not recommended. For any beginning or intermediate Swing programmers out there, you should essentially never use absolute layout. If I were doing this I might create my own custom implementation of the java.awt.LayoutManager interface, and give that implementation a swap() method. That would keep all the location-swapping stuff encapsulated in my custom layout manager. But that's not what you asked.

It's hard to answer your question without more details, but is there a reason you need to call the swapButton's doClick() method? You would call that if it were important for the user to see the button appear to be pushed on the screen. [doClick()'s default on-screen push length is 68 milliseconds, btw, during which the EDT* will be frozen.] If you're only concerned that swapButton's ActionListener method gets invoked, then it may work better to simply call that method directly. That way, the openButton stuff does not depend on the timing of when swapButton's listeners are registered and such.

If you replace swapButton.doClick() with swapButtonActionPerformed() does it work any better?

Something else to watch for is that you're doing all this location swapping stuff on the event dispatch thread (EDT). From your description there's no indication that you are not running on the EDT, but we can't tell for sure without seeing the rest of your code. Hence the usefulness of an SSCCE.

*footnote: unless you're not calling it from the EDT, which is its own problem