[英].class after an Interface with Custom Events in Java Swing
我正在學習Java Swing,並且發現了使用MVC和Observer模式的關於Swing的高級代碼。 這對我來說非常困難,我試圖理解它。 我有兩個問題:
DetailListener.class到底是什么? 這是我第一次在接口后使用.class。 我試圖搜索有關“ .class語法”的stackoverflow,但我發現它可以在使用一個類后使用,但是我仍然不了解它在這種情況下的作用。
方法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);
}
}
DetailsPanel
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);
}
}
DetailListener
import java.util.EventListener;
public interface DetailListener extends EventListener {
public void detailEventOccurred(DetailEvent event);
}
DetailEvent
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中 :
類Class的實例表示正在運行的Java應用程序中的類和接口。
這有點令人困惑,所以讓我們看一個例子。 調用DetailListener.class提供其Class表示形式。 在這種特定情況下, DetailListener.class
提供了一個Class<DetailListener>
因此可以執行以下操作:
Class<DetailListener> cdl = DetailListener.class;
cdl
只是另一個變量,類似於frame
只是另一個變量。 frame
恰好是提供某些方法的JFrame
,而cdl
是提供不同方法集的Class<DetailListener>
。
cdl
的類型是Class<DetailListener>
,它表示DetailListener
類。
但我仍然不明白在這種情況下它會做什么
考慮以下代碼:
listenerList.add(DetailListener.class, listener);
listenerList
的類型為EventListenerList
。 根據其API , add(...)
方法參數需要一個Class和一個T實例。 在這種情況下,通用T為DetailListener。 到目前為止,聽眾已經注冊,但是它會引出您的下一個問題。
#2 fireDetailEvent()方法到底是什么?
注冊listenerList
器后, listenerList
會保留一個內部數組,以后可以引用該數組。 該數組同時包含Class和實際的偵聽器實例。 如此調用
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) {
使用Class檢查是否相等,以確保能夠安全地進行等級傳遞,以便能夠將DetailEvent
傳遞給偵聽器(這是數組中的下一個元素)。 在這種情況下,可以使用==
(而不是.equals()
),因為DetailListener.class始終提供相同的Class。
DetailListener.class
到底是DetailListener.class
?
DetailListener.class
是所謂的類文字。 基本上,它是Class
類型的常量,表示DetailListener
類型。
您可以在Java什么是類文字中找到更多更好的解釋。 及其答案。
方法
fireDetailEvent()
到底是什么?
您的DetailsPanel
類使用EventListenerList
來處理事件偵聽器並將事件發送給他們。
類EventListenerList中給出的注釋詳細說明了如何使用它。 仔細閱讀本說明,你會認識到,這些方法addDetailListener
, removeDetailListener
和fireDetailEvent
類的DetailsPanel
寫這正好說明如下。
該方法fireDetailEvent
觸發一個DetailEvent
所有那些已經由早期注冊自己的聽眾addDetailListener
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.