Java 杰帕内尔在不同的班级,是我做的不好吗?为什么?
我创建了一个扩展JFrame的新类和一个扩展JPanel的新类,以制作swing GUI。这是伟大的,我喜欢这是因为它的易读性 然而,当涉及到事件处理时,事情开始变得复杂起来。我所做的看起来并不是一个真正的解决方案;就像打破好习惯让某些事情成功一样。我如何使其正常工作 这是我的JFrame课程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
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
在这里不是您的朋友,它不是跨对象通信机制,不应该以这种方式使用