2

It seems that in my application, the amount of times a method is executed when clicking a JButton is related to the amount of times I resize the JFrame. In the example below, when I start the application and don't resize at all, the method addPanel(Dimension dim) is executed 2 times. After resizing one time, even more at once. How is this explainable? Does the ResizeController has any influence on this? (The outcommented lines are concerning two other "screens", that in this case don't matter).

Start.java

public class Start {

    public static void main(String[] arg){

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new GroundFrame(Toolkit.getDefaultToolkit().getScreenSize());
            }
        });

    }
}

GroundFrame.java

public class GroundFrame extends JFrame{

    public static final long    serialVersionUID = 55;
    private Container           contentPane;
    public static Flyer         screenFlyer;
    public static Points        screenPoints;
    public static Sponsoren     screenSponsoren;
    public static JFrame        parent;

    public GroundFrame(Dimension screenDimension){
        createAndShowGUI(screenDimension);
        setVisible(true);
    }

    private void createAndShowGUI(Dimension screenDimension){
        setExtendedState(JFrame.MAXIMIZED_BOTH); 

        parent = this;

        contentPane = getContentPane();
        contentPane.setLayout(null);

        //screenFlyer = new Flyer(screenDimension);
        //screenSponsoren = new Sponsoren(screenDimension);
        //screenSponsoren.setVisible(false);
        screenPoints = new Points(screenDimension);
        //screenPoints.setVisible(false);

        ResizeController controller = new ResizeController();
        controller.start();

        //contentPane.add(screenFlyer);
        //contentPane.add(screenSponsoren);
        contentPane.add(screenPoints);
    }

    public static void exit(){
        System.exit(0);
    }
}

Points.java

public class Points extends JPanel{

    public static final long            serialVersionUID = 55;

    private JButton                     buttonNext, buttonExit, buttonAdd;
    private JLabel                      copyright;

    private Vector<PlayerPointsPanel>   panels = new Vector<PlayerPointsPanel>();
    final Color                         BACKGROUND_COLOR = new Color(60,60,60);                         
    private int                         pressed = 0;


    public Points(Dimension screenDimension){
        setLayout(null);
        setBackground(BACKGROUND_COLOR);
        setPreferredSize(screenDimension);
        initialize(screenDimension);
        setupElements(screenDimension);
    }

    private void initialize(Dimension dim){
        copyright = new JLabel("\u00a9 by Valentino Rugolo (2012)", SwingConstants.CENTER);
        buttonAdd = new JButton("+");
        buttonNext = new JButton("");
        buttonExit = new JButton("X");
        /*for(int i=0; i<8; i++){
            PlayerPointsPanel panel = new PlayerPointsPanel(dim, i);
            add(panel);
            panels.add(panel);
        }*/
    }

    private void setupElements(Dimension dim){
        setBounds(0,0,dim.width, dim.height);
        setLayout(null);
        dimensionCP = dim;

        copyright.setBounds((int)(dim.width*0.82), (int)(dim.height*0.9), (int)(dim.width*0.15), (int)(dim.height*0.05));
        copyright.setFont(new Font("Times New Roman", Font.PLAIN, (int)(dim.height*0.017)));
        copyright.setForeground(Color.white);

        buttonNext.setBounds((int)(dim.width*0.01), (int)(dim.height*0.9), (int)(dim.width*0.04), (int)(dim.height*0.04));
        buttonNext.setBackground(Color.DARK_GRAY);
        buttonNext.setForeground(Color.white);
        buttonNext.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                GroundFrame.screenPoints.setVisible(false);
                GroundFrame.screenFlyer.setVisible(true);
            }
        });

        buttonExit.setBackground(Color.DARK_GRAY);
        buttonExit.setForeground(Color.white);
        buttonExit.setBounds((int)(dim.width*0.95), (int)(dim.height*0.01), (int)(dim.width*0.04), (int)(dim.height*0.04));
        buttonExit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                GroundFrame.exit();
            }
        });

        buttonAdd.setBackground(Color.DARK_GRAY);
        buttonAdd.setForeground(Color.white);
        buttonAdd.setBounds((int)(dim.width*0.01), (int)(dim.height*0.01), (int)(dim.width*0.04), (int)(dim.height*0.04));
        buttonAdd.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg1) {
                System.out.println("pressed " + pressed);
                pressed++;  
            }
        });

        add(buttonExit);
        add(buttonNext);
        add(copyright);
        add(buttonAdd);
    }

    public void resizeContent(Dimension dim){
        /*for(int i=0; i<panels.size(); i++){
            panels.elementAt(i).resizeContent(dim, i);
        }*/
        setupElements(dim);
    }
}

ResizeController.java

public class ResizeController extends Thread{

    public int sizebeforeX = GroundFrame.parent.getWidth();
    public int sizebeforeY = GroundFrame.parent.getHeight();

    public ResizeController(){

    }

    public void run(){
        while(true){

            int actualX = GroundFrame.parent.getWidth();
            int actualY = GroundFrame.parent.getHeight();

            if(sizebeforeX != actualX || sizebeforeY != actualY){
                //GroundFrame.screenFlyer.resizeContent(GroundFrame.parent.getSize());
                GroundFrame.screenPoints.resizeContent(GroundFrame.parent.getSize());
                //GroundFrame.screenSponsoren.resizeContent(GroundFrame.parent.getSize());
                sizebeforeX = actualX;
                sizebeforeY = actualY;
            }

            try {
                Thread.sleep(250);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
Valentino Ru
  • 4,964
  • 12
  • 43
  • 78

2 Answers2

4

Whenever you're resizing the content of the frame you're calling setupElements() which is adding listeners to the buttons, over and over again. Just move the code of adding the listeners in the initialize() method of the frame.

wxyz
  • 709
  • 3
  • 8
  • Oh, I knew it would be that simple... And obvious, thank you! And that also explains why by default it's called 2 times, because `setExtendedState(JFrame.MAXIMIZED_BOTH);` is already the first act of risizing. – Valentino Ru Nov 09 '12 at 08:14
4
  1. (this is reason for why..) to use ComponentListener

  2. the safiest way is implemnts ComponentListener,

  3. override its method componentResized(ComponentEvent e), or

  4. inside this method start javax.swing.Timer with small dealy 350-500ms,

  5. if resize still continue call for Timer#restart(),

  6. add Swing Action for output from Swing Timer

  7. remove Thread.sleep(int), caused flickering or freeze during resize

  8. all above mentioned code is possible to replace with proper Layout Manager, GridBagLayout or custom (and todays) MigLayout

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • I know, I should really start get into LayoutManagers. With null-Layout I feel so free :-) – Valentino Ru Nov 09 '12 at 08:45
  • 1
    1. then to use resize from ComponentListener, 2. don't to use setBound/setLocation/setSize, take this vaule from Insets, code could be little longer but with proper methods for AbsoluteLayout, – mKorbel Nov 09 '12 at 08:48