问题描述
有人请帮帮我
我正在使用一个 Java 应用程序制作销售发票。我在下面复制了我的部分代码的工作示例。此应用程序包含一个带有菜单项的主窗口,单击该菜单项后,将打开一个带有组合框的“销售”窗口,以选择项目。在选择项目时,将打开一个弹出窗口以选择价格,然后打开另一个弹出窗口以选择数量。选择数量后,销售账单窗口中的表格将填入项目、价格和数量。
当打开多个销售窗口时,数量窗口中的数据将转到最后打开的销售窗口。有什么方法可以将数据传递到旧的销售窗口,通过鼠标点击将其带到前面?
import java.awt.EventQueue;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JComboBox;
import javax.swing.jdialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
public class Main extends JFrame {
private static JPanel contentPane;
public static void main(String[] args) {
EventQueue.invokelater(new Runnable() {
public void run() {
try {
Main frame = new Main();
frame.setVisible(true);
} catch (Exception e) {
e.printstacktrace();
}
}
});
}
public Main() {
setTitle("Menu");
setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
setBounds(500,500,425);
setLocationRelativeto(null);
contentPane = new JPanel();
contentPane.setLayout(null);
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu mnSales = new JMenu("Sales");
menuBar.add(mnSales);
JMenuItem mntmProcessSale = new JMenuItem("Generate Sales Invoice");
mntmProcessSale.addActionListener( e -> {
Sale frame = new Sale(this);
frame.setVisible(true);
});
mnSales.add(mntmProcessSale);
}
public static class Sale extends jdialog {
private JComboBox comboBox;
private JLabel lbl;
private static JTable table;
public Sale(JFrame sale) {
super(sale);
setTitle("Sale");
setDefaultCloSEOperation(JFrame.HIDE_ON_CLOSE);
setBounds(500,400,400);
setLocationRelativeto(null);
contentPane = new JPanel();
contentPane.setLayout(null);
setContentPane(contentPane);
lbl=new JLabel("Select Item");
lbl.setBounds(30,30,100,20);
contentPane.add (lbl);
String [] item = {"A","B","C","D"};
comboBox=new JComboBox(item);
comboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange() == ItemEvent.SELECTED) {
String s= (String) comboBox.getSelectedItem();
Price.Item(s);
comboBox.setSelectedindex(-1);
new Price(sale).setVisible(true);
}
}
});
comboBox.setBounds(30,50,200,20);
comboBox.setSelectedindex(-1);
contentPane.add (comboBox);
JScrollPane scrollPane= new JScrollPane();
scrollPane.setBounds(20,80,250,150);
contentPane.add(scrollPane);
table=new JTable();
table.setModel(new DefaultTableModel(
new Object[][] {
},new String[] {
"Item","Price","Qty"
}
));
scrollPane.setViewportView(table);
}
public static void filltable(Object[] row) {
DefaultTableModel tm1 = (DefaultTableModel)table.getModel();
tm1.addRow(row);
System.out.println(row);
}
}
public static class Price extends jdialog {
private JComboBox comboBox;
private JLabel lbl;
private JPanel contentPane1;
static String Item =null;
public Price(JFrame price) {
super(price);
setTitle("Price");
setDefaultCloSEOperation(JFrame.HIDE_ON_CLOSE);
setBounds(500,300,300);
contentPane1 = new JPanel();
contentPane1.setLayout(null);
setLocationRelativeto(null);
setContentPane(contentPane1);
lbl=new JLabel("Select Price");
lbl.setBounds(30,20);
contentPane1.add (lbl);
String [] Price = {"5","10","20","30"};
comboBox=new JComboBox(Price);
comboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange() == ItemEvent.SELECTED) {
String s= (String) comboBox.getSelectedItem();
Qty.Price(Item,s);
comboBox.setSelectedindex(-1);
new Qty(price).setVisible(true);
dispose();
}
}
});
comboBox.setBounds(30,20);
comboBox.setSelectedindex(-1);
contentPane1.add (comboBox);
}
public static void Item(String item) {
Item=item;
}
}
public static class Qty extends jdialog {
private JComboBox comboBox;
private JLabel lbl;
private JPanel contentPane2;
static String Item =null;
static String Price =null;
public Qty(JFrame qty) {
super(qty);
setTitle("Qty");
setDefaultCloSEOperation(JFrame.HIDE_ON_CLOSE);
setBounds(500,300);
setLocationRelativeto(null);
contentPane2 = new JPanel();
contentPane2.setLayout(null);
setContentPane(contentPane2);
lbl=new JLabel("Select Qty");
lbl.setBounds(30,20);
contentPane2.add (lbl);
String [] Qty = {"1","2","3","4"};
comboBox=new JComboBox(Qty);
comboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange() == ItemEvent.SELECTED) {
String qty= (String) comboBox.getSelectedItem();
Sale.filltable(new Object[] {Item,Price,qty});
dispose();
}
}
});
comboBox.setBounds(30,20);
comboBox.setSelectedindex(-1);
contentPane2.add (comboBox);
}
public static void Price(String item,String price) {
Item=item; Price=price;
}
}
}
解决方法
您的 Sale 类对您正在填写的表格有静态引用。这意味着 Sale 的所有实例共享同一个表引用——这个表引用实际上属于上次打开的销售窗口。这是一个重大错误,而且是非常糟糕的做法。
我假设您将方法 fillTable 设为静态,因为您在 QTY 对话框中没有对 Sale 对象的引用。而这个静态方法导致静态字段。
我认为您必须阅读模型-视图-控制器范例并重新设计您的程序。
您当前的问题可以轻松解决:
- 在 Sale
private final
课上制作桌子。 - 将 Sale 对象作为构造函数参数传递给 Qty 对话框。然后你可以在ot中调用fillTable()方法。
- 每个人和他的狗都将他们的班级命名为
Main
。我将名称更改为OthrMain
。 - 不要在每次点击“销售”菜单项时创建另一个
Sale
实例。我向类salesDlg
添加了一个名为OthrMain
的成员变量。 -
HIDE_ON_CLOSE
是JDialog
的默认值,因此无需明确设置。 - 无需显式设置
JDialog
内容窗格,所以不要这样做。 - 不要使用静态变量将数据从一个对象传递到另一个对象。如果您想将一个值从“Sales”
JDialog
传递给“Price”JDialog
,那么向“Price”JDialog
添加一个方法,即“Sales”{{1} } 可以打电话。 - 不要使用空布局。使用适当的 layout managers
- 每个
JDialog
的所有者应该是打开它的JDialog
。例如,“价格”JDialog
的所有者应该是“销售”JDialog
。
我相信以下代码可以满足您的需求。
JDialog