Создание различных моделей данных для jTables в разных внутренних фреймах
-
11-12-2019 - |
Вопрос
Во-первых, позвольте мне отметить, что я новичок в программировании графического пользовательского интерфейса Java Desktop.Я создал панель рабочего стола, которая может содержать несколько JInternalFrames.На данный момент каждый JinternalFrame содержит одни и те же компоненты графического интерфейса, а новый jInternalFrame (здесь называемый «Внутренний фрейм») может быть создан с помощью щелчка по пункту меню.
Элементы каждого внутреннего фрейма следующие:3 Jlabels, 3 JTextFields, Jbutton и Jtable.После рендеринга первого внутреннего кадра я заполняю три текстовых поля информацией, а затем нажимаю кнопку, и в таблицу добавляется новая строка.Строка содержит информацию, используемую для заполнения текстовых полей.
Открытие второго внутреннего фрейма визуально дает мне точный интерфейс первого.Я заполняю этот фрейм таким же образом, нажимаю кнопку и вуаля, таблица во втором фрейме заполнена.
Проблема возникает, когда я возвращаюсь к предыдущему внутреннему фрейму.Я могу без проблем вводить текстовые поля, но нажатие кнопки для заполнения таблицы приводит к заполнению таблицы во втором внутреннем фрейме. Я подозреваю, что использую общую модель данных, но не уверен, как создать отдельные модели данных для jInternalFrame jTables, когда графический интерфейс для каждого кадра один и тот же..
Ниже приведен код (поскольку я новичок в разработке графического интерфейса Java Desktop, я следовал одному из инструкций Oracle для визуализации самого внутреннего фрейма - очень простой пример):
public class InternalFrames extends JFrame
implements ActionListener {
private static final long serialVersionUID = 1L;
JDesktopPane desktop;
JLabel label1;
JLabel label2;
JLabel label3;
JLabel label4;
JTextField text1;
JTextField text2;
JTextField text3;
JTable table1;
public InternalFrames(){
super("Practice Internal Frames");
int inset = 50;
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setBounds(inset,inset,screenSize.width - (inset*2),screenSize.height - (inset*2));
desktop = new JDesktopPane();
createFrame();
setContentPane(desktop);
setJMenuBar(setMenuBar());
}
protected JMenuBar setMenuBar(){
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Document");
menu.setMnemonic(KeyEvent.VK_D);
menuBar.add(menu);
JMenuItem menuItem = new JMenuItem("New");
menuItem.setMnemonic(KeyEvent.VK_N);
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, ActionEvent.ALT_MASK));
menuItem.setActionCommand("New");
menuItem.addActionListener(this);
menu.add(menuItem);
menuItem = new JMenuItem("Quit");
menuItem.setMnemonic(KeyEvent.VK_Q);
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.ALT_MASK));
menuItem.setActionCommand("Quit");
menuItem.addActionListener(this);
menu.add(menuItem);
return menuBar;
}
public void actionPerformed(ActionEvent e){
if ("New".equals(e.getActionCommand())){
createFrame();
} else if ("Quit".equals(e.getActionCommand())){
}
}
protected void createFrame(){
InternalFrame internalFrame = new InternalFrame();
label1 = new JLabel("Name");
label2 = new JLabel("Email Address:");
label3 = new JLabel("Mobile Number:");
label4 = new JLabel("Test Frames");
label1.setSize(100,10);
label2.setSize(100,10);
label3.setSize(100,10);
label4.setSize(200,10);
text1 = new JTextField(40);
text2 = new JTextField(40);
text3 = new JTextField(40);
internalFrame.setLayout(new MigLayout());
internalFrame.getContentPane().add(label1);
internalFrame.getContentPane().add(text1, "wrap");
internalFrame.getContentPane().add(label2);
internalFrame.getContentPane().add(text2, "wrap");
internalFrame.getContentPane().add(label3);
internalFrame.getContentPane().add(text3,"wrap");
internalFrame.getContentPane().add(label4, "span 2, wrap");
internalFrame.getContentPane().add(new JScrollPane(createTable()), "span 2 2, wrap");
internalFrame.getContentPane().add(createButton());
internalFrame.setVisible(true);
desktop.add(internalFrame);
try {
internalFrame.setSelected(true);
} catch (java.beans.PropertyVetoException pve){ }
}
protected JTable createTable(){
DefaultTableModel dModel = new DefaultTableModel();
table1 = new JTable(dModel);
dModel.addColumn("Name");
dModel.addColumn("Email Address");
dModel.addColumn("Mobile Number");
return table1;
}
protected JButton createButton(){
JButton button1 = new JButton("Add New List Member");
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
//Execute when button is pressed
System.out.println("You clicked the button");
populateTable(table1);
}
});
return button1;
}
protected void populateTable(JTable theTable){
if (validateEntry() == 0)
{
ListMembers listMember = new ListMembers();
listMember.setName(text1.getText());
listMember.setEmailAddress(text2.getText());
listMember.setMobilePhone(text3.getText());
Object[] data = {listMember.getName(),listMember.getEmailAddress(),listMember.getMobilePhone()};
DefaultTableModel dm = (DefaultTableModel) table1.getModel();
dm.addRow(data);
}
}
private static void createAndShowGUI(){
JFrame.setDefaultLookAndFeelDecorated(true);
InternalFrames internalFrame = new InternalFrames();
internalFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
internalFrame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Любая помощь будет принята с благодарностью.
Решение
Каждый раз, когда вы создаете новый кадр, вы инициализируете одно поле (table1
) с этой вновь созданной таблицей.И прослушиватель каждой создаваемой вами кнопки заполняет таблицу, на которую ссылается этот уникальный table1
переменная.То же самое касается ваших текстовых полей и т. д.
Либо используйте только локальные переменные и передавайте их между методами (например, вам нужно передать только что созданную таблицу методу, создающему кнопку, чтобы эта кнопка заполнила эту таблицу.Или вы извлекаете весь код в новый класс, MyInternalFrame
(выберите лучшее имя), создайте поля экземпляра таблицы, текстовых полей и кнопок этого нового класса и создавайте новый экземпляр этого класса MyInternalFrame каждый раз, когда вам понадобится новый.
Это второе решение кажется мне лучшим.