已关闭此问题为not reproducible or was caused by typos。它目前不接受回答。
此问题是由打印错误或无法再重现的问题引起的。虽然类似的问题可能是on-topic在这里,这一个是解决的方式不太可能帮助未来的读者。
2天前关闭。
Improve this question
我有一个比这个复杂得多的应用程序,但这个简化的代码也有同样的问题。完整的应用程序在选项卡式窗格中有4个选项卡,并查询数据库以更新滚动窗格中的表。当每次请求搜索信息时,侦听器会对每个请求触发多次,导致应用程序变慢,直至无法使用。
下面最小化的代码演示了这个问题。每个选项卡上都有一个附加了侦听器的按钮。这些按钮交替地被“按下”......选项卡0,选项卡1,选项卡0,选项卡1,等等。系统输出显示乘法如何传播。迭代#1和#2都很好...侦听器每次被触发一次。迭代3到6示出了每个收听者发射两次,尽管按钮每次被按下一次。迭代7到14然后示出每个收听者发射4次。很明显,每次都要加倍查询数据库以获得相同的信息,这会大大降低应用程序的速度。
系统输出:
Iteration #1 Tab 0 listener alerted
Iteration #2 Tab 1 listener alerted
Iteration #3 Tab 0 listener alerted
Iteration #4 Tab 0 listener alerted
Iteration #5 Tab 1 listener alerted
Iteration #6 Tab 1 listener alerted
Iteration #7 Tab 0 listener alerted
Iteration #8 Tab 0 listener alerted
Iteration #9 Tab 0 listener alerted
Iteration #10 Tab 0 listener alerted
Iteration #11 Tab 1 listener alerted
Iteration #12 Tab 1 listener alerted
Iteration #13 Tab 1 listener alerted
Iteration #14 Tab 1 listener alerted
代码如下:
package SwingTest;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class SwingTest extends JFrame
{JTabbedPane MainScreen = new JTabbedPane();
final static long serialVersionUID = 1L;
int iter = 0;
JPanel tab0Panel = new JPanel();`your text`
final JLabel t0ID = new JLabel("Tab 0");
JButton t0Test = new JButton("Test");
JPanel tab1Panel = new JPanel();
final JLabel t1ID = new JLabel("Tab 1");
JButton t1Test = new JButton("Test");
public static void main(String[] args)
{JFrame MainDisplay = new SwingTest();
MainDisplay.setVisible(true);
MainDisplay.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public SwingTest()
{super("SwingTest");
setSize(300, 300);
getContentPane().setLayout(null);
setLocationRelativeTo(null);
MainScreen.setBounds(0, 0, 300, 300);
MainScreen.add("Tab 0",tab0Layout());
MainScreen.add("Tab 1",tab1Layout());
getContentPane().add(MainScreen);
}
public JPanel tab0Layout()
{tab0Panel.setSize(300, 300);
t0ID.setBounds(100,100,60,20);
tab0Panel.add(t0ID);
t0Test.setBounds(100,150,60,20);
tab0Panel.add(t0Test);
t0Test.addActionListener
(new ActionListener()
{public void actionPerformed(ActionEvent e)
{iter++;
System.out.println("Iteration #"+iter+" Tab 0 listener alerted");
MainScreen.setComponentAt(0, tab0Layout());
revalidate();
repaint();
}
}
);
return tab0Panel;
}
public JPanel tab1Layout()
{tab1Panel.setSize(300, 300);
t1ID.setBounds(100,100,60,20);
tab1Panel.add(t1ID);
t1Test.setBounds(100,150,60,20);
tab1Panel.add(t1Test);
t1Test.addActionListener
(new ActionListener()
{public void actionPerformed(ActionEvent e)
{iter++;
System.out.println("Iteration #"+iter+" Tab 1 listener alerted");
MainScreen.setComponentAt(1, tab1Layout());
revalidate();
repaint();
}
}
);
return tab1Panel;
}
}
提前感谢您的帮助!
显然我做错了什么,不明白原因。
1条答案
按热度按时间von4xj4u1#
每次运行第一个ActionListener时,它都会调用
tab0Layout()
,向t0Test变量添加一个 new ActionListener,同样,每次运行第二个ActionListener时,它都会调用tab1Layout()
,向t1Test变量添加一个 new ActionListener。这意味着,每个ActionListener都将自己的新副本添加到每次调用的自己的按钮中,这会导致一堆侦听器被添加到按钮中,所有侦听器都同时调用。不好解决方案是只添加一次侦听器,而不是在侦听器中添加。