2

似乎在我的应用程序中,单击 a 时执行方法的JButton次数与我调整JFrame. 在下面的示例中,当我启动应用程序并且根本不调整大小时,该方法addPanel(Dimension dim)执行了 2 次。调整一次大小后,一次甚至更多。这怎么解释?ResizeController对这个有影响吗?(注释行与另外两个“屏幕”有关,在这种情况下无关紧要)。

启动.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);
    }
}

点数.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();
            }
        }
    }
}
4

2 回答 2

4

每当您调整框架内容的大小时,您都会调用 setupElements() ,它会一遍又一遍地向按钮添加侦听器。只需将添加监听器的代码移到框架的initialize()方法中即可。

于 2012-11-09T08:09:00.680 回答
4
  1. (这是为什么..)使用ComponentListener

  2. 最安全的方法是实施ComponentListener

  3. 覆盖其方法componentResized(ComponentEvent e)

  4. 在这个方法里面javax.swing.Timer从小交易开始350-500ms

  5. 如果调整大小仍然继续调用Timer#restart()

  6. 添加Swing Action从输出Swing Timer

  7. remove Thread.sleep(int), 在调整大小时导致闪烁或冻结

  8. 上述所有代码都可以用适当Layout ManagerGridBagLayout或自定义的(以及今天的)替换MigLayout

于 2012-11-09T08:13:56.907 回答