gpt4 book ai didi

java - Java Swing 中带有自定义事件的接口(interface)之后的 .class

转载 作者:行者123 更新时间:2023-12-02 11:14:55 24 4
gpt4 key购买 nike

我正在学习 Java Swing,并且我发现了有关使用 MVC 和观察者模式的 Swing 的高级代码(在我看来)。这对我来说非常困难,我试图理解它。我有两个问题:

  1. DetailListener.class 到底有什么作用?这是我第一次在接口(interface)后使用.class。我尝试在 stackoverflow 上搜索“.class 语法”,我发现它可以在类(class)之后使用,但我仍然不明白它在这种情况下的作用。

  2. fireDetailEvent() 方法到底有什么作用?

提前致谢!

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class App {

public static void main(String args[]) {

SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {

JFrame frame = new MainFrame("Hello world Swing");
frame.setSize(500, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}

主机

import java.awt.BorderLayout;
import java.awt.Container;

import javax.swing.JFrame;
import javax.swing.JTextArea;

public class MainFrame extends JFrame {

private JTextArea textArea;

public MainFrame(String title) {

super(title);

Container c = getContentPane();

c.setLayout(new BorderLayout());

textArea = new JTextArea();

DetailsPanel detailsPanel = new DetailsPanel();

detailsPanel.addDetailListener(new DetailListener() {

public void detailEventOccurred(DetailEvent event) {

String text = event.getText();
textArea.append(text);
}
});

c.add(textArea, BorderLayout.CENTER);
c.add(detailsPanel, BorderLayout.WEST);
}
}

详细信息面板

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;
import javax.swing.event.EventListenerList;

public class DetailsPanel extends JPanel {

private static final long serialVersionUID = -5115286206114930420L;

private EventListenerList listenerList = new EventListenerList();

public DetailsPanel() {

Dimension size = getPreferredSize();
size.width = 250;
setPreferredSize(size);

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

JLabel nameLabel = new JLabel("Name:");
JLabel occupationLabel = new JLabel("Occupation:");

JTextField nameField = new JTextField(10);
JTextField occupationField = new JTextField(10);

JButton addBtn = new JButton("Add");

setLayout(new GridBagLayout());

GridBagConstraints gc = new GridBagConstraints();

////// First column /////
gc.anchor = GridBagConstraints.LINE_END;


gc.weightx = 0.5;
gc.weighty = 0.5;

gc.gridx = 0;
gc.gridy = 0;
add(nameLabel, gc);

gc.gridy = 1;
add(occupationLabel, gc);

////// Second column /////

gc.anchor = GridBagConstraints.LINE_START;

gc.gridx = 1;
gc.gridy = 0;
add(nameField, gc);

gc.gridy = 1;
add(occupationField, gc);

////// Final row /////

gc.anchor = GridBagConstraints.FIRST_LINE_START;
gc.weightx = 10;
gc.weighty = 10;
gc.gridy = 2;
add(addBtn, gc);

addBtn.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {

String name = nameField.getText();
String occupation = occupationField.getText();

String text = name + ": " + occupation + "\n";
System.out.println(text);

fireDetailEvent(new DetailEvent(this, text));

}
});
}

public void fireDetailEvent(DetailEvent event) {

Object[] listeners = listenerList.getListenerList();

for (int i = 0; i < listeners.length; i += 2) {

if (listeners[i] == DetailListener.class) {

((DetailListener)listeners[i+1]).detailEventOccurred(event);
}
}
}

public void addDetailListener(DetailListener listener) {

listenerList.add(DetailListener.class, listener);
}

public void removeDetailListener(DetailListener listener) {

listenerList.remove(DetailListener.class, listener);
}
}

详细监听器

import java.util.EventListener;

public interface DetailListener extends EventListener {

public void detailEventOccurred(DetailEvent event);
}

详细事件

import java.util.EventObject;

public class DetailEvent extends EventObject {

private String text;

public DetailEvent(Object source, String text) {

super(source);
this.text = text;
}

public String getText() {

return text;
}
}

最佳答案

1) DetailListener.class 到底做什么?

来自API :

Instances of the class Class represent classes and interfaces in a running Java application.

这有点令人困惑,所以让我们看一个例子。调用 DetailListener.class 提供其类表示形式。在这种具体情况下DetailListener.class提供Class<DetailListener>所以可以这样做:

Class<DetailListener> cdl = DetailListener.class;

cdl只是另一个变量,类似于 frame只是另一个变量。 frame恰好是 JFrame它提供了一些方法,而cdlClass<DetailListener>它提供了一组不同的方法。

cdl的类型是 Class<DetailListener>代表 DetailListener类。

但我仍然不明白它在这种情况下会做什么

考虑这段代码:

listenerList.add(DetailListener.class, listener);

listenerList类型为EventListenerList 。据其APIadd(...)方法参数需要一个 Class 和一个 T 实例。在本例中,通用 T 是 DetailListener。到目前为止,监听器已注册,但这会引出您的下一个问题。

#2 fireDetailEvent() 方法到底做什么?

当监听器注册时 listenerList保留一个内部数组,稍后可以引用。该数组包含类和实际的监听器实例。所以调用

Object[] listeners = listenerList.getListenerList();

提供对数组的访问。在这种情况下:

listeners[0] = DetailListener.class
listeners[1] = reference to the anonymous inner class instance created from detailsPanel.addDetailListener(...)

所以 fireDetailEvent(...) 中的循环保证是 2 的倍数(如果没有注册监听器,0 也有效)。但是listenerList可以容纳任何类型的听众,所以

if (listeners[i] == DetailListener.class) {

使用类来检查是否相等,以确保种姓能够安全地通过 DetailEvent到监听器(这是数组中的下一个元素)。使用== (而不是 .equals() )在这种情况下是可以的,因为 DetailListener.class 始终提供相同的类。

关于java - Java Swing 中带有自定义事件的接口(interface)之后的 .class,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50354666/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com