Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 杰帕内尔在不同的班级,是我做的不好吗?为什么?_Java_Swing_User Interface_Event Handling_Jpanel - Fatal编程技术网

Java 杰帕内尔在不同的班级,是我做的不好吗?为什么?

Java 杰帕内尔在不同的班级,是我做的不好吗?为什么?,java,swing,user-interface,event-handling,jpanel,Java,Swing,User Interface,Event Handling,Jpanel,我创建了一个扩展JFrame的新类和一个扩展JPanel的新类,以制作swing GUI。这是伟大的,我喜欢这是因为它的易读性 然而,当涉及到事件处理时,事情开始变得复杂起来。我所做的看起来并不是一个真正的解决方案;就像打破好习惯让某些事情成功一样。我如何使其正常工作 这是我的JFrame课程 public class MainFrame extends JFrame{ private JTextArea textArea; public MainFrame(String ti

我创建了一个扩展JFrame的新类和一个扩展JPanel的新类,以制作swing GUI。这是伟大的,我喜欢这是因为它的易读性

然而,当涉及到事件处理时,事情开始变得复杂起来。我所做的看起来并不是一个真正的解决方案;就像打破好习惯让某些事情成功一样。我如何使其正常工作

这是我的JFrame课程

public class MainFrame extends JFrame{
    private JTextArea textArea;

    public MainFrame(String title){
        super(title);

        //set layout
        setLayout(new BorderLayout());

        //create components
        JButton buttonOne = new JButton("click me");
        textArea = new JTextArea();
        JPanel detailedPanel = new leftPanel();

        //add to panel
        Container c = getContentPane();

        c.add(buttonOne, BorderLayout.SOUTH);
        c.add(textArea, BorderLayout.CENTER);
        c.add(detailedPanel, BorderLayout.WEST);

        //Event Listening
        leftPanel.buttonAdd.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                textArea.setText(textArea.getText() + " " + leftPanel.fieldName.getText() + " : " + leftPanel.fieldOccupation.getText());
            }

        });

    }

}
这是我的JPanel

public class leftPanel extends JPanel {

    public static JTextField fieldName;
    public static JTextField fieldOccupation;
    public static JButton buttonAdd;

    public leftPanel(){
        Dimension panelSize = getPreferredSize();
        panelSize.width = 250;
        setPreferredSize(panelSize);

        setBorder(BorderFactory.createTitledBorder("Personal Info"));

        //labels
        JLabel labelName = new JLabel("name: ");
        JLabel labelOccupation = new JLabel("Occupation: ");

        //textFields
        fieldName = new JTextField(10);
        fieldOccupation = new JTextField(10);

        //buttons
        buttonAdd = new JButton("Add !");

        //actions
        buttonAdd.addActionListener(new ActionListener(){
            //on click
            public void actionPerformed(ActionEvent e) {
                String name = fieldName.getText();
                String occupation = fieldOccupation.getText();

                System.out.print(name + ": " + occupation);                    
            }    
        });

        setLayout(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();

        //// First Y  add //////////////////////////////////////

        //label NAME
        gbc.anchor = GridBagConstraints.FIRST_LINE_END;
        gbc.weightx = 1;
        gbc.weighty = 1;
        gbc.gridx = 0;
        gbc.gridy = 0;
        add(labelName, gbc);

        //label Occupation
        gbc.anchor = GridBagConstraints.FIRST_LINE_END;
        gbc.weightx = 1;
        gbc.weighty = 1;
        gbc.gridx = 0;
        gbc.gridy = 1;
        add(labelOccupation, gbc);

        //// SECOND Y add /////////////////////////////////////  

        //text field name
        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
        gbc.weightx = 2;
        gbc.weighty = 1;
        gbc.gridx = 1;
        gbc.gridy = 0;
        add(fieldName, gbc);

        //text feld occupation
        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
        gbc.weightx = 2;
        gbc.weighty = 1;
        gbc.gridx = 1;
        gbc.gridy = 1;
        add(fieldOccupation, gbc);

        //// THIRD Y add //////////////////////////////////////

        //add button
        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
        gbc.gridx = 1;
        gbc.gridy = 3;
        gbc.weightx = 1;
        gbc.weighty = 10;
        add(buttonAdd, gbc); 
    }
}

在大多数情况下,您的组件应该尽可能自包含,这意味着该组件应该负责处理由其直接子级生成的事件

这并不意味着组件不会生成它自己的事件,而是意味着组件管理它自己的直接子级

您应该尽量避免直接(使用
public
字段或
getters
)或间接(通过事件对象)暴露子组件,这可能会导致外部源误用这些组件,这永远不会令人愉快

在您的示例中,第一个类只想知道何时发生了需要它更新文本区域的事情

这表明
LeftPanel
需要生成某种类型的事件(可能是
ActionEvent
),并为可能有兴趣访问
LeftPanel
正在管理的信息的任何人提供
getter

例如

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class LeftPanel extends JPanel {

    private JTextField fieldName;
    private JTextField fieldOccupation;
    private JButton buttonAdd;

    public LeftPanel() {

        setBorder(BorderFactory.createTitledBorder("Personal Info"));

        //labels
        JLabel labelName = new JLabel("name: ");
        JLabel labelOccupation = new JLabel("Occupation: ");

        //textFields
        fieldName = new JTextField(10);
        fieldOccupation = new JTextField(10);

        //buttons
        buttonAdd = new JButton("Add !");

        //actions
        buttonAdd.addActionListener(new ActionListener() {
            //on click
            public void actionPerformed(ActionEvent e) {
                fireActionPerformed();
            }
        });

        setLayout(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();

        //// First Y  add //////////////////////////////////////
        //label NAME
        gbc.anchor = GridBagConstraints.FIRST_LINE_END;
        gbc.weightx = 1;
        gbc.weighty = 1;
        gbc.gridx = 0;
        gbc.gridy = 0;
        add(labelName, gbc);

        //label Occupation
        gbc.anchor = GridBagConstraints.FIRST_LINE_END;
        gbc.weightx = 1;
        gbc.weighty = 1;
        gbc.gridx = 0;
        gbc.gridy = 1;
        add(labelOccupation, gbc);

        //// SECOND Y add /////////////////////////////////////  
        //text field name
        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
        gbc.weightx = 2;
        gbc.weighty = 1;
        gbc.gridx = 1;
        gbc.gridy = 0;
        add(fieldName, gbc);

        //text feld occupation
        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
        gbc.weightx = 2;
        gbc.weighty = 1;
        gbc.gridx = 1;
        gbc.gridy = 1;
        add(fieldOccupation, gbc);

        //// THIRD Y add //////////////////////////////////////
        //add button
        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
        gbc.gridx = 1;
        gbc.gridy = 3;
        gbc.weightx = 1;
        gbc.weighty = 10;
        add(buttonAdd, gbc);

    }

    public void addActionListener(ActionListener listener) {
        listenerList.add(ActionListener.class, listener);
    }

    public void removeActionListener(ActionListener listener) {
        listenerList.remove(ActionListener.class, listener);
    }

    protected void fireActionPerformed() {
        ActionListener[] listeners = listenerList.getListeners(ActionListener.class);
        if (listeners.length > 0) {
            ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "PropertiesSet");
            for (ActionListener listener : listeners) {
                listener.actionPerformed(evt);
            }
        }
    }

    public String getPersonName() {
        return fieldName.getText();
    }

    public String getPersonOccupation() {
        return fieldOccupation.getText();
    }

}
此处的
LeftPanel
现在管理其组件的内部状态(无
static
public
字段)。它还提供了一个
ActionListener
支持,向相关方提供通知,这些相关方可以通过getter获取组件正在管理的信息

然后,
MainFrame
只需使用
LeftPanel
的一个实例,并向其注册一个
ActionListener
,以便在面板更新时通知它,并使用getter获取它感兴趣的信息

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;

public class MainFrame extends JFrame {

    private JTextArea textArea;

    public MainFrame(String title) {
        super(title);

        //set layout
        setLayout(new BorderLayout());

        //create components
        JButton buttonOne = new JButton("click me");
        textArea = new JTextArea();
        LeftPanel detailedPanel = new LeftPanel();

        //add to panel
        Container c = getContentPane();

        c.add(buttonOne, BorderLayout.SOUTH);
        c.add(textArea, BorderLayout.CENTER);
        c.add(detailedPanel, BorderLayout.WEST);

        //Event Listening
        detailedPanel.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                textArea.append(textArea.getText() + " " + detailedPanel.getPersonName() + " : " + detailedPanel.getPersonOccupation() + "\n");
            }

        });

    }

}

在OO中,您希望将逻辑和责任封装到对象中,然后根据需要从回调(如a)发出通知,通知相关方某些预定义状态已更改。然后只需通过getter公开对象正在管理的信息(如果需要,还可以通过setter让其他人根据需要更改信息)

offtopic。。。用大写字母命名班级是一个很好的做法
public class leftPanel
可以是
public class leftPanel
而且,
static
在这里不是您的朋友,它不是跨对象通信机制,不应该以这种方式使用