我有一个主窗口(JFrame),其中包含许多组件,包括一个按钮。按下该按钮后,打开另一个窗口(JFrame),让我们称之为客户窗口,供用户搜索详细信息并在主窗口中显示这些详细信息。
有许多类似于主窗口的窗口,所有这些主窗口都有自己的客户窗口,用于搜索和显示详细信息。
现在,我的问题是我希望所有主窗口只有一类客户窗口,而不是每个主窗口都有它。这是因为客户窗口内的所有主窗口都是相同的,除了每个客户窗口打开该特定主窗口的详细信息,即设置字段文本和将数据插入表格等等。 这里的问题是当我必须修改某些内容时...我必须编写所有其他客户窗口的代码,这也浪费时间并且还增加了应用程序/重复代码的大小。
所以,我想知道一些方法,我可以为所有主窗口提供1类客户窗口,并跟踪打开客户窗口的主窗口,以便我可以在该主窗口中打开详细信息。请注意,用户将同时打开多个主窗口,因此需要打开多个客户窗口实例。
下面是一些代码,可以了解我目前是如何做到的......
Cash_sale_customer_window:
..... get all the data from database.....
CashSaleInvoice.customerNumberTextField.setText(rs.getString(1));
CashSaleInvoice.customerNameTextField.setText(rs.getString(2));
....and so on....
Credit_sale_customer_window:
.....get all the data from database.....
CreditSaleInvoice.customerNumberTextField.setText(rs.getString(1));
CreditSaleInvoice.customerNameTextField.setText(rs.getString(2));
....and so on....
该计划的屏幕截图:
主窗口:http://postimg.org/image/adrdmrli5/
现金销售发票:http://postimg.org/image/6bcdynwhd/
任何帮助将不胜感激!
答案 0 :(得分:2)
首先,请查看The Use of Multiple JFrames: Good or Bad Practice?
其次,考虑使用模态对话框,因为这些将允许你"暂停"在对话框可见的位置执行代码并且"继续"关闭后执行。
这允许您提示用户提供详细信息,收集结果并处理它们,而无需设置引用链或回调
请查看How to make dialogs了解详情
<强>更新强>
如果您不能使用模态对话框,则需要将主框架的引用传递给子框架。就个人而言,我首先定义一个interface
来描述子框架可以对主窗口执行的允许操作,这样就可以解耦实现并防止子框架对主窗口执行操作#39; t,就像移除所有组件一样......
答案 1 :(得分:1)
我可能会误解这个问题,但过去我做过类似的事情。这是我写的代码。这是一个Singleton,Duplicatable JFrame(我根据我的设计扩展JPanel
)。
这是如何工作的:
如果您尝试打开一个新窗口并且它已经打开,它会收到焦点。如果不是,则打开一个新窗口。它使用identifier
变量(可以是任何东西)来跟踪。
如何使用它:
使用静态showPanel
方法,以便类确定您是否需要新面板,如下所示:
SingletonDuplicatableFramePanel.showPanel(new SingletonDuplicatableFramePanel(identifier));
(请记住,SingletonDuplicatableFramePanel
是抽象的,所以你需要创建另一个扩展它的类。)
您传递了showPanel()
新班级的实例。
只有在实际创建新实例时才会执行抽象方法init()
。这是您初始化新窗口所需的任何内容。在init()
方法结束时,您拨打setVisible()
。
如前所述,为了使其可复制,它会跟踪一个唯一的identifier
,它用于确定您是否已打开实例。运行演示时应该很清楚。
以下是SingletonDuplicatableFramePanel
的代码:
public abstract class SingletonDuplicatableFramePanel extends JPanel {
public SingletonDuplicatableFramePanel(String name) {
this.name = name;
}
static LinkedHashMap<Class, LinkedHashMap<Object, SingletonDuplicatableFramePanel>> self_panel_map;
JFrame self_jf;
protected SingletonDuplicatableFramePanel self_panel;
boolean loading;
boolean showing;
LinkedList<SingletonDuplicatableFramePanel> vpanel_children;
LinkedList<JDialog> dialog_children;
public final String name;
public abstract void init();
private boolean searchablePanel;
public boolean isSearchablePanel() {
return searchablePanel;
}
public void setSearchablePanel(boolean searchablePanel) {
this.searchablePanel = searchablePanel;
}
public void toFront() {
self_jf.toFront();
}
protected Object identifier;
public static SingletonDuplicatableFramePanel showPanel(Object identifier, SingletonDuplicatableFramePanel newInstance) {
if(self_panel_map == null)
self_panel_map = new LinkedHashMap<>();
Class newInstanceClass = newInstance.getClass();
if(self_panel_map.containsKey(newInstanceClass) && self_panel_map.get(newInstanceClass).containsKey(identifier)) {
SingletonDuplicatableFramePanel oldInstance = self_panel_map.get(newInstanceClass).get(identifier);
oldInstance.showing = oldInstance.self_jf.isVisible();
if(!oldInstance.loading && !oldInstance.showing) {
newInstance.loading = true;
newInstance.self_panel = newInstance;
newInstance.self_jf = new JFrame(newInstance.name);
newInstance.identifier = identifier;
newInstance.self_panel.init();
self_panel_map.get(newInstanceClass).put(identifier, newInstance);
return newInstance;
} else if(oldInstance.showing) {
oldInstance.self_jf.toFront();
}
return oldInstance;
} else {
if(!self_panel_map.containsKey(newInstanceClass))
self_panel_map.put(newInstanceClass, new LinkedHashMap<Object, SingletonDuplicatableFramePanel>());
newInstance.loading = true;
newInstance.self_panel = newInstance;
newInstance.self_jf = new JFrame(newInstance.name);
newInstance.identifier = identifier;
newInstance.self_panel.init();
self_panel_map.get(newInstanceClass).put(identifier, newInstance);
return newInstance;
}
}
public void addChild(SingletonDuplicatableFramePanel panel) {
if(vpanel_children == null)
vpanel_children = new LinkedList<>();
vpanel_children.add(panel);
}
public void dispose() {
loading = false;
showing = false;
self_jf.dispose();
}
boolean packed;
public void pack() {
self_jf.add(self_panel);
self_jf.pack();
self_jf.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
if(vpanel_children != null)
for(SingletonDuplicatableFramePanel vpanel : vpanel_children)
vpanel.dispose();
if(dialog_children != null)
for(JDialog dialog : dialog_children)
dialog.dispose();
}
});
setLocationByPlatform(true);
self_jf.toFront();
self_jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
packed = true;
}
public void setVisible() {
if(!packed) {
pack();
}
self_jf.setVisible(true);
loading = false;
}
public void setTitle(String title) {
self_jf.setTitle(title);
}
public void centerJF() {
self_jf.setLocationRelativeTo(null);
}
public void setLocationByPlatform(boolean bool) {
self_jf.setLocationByPlatform(bool);
}
}
这是一个正在使用的样本:
static class My_SDFP extends SingletonDuplicatableFramePanel {
String customer_number;
public My_SDFP(String customer_number) {
super("My SDFP");
this.customer_number = customer_number;
}
@Override
public void init() {
JLabel label = new JLabel("Customer Number = " + customer_number);
add(label);
setVisible();
}
}
public static void main(String[] args) {
JFrame baseFrame = new JFrame();
baseFrame.setLayout(new GridBagLayout());
JButton button = new JButton("Open customer #");
final JTextField identifier_field = new JTextField();
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
String identifier = identifier_field.getText();
My_SDFP.showPanel(identifier, new My_SDFP(identifier));
}
});
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(2, 2, 2, 2);
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridy = 1;
baseFrame.add(new JLabel("Customer #:"), gbc);
baseFrame.add(identifier_field, gbc);
gbc.gridwidth = 2;
gbc.gridy = 2;
baseFrame.add(button, gbc);
baseFrame.pack();
baseFrame.setLocationByPlatform(true);
baseFrame.setVisible(true);
baseFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
在Customer#字段中键入一个数字,然后单击按钮。您会注意到您无法打开同一客户编号的两个实例。如果您尝试,它只会重新聚焦您尝试重新打开的帧(但不能因为它已经打开)。