简体   繁体   中英

What Java Swing event can be used to know when application has finished starting?

I'm looking for a place to hook some code to programmatically create, size and position a JPanel after the application has finished loading.

I'm just starting with Java. I'm using NetBeans 6.5.1 with jdk1.6.0_13. I've used the new project wizard to create a basic Java/Swing desktop application. This is a SingleFrameApplication that uses a FrameView with a central main JPanel where all the UI elements are placed.

I first tried my code in the FrameView constructor but when I try to arrange my JPanel based on the bounding rectangle of one of the design time controls I added to the UI, that control has not yet finished being positioned and sized so I'm getting all zeros for the coordinates.

I've verified my code works as expected by calling it from a click event after the application has loaded so my problem is finding a way to know when everything is finished being sized and arranged.

I also tried the componentShown event from the main JPanel but I later read that is only fired if setVisible is explicitly called which apparently doesn't happen during normal application startup.

Can anyone provide some pointers? Thanks.

Update:

In addition to what I mention in my answer below, I also read about the Application.ready() method. This would also be a point in time of interest for knowing when the UI part of an application is finished doing everything it needs to do. Communicating to my view from the application seemed a bit messy though.

The solution I went with was actually a combination of the answers from Charles Marin and JRL (I upvoted both of your answers for credit, thanks).

I had my FrameView class implement WindowListener.

...
public class MyView extends FrameView implements WindowListener
...

and in my FrameView constructor I added a listener to the application's main frame.

...
getFrame().addWindowListener((WindowListener) this);
...

Then in my implementation of windowActivated I could call the code I had to arrange and size a control on the main JPanel based on the location and size of other controls.

public void windowActivated(WindowEvent e)
{
    // The application should now be finished doing its startup stuff.
    // Position and size a control based on other UI controls here
}

I think you want WindowActivated. Have a look at this part of the tutorial .

我尝试使用getFrame().isValid()

I assume this is the WYSIWYG editor thing. I'm looking at NetBeans 6.1, so your experiences may vary.

The traditional way to layout Swing components is by using a LayoutManager (or LayoutManager2 ). According to the NetBeans help, the visual editor supports these so long as they don't require support for constraints.

The procedure goes something like this:

  1. Create a new JavaBean and have it implement LayoutManager (a BeanInfo is required too for palette support - you can create one by right-clicking the bean class)
  2. Build the project
  3. Right-click the bean and choose Tools > Add to Palette... and add it
  4. Right-click the panel for which you want to set the layout and select Set Layout > Your Bean Name

You may find the design-time experience somewhat lacking.

A sample layout implementation:

public class StepLayoutBean extends Object implements Serializable, LayoutManager {

    public void addLayoutComponent(String name, Component component) {
    }

    public void layoutContainer(Container container) {
        Dimension space = container.getSize();
        int xoffset = 0;
        int yoffset = 0;
        for (Component kid : container.getComponents()) {
            Dimension prefSize = kid.getPreferredSize();
            if (prefSize.width + xoffset > space.width) {
                xoffset = 0;
            }
            Rectangle bounds = new Rectangle(xoffset, yoffset, prefSize.width, prefSize.height);
            kid.setBounds(bounds);
            xoffset += prefSize.width;
            yoffset += prefSize.height;
        }
    }

    public Dimension minimumLayoutSize(Container container) {
        Dimension size = new Dimension();
        for (Component kid : container.getComponents()) {
            Dimension minSize = kid.getMinimumSize();
            size.width = minSize.width > size.width ? minSize.width : size.width;
            size.height += minSize.height;
        }
        return size;
    }

    public Dimension preferredLayoutSize(Container container) {
        Dimension size = new Dimension();
        for (Component kid : container.getComponents()) {
            Dimension prefSize = kid.getPreferredSize();
            size.width += prefSize.width;
            size.height += prefSize.height;
        }
        return size;
    }

    public void removeLayoutComponent(Component component) {
    }
}

If a custom layout doesn't fit the bill, have a look at the event bindings under the component's properties panel - though resizing that way might be a recipe for some kind of recursive event storm.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM