我正在處理我的聊天項目。我編寫了沒有GUI的服務器和客戶端,只是控制檯UI。現在,在處理客戶端GUI(使用Netbeans提供的工具,而不是我自己編寫的代碼)時,我堅持了綁定問題。將Swing GUI組件的屬性綁定到自定義類方法(屬性)
裏面的ClientGui
class我有Client
對象。在我的GUI中,我希望禁用輸入文本字段,直到客戶端未連接到聊天服務器。我試圖綁定(通過Netbeans GUI)我的輸入文本框的屬性啓用該客戶端對象的方法isConnected()
(返回boolean
)。 isConnected
不只是返回某個變量的值,而是組合的布爾表達式。所以當用戶單擊連接時,它會成功,但輸入文本字段不會將其狀態更改爲啓用狀態。
因此,當我得到它,我必須與事件和聽衆合作,並在我的Client
類中通知?但是,那麼綁定點又是什麼呢,因爲我可以在我的Client
上觸發事件,並且我的輸入字段可以偵聽客戶端連接的事件?
所以我提供了我的代碼塊。
的Client
類:(您可能會看到行動的聽衆和事件的某些行,我沒有刪除它們,只是試行)
public class Client {
private ClientListener listener;
private ClientSender sender;
private Socket connection;
private boolean finnish = false;
private PropertyChangeEvent connected;
public Client(String hostname, int port) throws UnknownHostException, IOException {
connection = new Socket(hostname, port);
}
public void start() {
try {
connected = new PropertyChangeEvent(this, "connected", null, connection);
sender = new ClientSender(new ObjectOutputStream(connection.getOutputStream()));
Thread senderThread = new Thread(sender);
senderThread.start();
Logger.getLogger(Client.class.getName()).log(Level.INFO, "Sender thread has started");
listener = new ClientListener(new ObjectInputStream(connection.getInputStream()));
Thread listenerThread = new Thread(listener);
listenerThread.start();
Logger.getLogger(Client.class.getName()).log(Level.INFO, "Listener thread has started");
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, "IO problems", ex);
}
}
public ClientSender getSender() {
return sender;
}
public void stop() {
sender.stop();
listener.stop();
}
public boolean isConnected() {
return connection != null && !connection.isClosed();
}
}
的Client
GUI類:
public class ClientGui extends javax.swing.JFrame {
private Client client;
public boolean getConnected() {
System.out.println(client != null && client.isConnected());
return client != null && client.isConnected();
}
/**
* Creates new form ClientGui
*/
public ClientGui() {
initComponents();
}
// GENERATED CODE
private void tfUserInputKeyPressed(java.awt.event.KeyEvent evt) {
if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
Message message = new Message("user", tfUserInput.getText());
client.getSender().add(message);
tfUserInput.setText("");
}
}
private void btnConnectActionPerformed(java.awt.event.ActionEvent evt) {
try {
client = new Client(tfHostname.getText(), Integer.parseInt(tfPort.getText()));
client.start();
} catch (UnknownHostException ex) {
Logger.getLogger(ClientGui.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(ClientGui.class.getName()).log(Level.SEVERE, null, ex);
}
}
// and somewhere GUI generated code of my binding (also tried with custom code, but no success)
org.jdesktop.beansbinding.Binding binding =
org.jdesktop.beansbinding.Bindings.createAutoBinding
(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ, this,
org.jdesktop.beansbinding.ELProperty.create("${connected}"), listConversation,
org.jdesktop.beansbinding.BeanProperty.create("enabled"), "listConversationBinding");
bindingGroup.addBinding(binding);
事實上,這是一個JList
,但沒關係,因爲我想要這樣的綁定少數組件。 在這裏,我嘗試在GUI窗體中使用僞造方法,該窗體調用客戶端連接(這是因爲不知道如何將Client
作爲組件添加)。
我在論壇上看到過,每處都有關於豆類的說法等等。我希望我的Client
類具有儘可能少的GUI所需的代碼,接口實現和調用事件觸發事件等。
UPDATE
非常好!謝謝。爲什麼我不能綁定,所以我不必使用setEnabled(value)
方法(使該屬性能夠跟蹤布爾表達式「屬性」(connection != null && !connection.isClosed()
)。另外,由於這個技巧,我必須做setConnected(value)
,即使解決了這個問題在運行時取決於連接,我什至不知道舊值(當然,我可以做私人無效setConnected(booleanvalue)
,並根據在這些地方發生的事情真正或假的調用。似乎我的使用財產的想法是錯了,最好在GU用行動或事件做。
謝謝!請檢查我的第一篇文章中的更新,以下是一些問題:) – EEE 2012-08-17 20:11:59
這不是在GUI設計模式下使用NetBeans IDE的屬性。它只是一個bean屬性。該bean是'Client',該屬性已連接。看看這個http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html#bound'setConnected'修改屬性的真實值,所以它被激發了事件。舊值是事件發生前的值。只要你使用線程,你可能想使用'SwingWorker'而不是'PropertyChangeSupport'。 – 2012-08-17 20:42:03
非常感謝羅馬! – EEE 2012-08-18 07:39:08