似乎在我的应用程序中,单击JButton
时执行方法的次数与我调整JFrame
的大小相关。在下面的示例中,当我启动应用程序并且根本不调整大小时,方法addPanel(Dimension dim)
将执行2次。调整大小一次,甚至更多。这怎么解释? ResizeController
对此有影响吗?
(已经说明的线条涉及另外两个“屏幕”,在这种情况下并不重要)。
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();
}
}
}
}
答案 0 :(得分:4)
每当你调整帧的内容时,你都会调用setupElements(),它会一次又一次地向按钮添加监听器。 只需移动在框架的initialize()方法中添加侦听器的代码。
答案 1 :(得分:4)
(这就是为什么......)使用ComponentListener
最安全的方式是实现ComponentListener
,
以小型javax.swing.Timer
开始350-500ms
,
如果调整大小仍然继续调用Timer#restart()
,
为Swing Action
Swing Timer
删除Thread.sleep(int)
,在调整大小期间导致闪烁或冻结
所有上述代码都可以替换为正确的Layout Manager
,GridBagLayout
或自定义(和今天)MigLayout