-1

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?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 1
    *"Or something wrong done by me?"* Yep. And it began with not using a layout. Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). – Andrew Thompson Aug 31 '17 at 16:19
  • 1
    General advice: 1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 2) Provide ASCII art or a simple drawing of the *intended* layout of the GUI at minimum size, and if resizable, with more width and height. – Andrew Thompson Aug 31 '17 at 16:20
  • I have used absolute layout. – user8544110 Aug 31 '17 at 16:26
  • *"I have used absolute layout."* That's a fancy-pants name for a `null` layout. And a `null` layout is *"not using a layout"*. – Andrew Thompson Aug 31 '17 at 17:51
  • 2
    From another (now closed & deleted question, a duplicate of this one) *"This is the minimal version of that question,"* As minimal as your attention span seems to be? MCVE has 4 letters. Ignore the first for the moment and concentrate on the other 3. *"I couldn't provide the code where the problem lies, that's why i have posted this again. I wanted to delete the previous question."* No, don't delete it! Instead you can [edit] your own question at any time. When you do, post an MCVE. But **read** the documents on both the MCVE & SSCCE first & stop wasting your (& more importantly **our**) time. – Andrew Thompson Sep 01 '17 at 06:42
  • `I have used absolute layout` - why? Based on the picture from your other (closed) question you can easily use a `GridLayout`. Don't try to manage the size/location manually. Swing was designed to be used with layout managers. Don't attempt to "swap" buttons. Just change the Icon on the button using the setIcon(...) method. – camickr Sep 01 '17 at 14:29

1 Answers1

1

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

bitguru
  • 21
  • 2