How to add internal frame to menu

时间:2015-10-31 00:01:09

标签: java user-interface

i have a GUI that has 3 menus:Read Files, Add, Finish. under the Add menu specifically, i have 3 menu items called add owner, add residential property and add commercial property. when clicking any of these menu items i have an internal frame come up but i do not want the internal frame to be the same for all menu items. i am trying to add a few more text fields for commercial and residential property compared to owner. so i do not qant the internal frame to be the same but unique for each menu item and that is where i am having trouble. here is the code import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; public class PropertyGUITest { public static void main(String[] args) { PropertyGUI obj = new PropertyGUI(); obj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); obj.setSize(400,300); obj.setVisible(true); obj.setLocation(100,50); } } class PropertyGUI extends JFrame { private int countFrames = 0; public PropertyGUI() { super("Property GUI"); JMenuBar bar = new JMenuBar(); setJMenuBar(bar); JMenu readMenu = new JMenu("Read Files"); bar.add(readMenu); JMenu addMenu = new JMenu("Add"); bar.add(addMenu); JMenuItem newFrame1=new JMenuItem("Add Owner"); addMenu.add(newFrame1); JMenuItem newFrame2=new JMenuItem("Add Residential Property"); addMenu.add(newFrame2); JMenuItem newFrame3=new JMenuItem("Add Commercial Property"); addMenu.add(newFrame3); JMenu finishMenu = new JMenu("Finish"); bar.add(finishMenu); JDesktopPane theDesktop = new JDesktopPane(); add(theDesktop); JMenuItem writeItem = new JMenuItem("Write Owners"); finishMenu.add(writeItem); JMenuItem readpItem = new JMenuItem("Read Properties"); readMenu.add(readpItem); JMenuItem readoItem = new JMenuItem("Read Owners"); readMenu.add(readoItem); JMenuItem exitItem = new JMenuItem("Exit"); exitItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent event) { //System.exit(0); dispose(); } } ); finishMenu.add(exitItem); newFrame1.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { countFrames++; JInternalFrame jf = new JInternalFrame("Add Owner",true,true,true,true); theDesktop.add(jf); jf.setVisible(true); jf.pack(); jf.setSize(300,200); jf.setLocation(countFrames*10,countFrames*20); CustomPanel panel1 = new CustomPanel(); jf.add(panel1); } } ); newFrame2.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { countFrames++; JInternalFrame jf = new JInternalFrame("Add Residential Property",true,true,true,true); theDesktop.add(jf); jf.setVisible(true); jf.pack(); jf.setSize(300,200); jf.setLocation(countFrames*10,countFrames*20); CustomPanel panel2 = new CustomPanel(); jf.add(panel2); } } ); newFrame3.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { countFrames++; JInternalFrame jf = new JInternalFrame("Add Commercial Property",true,true,true,true); theDesktop.add(jf); jf.setVisible(true); jf.pack(); jf.setSize(300,200); jf.setLocation(countFrames*10,countFrames*20); CustomPanel panel3 = new CustomPanel(); jf.add(panel3); } } ); } class CustomPanel extends JPanel { JTextField tf1; JTextField tf2; JTextField tf3; JTextField tf4; JTextField tf5; JLabel label1; JLabel label2; JLabel label3; JLabel label4; JLabel label5; JLabel label6; JButton button1; public CustomPanel() { setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 1; gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets(2, 2, 2, 2); add(new JLabel("Name"), gbc); gbc.gridy++; add(new JLabel("Street"), gbc); gbc.gridy++; add(new JLabel("City"), gbc); gbc.gridy++; add(new JLabel("State"), gbc); gbc.gridy++; add(new JLabel("Zip"), gbc); gbc.gridy++; add(new JLabel("Submit when done"), gbc); JTextField[] fields = new JTextField[5]; gbc.gridx = 1; gbc.gridy = 0; gbc.weightx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; add((fields[0] = new JTextField(10)), gbc); gbc.gridy++; add((fields[1] = new JTextField(10)), gbc); gbc.gridy++; add((fields[2] = new JTextField(10)), gbc); gbc.gridy++; add((fields[3] = new JTextField(10)), gbc); gbc.gridy++; add((fields[4] = new JTextField(10)), gbc); gbc.gridy++; JButton btn = new JButton("Submit"); add(btn, gbc); } } } for commercial and residential property i just want to add two more text fields for account number and price before the submit button.

3 个答案:

答案 0 :(得分:1)

i do not qant the internal frame to be the same but unique for each menu item and that is where i am having trouble. CustomPanel panel1 = new CustomPanel(); ... CustomPanel panel2 = new CustomPanel(); ... CustomPanel panel3 = new CustomPanel(); Then you can't use the same panel. You need 3 different panels. You need: "OwnerPanel" "ResidentialPanel" "CommercialPanel" Don't try to for the internal frames to use the same panel if the data is different for each panel. //CustomPanel panel1 = new CustomPanel(); OwnerPanel panel1 = new OwnerPanel(); ... //CustomPanel panel2 = new CustomPanel(); ResidentialPanel panel2 = new ResidentialPanel(); ... //CustomPanel panel3 = new CustomPanel(); CommercialPanel panel3 = new CommercialPanel();

答案 1 :(得分:1)

因此,根据您的代码,每个菜单项都会创建相同的组件并将其添加到新的JInternalFrame,这显然不是您想要的,而是您希望每个菜单项都创建它根据需要自己观点。

有几种方法可以实现这一点,但由于所有这些方法的基本机制相同,因此您可以减少需要执行的复制粘贴操作的数量。

首先,首先定义您需要的实际视图/组件

public class AddOwnerPane extends JPanel {
    //...
}

public class AddResidentialPropertyPane extends JPanel {
    //...
}

public class AddCommercialPropertyPane extends JPanel {
    //...
}

我试图确定是否有任何可以在视图之间共享的公共属性,但是无法确定,但如果可以,您可以从其他视图中继承或定义“常见的“视图可以添加到其他视图中,以进一步减少代码重复。

当谈到这类问题时,你有两个基本的选择,你可以使用继承,你可以定义一个基类,其他所有人都可以从中扩展...

inheritance

或作文......

Composition

“共同”部分(实际上)是一个独立的类,但是你在另一个类中使用它。

在GUI中使用继承是棘手的,因为你需要处理布局(特别是)。这是有问题的,因为基础类布局可能具有非常特定的要求,如果搞砸了,则很快就会崩溃,使得添加新组件变得困难。基类可能也有自己定义的生命周期和管理期望,这也会使你的新需求变得棘手

在这些情况下,我通常会发现易于设计和管理的作品。

关于这个问题有很多讨论,例如:

因此,丢失有关该主题的信息,我将继续研究它

接下来,我们需要定义一个共同的动作,它可以完成大部分繁重的工作

public class ViewAction extends AbstractAction {

    private JDesktopPane desktop;
    private Class<? extends JComponent> view;

    public ViewAction(JDesktopPane desktop, Class<? extends JComponent> view) {
        this.desktop = desktop;
        this.view = view;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        try {
            countFrames++;
            JInternalFrame jf = new JInternalFrame("Add Owner", true, true, true, true);
            JComponent viewComponent = view.newInstance();
            jf.add(viewComponent);
            jf.pack();
            jf.setLocation(countFrames * 10, countFrames * 20);
            jf.setVisible(true);
            desktop.add(jf);
        } catch (InstantiationException | IllegalAccessException ex) {
            ex.printStackTrace();
        }
    }

}

这是基本Action,在触发时会创建JInternalFrame,初始化指定视图的新实例,将其添加到JInternalFrame并添加JInternalFrame到桌面窗格。

稍微不同的方法可能会让这个类成为abstract类,其abstract方法称为getViewComponent,它负责创建实际组件而不是Class#newInstance 1}},但是什么对你有用。

接下来,我们定义生成我们想要的视图所需的Action

public class AddOwnerAction extends ViewAction {

    public AddOwnerAction(JDesktopPane desktopPane) {
        super(desktopPane, AddOwnerPane.class);
        putValue(NAME, "Add Owner");
    }

}

public class AddResidentialPropertyAction extends ViewAction {

    public AddResidentialPropertyAction(JDesktopPane desktopPane) {
        super(desktopPane, AddResidentialPropertyPane.class);
        putValue(NAME, "Add Residential Property");
    }

}

public class AddCommercialPropertyAction extends ViewAction {

    public AddCommercialPropertyAction(JDesktopPane desktopPane) {
        super(desktopPane, AddCommercialPropertyPane.class);
        putValue(NAME, "Add Commercial Property");
    }

}

这些Action中的每一个都从ViewAction延伸,只是提供Class将创建并在其中设置各个属性的视图组件所需的Action引用。

最后,我们为每个动作创建JMenuItem ...

addMenu.add(new JMenuItem(new AddOwnerAction(theDesktop)));
addMenu.add(new JMenuItem(new AddResidentialPropertyAction(theDesktop)));
addMenu.add(new JMenuItem(new AddCommercialPropertyAction(theDesktop)));

基本上,我们定义了一系列自包含的工作单元,这减少了为每个操作添加不同视图组件所需的代码重复数量

有关详细信息,请查看How to Use Actions

答案 2 :(得分:0)

Since the panel for customer and residental property share the some common components, you can add a subclass of CustomerPanel for commercial and residential properties. This requires some refactoring of the CustomerPanel so that most of its code is reusable. For example, a setUpBaseLayout() to add the common components, a setUpCustomizedLayout() to add the additional components that commercial and residential Panel can extend, a setUpSubmitButton() which comes after the first two methods to add the submit button. class CustomPanel extends JPanel { JTextField tf1; JTextField tf2; JTextField tf3; JTextField tf4; JTextField tf5; JLabel label1; JLabel label2; JLabel label3; JLabel label4; JLabel label5; JLabel label6; JButton button1; GridBagConstraints gbc = new GridBagConstraints(); public void setUpBaseLayout() { setLayout(new GridBagLayout()); gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 1; gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets(2, 2, 2, 2); add(new JLabel("Name"), gbc); gbc.gridy++; add(new JLabel("Street"), gbc); gbc.gridy++; add(new JLabel("City"), gbc); gbc.gridy++; add(new JLabel("State"), gbc); gbc.gridy++; add(new JLabel("Zip"), gbc); JTextField[] fields = new JTextField[5]; gbc.gridx = 1; gbc.gridy = 0; gbc.weightx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; add((fields[0] = new JTextField(10)), gbc); gbc.gridy++; add((fields[1] = new JTextField(10)), gbc); gbc.gridy++; add((fields[2] = new JTextField(10)), gbc); gbc.gridy++; add((fields[3] = new JTextField(10)), gbc); gbc.gridy++; add((fields[4] = new JTextField(10)), gbc); } public void setUpCustomizedLayout() { } public CustomPanel() { setUpBaseLayout(); setUpCustomizedLayout(); setUpSubmitButton(); } private void setUpSubmitButton() { gbc.gridx = 0; gbc.gridy++; add(new JLabel("Submit when done"), gbc); gbc.gridx = 1; JButton btn = new JButton("Submit"); add(btn, gbc); } } class ResidentialPanel extends CustomPanel { ResidentialPanel() { super(); } public void setUpCustomizedLayout() { gbc.gridx = 0; gbc.gridy++; add(new JLabel("Account Number"), gbc); gbc.gridy++; add(new JLabel("Price"), gbc); gbc.gridx = 1; gbc.gridy--; add(new JTextField(10), gbc); gbc.gridy++; add(new JTextField(10), gbc); } } So for residential frame, you can use: CustomPanel panel2 = new ResidentialPanel(); jf.add(panel2);