Mam ramkę JF Java zawierającą JPanel. W ramach tego JPanel istnieją dwa oddzielne JPanele. Kiedy użytkownik kliknie przycisk w pierwszym JPanelu, wiadomość musi zostać wysłana do innego JPanel informującego, który przycisk został kliknięty. Jaki jest najłatwiejszy sposób wysyłania wiadomości między takimi obiektami?Wysyłanie wiadomości między dwoma obiektami JPanel
Odpowiedz
Dla mKorbel (i ich twórców):
Co ja polecając jest luźniejsza sprzęgło, że jeden JPanel nie ma wiedzy na temat innego JPanel i że wszystkie połączenia są wykonywane za pośrednictwem kontrola jakiegoś rodzaju. Na przykład, aby pożyczyć trochę swojego kodu:
CopyTextNorthPanel2.java
import java.awt.*;
import javax.swing.*;
public class CopyTextNorthPanel2 extends JPanel {
private static final long serialVersionUID = 1L;
public JTextField northField;
public CopyTextNorthPanel2() {
northField = new JTextField("Welcome World");
northField.setFont(new Font("Serif", Font.BOLD, 20));
northField.setPreferredSize(new Dimension(300, 25));
add(northField);
}
public String getNorthFieldText() {
return northField.getText();
}
}
CopyTextSouthPanel2.java
import java.awt.event.*;
import javax.swing.*;
public class CopyTextSouthPanel2 extends JPanel {
private static final long serialVersionUID = 1L;
private JTextField firstText = new JTextField("Desired TextField");
private JButton copyButton = new JButton("Copy text from JTextFields");
private CopyTextControl2 control;
public CopyTextSouthPanel2() {
copyButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (control != null) {
control.copyAction();
}
}
});
add(firstText);
add(copyButton);
}
public void setControl(CopyTextControl2 control) {
this.control = control;
}
public void setFirstText(String text) {
firstText.setText(text);
}
}
CopyTextControl2.java
public class CopyTextControl2 {
private CopyTextNorthPanel2 northPanel;
private CopyTextSouthPanel2 southPanel;
public void copyAction() {
if (northPanel != null && southPanel != null) {
southPanel.setFirstText(northPanel.getNorthFieldText());
}
}
public void setNorthPanel(CopyTextNorthPanel2 northPanel) {
this.northPanel = northPanel;
}
public void setSouthPanel(CopyTextSouthPanel2 southPanel) {
this.southPanel = southPanel;
}
}
CopyText2.java
import java.awt.*;
import javax.swing.*;
public class CopyText2 {
private static void createAndShowUI() {
CopyTextNorthPanel2 northPanel = new CopyTextNorthPanel2();
CopyTextSouthPanel2 southPanel = new CopyTextSouthPanel2();
CopyTextControl2 control = new CopyTextControl2();
southPanel.setControl(control);
control.setNorthPanel(northPanel);
control.setSouthPanel(southPanel);
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.add(northPanel, BorderLayout.NORTH);
mainPanel.add(Box.createRigidArea(new Dimension(100, 100)), BorderLayout.CENTER);
mainPanel.add(southPanel, BorderLayout.SOUTH);
JFrame frame = new JFrame("Copy Text");
frame.getContentPane().add(mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
Można utworzyć zdarzenie niestandardowe i dołączyć do niego co najmniej jednego detektora.
Właściwy sposób implementacji polega na tym, że Button ActionListener wywołuje zdarzenie, a następnie dwa panele są odbiorcami tego zdarzenia.
na szczycie swojej klasy
public MyClass implements ActionListener {
...
myButton.addActionListener(this);
...
public void actionPerformed(ActionEvent e) {
//for example if you have more than one events that you need to handle
if(e.getSource().equals(myButton) {
//update your do some work on you jpanels
}
}
Ale naprawdę, myślę, że nadszedł czas, aby zacząć myśleć o wzorcach projektowych. Co opisujesz jest idealnym kandydatem na wzór observer i ewentualnie command wzór
na przykład za pomocą pośredników Konstruktor klasy lub (dla debuging wystawienia) wyodrębnić wartość od pożądanego JComponent
(ów) za pomocą getParent()
import java.awt.*;
import javax.swing.*;
public class CopyTextFrame extends JFrame {
private static final long serialVersionUID = 1L;
private CopyTextNorthPanel northPanel;
private CopyTextCenterPanel centerPanel;
private CopyTextSouthPanel southPanel;
public void makeUI() {
northPanel = new CopyTextNorthPanel();
centerPanel = new CopyTextCenterPanel();
southPanel = new CopyTextSouthPanel();
northPanel.setName("northPanel");
centerPanel.setName("centerPanel");
southPanel.setName("southPanel");
centerPanel = new CopyTextCenterPanel();
centerPanel.setPreferredSize(new Dimension(300, 40));
southPanel = new CopyTextSouthPanel();
southPanel.setSourceTextField(northPanel.desText);
northPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
centerPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
southPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
setLayout(new BorderLayout(5, 5));
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(northPanel, BorderLayout.NORTH);
add(centerPanel, BorderLayout.CENTER);
add(southPanel, BorderLayout.SOUTH);
pack();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new CopyTextFrame().makeUI();
}
});
}
}
+
import javax.swing.*;
public class CopyTextCenterPanel extends JPanel {
private static final long serialVersionUID = 1L;
public CopyTextCenterPanel() {
}
}
+
import java.awt.*;
import javax.swing.*;
public class CopyTextNorthPanel extends JPanel {
private static final long serialVersionUID = 1L;
public JTextField desText;
public CopyTextNorthPanel() {
desText = new JTextField("Welcome World");
desText.setFont(new Font("Serif", Font.BOLD, 20));
desText.setPreferredSize(new Dimension(300, 25));
desText.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
desText.addComponentListener(null);
desText.setName("desText");
add(desText);
}
public JTextField getDesText() {
return desText;
}
}
+
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class CopyTextSouthPanel extends JPanel {
private static final long serialVersionUID = 1L;
private JTextField firstText;
private JButton copyButton;
private JTextField sourceTextField;
private String lds = "";
public CopyTextSouthPanel() {
firstText = new JTextField("Desired TextField");
firstText.setMinimumSize(new Dimension(300, 25));
firstText.setPreferredSize(new Dimension(300, 25));
firstText.setMaximumSize(new Dimension(300, 25));
copyButton = new JButton("Copy text from JTextFields");
copyButton.setMinimumSize(new Dimension(200, 25));
copyButton.setPreferredSize(new Dimension(200, 25));
copyButton.setMaximumSize(new Dimension(200, 25));
copyButton.addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
copyButtonActionPerformed(evt);
}
private void copyButtonActionPerformed(ActionEvent evt) {
System.out.print("Button pressed" + "\n");
Component[] comp = CopyTextSouthPanel.this.getParent().getComponents();
int nO = comp.length;
for (int i = 0; i < comp.length; ++i) {
if (comp[i] instanceof JPanel) {
String name = ((JPanel) comp[i]).getName();
if (name.equals("northPanel")) {
JPanel panel = (JPanel) comp[i];
Component[] comp1 = panel.getComponents();
int nO1 = comp1.length;
for (int ii = 0; ii < comp1.length; ++ii) {
if (comp1[ii] instanceof JTextField) {
String name1 = ((JTextField) comp1[ii]).getName();
if (!(name1 == null)) {
if (name1.equals("desText")) {
JTextField text = (JTextField) comp1[ii];
String str = text.getText();
firstText.setText(str);
System.out.print("set value -> " + str + "\n");
break;
}
}
}
}
break;
}
}
}
lds = sourceTextField.getText();
if (lds != null || (!(lds.isEmpty()))) {
firstText.setText(" Msg -> " + lds);
}
}
});
add(firstText, BorderLayout.EAST);
add(copyButton, BorderLayout.WEST);
}
public void setSourceTextField(JTextField source) {
this.sourceTextField = source;
}
}
Twarde kodowanie polega na uzyskaniu odwołania do jednego z paneli, który wydaje się być dość kruche rozwiązanie. O wiele lepiej jest sprawić, aby oba JPanels nie znały się nawzajem i używały słuchaczy zgodnie z innymi odpowiedziami. –
@ Poduszkowiec pełen węgorzy w zależności od twoich komentarzy ciężko jest powiedzieć coś mądrego, Konstruktor i ostatecznie także Getter/Setter są zakodowane na sztywno, i myślę, że oba są nadal uważane za podstawowe rzeczy dla JComponents, dla mnie jest to ten sam wspaniały sposób tworzenia Klasy obiektu w przypadku, gdy coś złego dzieje się na każdym połączeniu – mKorbel
, zobacz moją odpowiedź, aby zrozumieć, co mam na myśli. –
- 1. Wysyłanie wiadomości między komputerami
- 2. Wykrywanie kolizji Java między dwoma obiektami Shape?
- 3. Wysyłanie zdarzenia między dwoma oknami WPF
- 4. Wysyłanie wiadomości między wątkami klas Python
- 5. jak obliczyć różnicę między dwoma obiektami Zend_Date, w miesiącach
- 6. Uzyskiwanie różnicy między dwoma obiektami o tych samych właściwościach
- 7. Schemat DTO: Najlepszy sposób na kopiowanie właściwości między dwoma obiektami
- 8. Ograniczenia dla środka i obiektu między dwoma obiektami
- 9. Jak uzyskać wszystkie punkty między dwoma obiektami Point?
- 10. Potrzebuję obliczyć upływ czasu między dwoma obiektami daty
- 11. Rysowanie strzałki na płótnie HTML5 między dwoma obiektami
- 12. W ulotce, jak obliczyć odległość pikseli między dwoma obiektami LatLng?
- 13. Uzyskaj liczbę dni między dwoma różnymi obiektami DateTime
- 14. Wysyłanie dużych ilości danych między dwoma programami C#
- 15. Python: wysyłanie danych między dwoma komputerami za pośrednictwem gniazd
- 16. Wysyłanie wiadomości "w imieniu"
- 17. Wysyłanie wiadomości e-mail
- 18. Czy mogę otrzymać ostrzeżenia dotyczące wysyłania wiadomości z pustymi obiektami?
- 19. Komunikacja między dwoma wątkami
- 20. Łączenie DQL między niepowiązanymi obiektami?
- 21. Wysyłanie wiadomości e-mail - MFMailComposeResult
- 22. wysyłanie wiadomości z pliku wsadowego
- 23. Wysyłanie wiadomości do unikalnego gniazda
- 24. Wysyłanie wiadomości Firebase NoSuchMethodError.zzUr wyjątek
- 25. Różnica między obiektami podlegającymi modyfikacji a obiektami niezmiennymi
- 26. Korelacja między dwoma wektorami?
- 27. Połączenie między dwoma użytkownikami
- 28. Jak mogę wysłać ciągi między dwoma komputerami?
- 29. Przenieść Konstruktora, przenieść wektor między dwoma obiektami za pomocą std :: move?
- 30. Synchronizacja/wysyłanie danych między wątkami
dziękuję, bez baterii w zestawie, nadal mogę zobaczyć to samo w mojej strefie czasowej jest więcej niż 2 godziny po północy, czas spać +1 – mKorbel
@mKorbel: dobranoc i dobry wypoczynek! –
dzięki za lekcję, w przypadku, gdy jest więcej niż jedno połączenie, to lepiej ... – mKorbel