在JavaSwing中处理来自复合组件的事件

col17t5w  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(413)

我制作了一个桌面应用程序来处理一些web服务的配置,它可以工作,但是代码很难维护,因为所有de-logic视图都在同一个类(主类)中,所以我决定重做它,并应用mvc架构和react哲学将复杂的应用程序拆分为简单的、可重用的组件。我最终得到的结果是:

我的应用程序有 JFrame 有一个主要的 JPanel ,此主 JPanel 有很多其他的 JPanel 但是主电源是 centerJPanel 以及 SaveJPanel 用于演示目的。centerjpanel有我的复合组件(蓝色矩形)contenedorswtbtn。
我的对手包括 JPanel , JLabel 对于标题和switchtogglebtn组件,我可以有任意多个switchtogglebtn,因为我的想法是动态添加它们。

我的switchtogglebtn由一个 JPanel , JLabel 名字,还有 JToggleButton .

mycomponent:switchtogglebtn的代码(很抱歉是西班牙语):

  1. public class SwitchToggleBtn extends JPanel
  2. {
  3. private JToggleButton SwtBtn;
  4. private JLabel nombLogs;
  5. private String Name;
  6. public SwitchToggleBtn(String Nombre, boolean bandera)
  7. {
  8. super(new BorderLayout(10,10));
  9. this.Name = Nombre;
  10. this.setBackground(new java.awt.Color(255, 255, 255));
  11. this.setBorder( new EmptyBorder( 5, 5, 5, 12));
  12. this.setBorder(javax.swing.BorderFactory.createMatteBorder(1, 1, 1, 1, new java.awt.Color(153, 153, 153)));
  13. this.nombLogs = new JLabel(Nombre);
  14. this.nombLogs.setFont(new java.awt.Font("Segoe UI Symbol", 0, 14));
  15. this.add(nombLogs, BorderLayout.WEST);
  16. this.SwtBtn = new JToggleButton();
  17. this.SwtBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/principal/icon/btnToggleOff.png"))); // NOI18N
  18. this.SwtBtn.setBorder(null);
  19. this.SwtBtn.setBorderPainted(false);
  20. this.SwtBtn.setContentAreaFilled(false);
  21. this.SwtBtn.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
  22. this.SwtBtn.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/principal/icon/btnToggleOffDisabled.png"))); // NOI18N
  23. this.SwtBtn.setDisabledSelectedIcon(new javax.swing.ImageIcon(getClass().getResource("/principal/icon/btnToggleOnDisable.png"))); // NOI18N
  24. this.SwtBtn.setFocusPainted(false);
  25. this.SwtBtn.setMaximumSize(new java.awt.Dimension(70, 34));
  26. this.SwtBtn.setMinimumSize(new java.awt.Dimension(70, 34));
  27. this.SwtBtn.setPreferredSize(new java.awt.Dimension(70, 34));
  28. this.SwtBtn.setSelected(bandera);
  29. this.SwtBtn.setName(Nombre);
  30. IsSelected();
  31. this.SwtBtn.addActionListener(new ActionListener() {
  32. @Override
  33. public void actionPerformed(ActionEvent e) {
  34. IsSelected();
  35. }
  36. });
  37. this.add(SwtBtn, BorderLayout.EAST);
  38. this.addMouseListener(new java.awt.event.MouseAdapter() {
  39. public void mouseClicked(java.awt.event.MouseEvent evt) {
  40. mouseclicked(evt);
  41. }
  42. });
  43. }
  44. private void IsSelected()
  45. {
  46. if (this.SwtBtn.isSelected())
  47. this.SwtBtn.setIcon(new ImageIcon(getClass().getResource("/principal/icon/btnToggleOn.png")));
  48. else
  49. this.SwtBtn.setIcon(new ImageIcon(getClass().getResource("/principal/icon/btnToggleOff.png")));
  50. }
  51. }

上下文WTBTN的代码(很抱歉是西班牙语):

  1. public class ContenedorSwtBtn extends JPanel
  2. {
  3. public ContenedorSwtBtn(String Nombre)
  4. {
  5. super();
  6. this.setBackground(new java.awt.Color(255, 255, 255));
  7. this.setBorder(javax.swing.BorderFactory.createMatteBorder(1, 1, 1, 1, new java.awt.Color(153, 153, 153)));
  8. this.setToolTipText("");
  9. this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
  10. JLabel titulo = new JLabel();
  11. titulo.setBackground(new java.awt.Color(0, 0, 0));
  12. titulo.setFont(new java.awt.Font("Dialog", 1, 14)); // NOI18N
  13. titulo.setForeground(new java.awt.Color(0, 51, 51));
  14. titulo.setText(Nombre);
  15. titulo.setAlignmentX(Component.CENTER_ALIGNMENT);
  16. this.add(titulo);
  17. }
  18. public void AddComponent(String nombreLog, boolean bandera)
  19. {
  20. SwitchToggleBtn log = new SwitchToggleBtn(nombreLog, bandera);
  21. this.add(log);
  22. }
  23. }

这是最终结果:

当我单击swichtogglebtn组件中的jtogglebutton时,它会改变他的状态,并将图标从off更改为on,反之亦然。
最后是创建新组件并将其添加到主jpanel中,如下所示:

  1. JPanel MainPanel= new JPanel();
  2. MainPanel.setBackground(new java.awt.Color(255, 255, 255));
  3. MainPanel.setEnabled(true);
  4. MainPanel.setMaximumSize(new java.awt.Dimension(300, 280));
  5. MainPanel.setMinimumSize(new java.awt.Dimension(300, 280));
  6. MainPanel.setPreferredSize(new java.awt.Dimension(300, 280));
  7. MainPanel.setVisible(true);
  8. ContenedorSwtBtn myComponent= new ContenedorSwtBtn("SETTINGS");
  9. myComponent.AddComponent("ONE", true);
  10. myComponent.AddComponent("TWO", false);
  11. myComponent.AddComponent("THREE",true);
  12. MainPanel.add(myComponent);

当我点击jtogglebutton并改变它的状态时,我想要确切的组件和它的当前状态,但是从主jpanel或中心面板,这样我就可以“保存更改”(savejpanel中的红色按钮)并实现一些逻辑来保存配置。如何将事件从子组件传递到父组件,或者如何从父组件知道子组件何时更改其状态。我读过关于创建一个实现actionlistener接口或实现propertychangeslistener接口的类,但我不明白。非常感谢你的帮助。

x7rlezfr

x7rlezfr1#

我不确定你想做什么,因为你的问题与mvc有任何关系(例如mvc swing应用程序的一个例子,请看这里),因为我可以告诉你,你真正需要的是从自定义控件中弹出事件,这样你就可以注册以在主面板中接收这些事件。
这很容易做到。检查我下面的例子。
基本上: ButtonPanel 是它自己的“组件”(它不扩展 JPanel 因为我不认为这是必要的,相反,有一个getter getPanel() 对于它创建的组件)。 ButtonPanel 还实现了 ActionListener 为按钮创建事件 ButtonPanel 有能力添加 ActionListener 通过 addActionListener 所以其他人可以注册 ActionEvent 他是从 ButtonPanel .

testapp.java文件:

  1. import java.awt.event.ActionEvent;
  2. import javax.swing.BoxLayout;
  3. import javax.swing.JFrame;
  4. import javax.swing.JOptionPane;
  5. import javax.swing.JPanel;
  6. import javax.swing.JToggleButton;
  7. import javax.swing.SwingUtilities;
  8. import javax.swing.border.EmptyBorder;
  9. public class TestApp {
  10. public TestApp() {
  11. createAndShowGUI();
  12. }
  13. public static void main(String[] args) {
  14. SwingUtilities.invokeLater(TestApp::new);
  15. }
  16. private void createAndShowGUI() {
  17. JFrame frame = new JFrame("TestApp");
  18. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  19. JPanel panel = new JPanel();
  20. panel.setBorder(new EmptyBorder(20, 20, 20, 20));
  21. panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
  22. ButtonPanel buttonPanel = new ButtonPanel();
  23. // here we register for events created from the button panel as buttons are pressed
  24. buttonPanel.addActionListener((ActionEvent e) -> {
  25. JToggleButton button = (JToggleButton) e.getSource();
  26. switch (e.getActionCommand()) { // which button was pressed?
  27. case "button1":
  28. JOptionPane.showMessageDialog(panel, "Button 1 pressed and isSelected is: " + button.isSelected());
  29. break;
  30. case "button2":
  31. JOptionPane.showMessageDialog(panel, "Button 2 pressed and isSelected is:" + button.isSelected());
  32. break;
  33. }
  34. });
  35. panel.add(buttonPanel.getPanel());
  36. frame.add(panel);
  37. frame.pack();
  38. frame.setVisible(true);
  39. }
  40. }

buttonpanel.java:

  1. import java.awt.event.ActionEvent;
  2. import java.awt.event.ActionListener;
  3. import javax.swing.JPanel;
  4. import javax.swing.JToggleButton;
  5. public class ButtonPanel implements ActionListener {
  6. private JPanel panel;
  7. private JToggleButton button1;
  8. private JToggleButton button2;
  9. private ActionListener actionListener;
  10. public ButtonPanel() {
  11. initView();
  12. }
  13. private void initView() {
  14. panel = new JPanel();
  15. button1 = new JToggleButton("Button 1 (OFF)");
  16. button2 = new JToggleButton("Button 2 (OFF)");
  17. button1.addActionListener(this);
  18. button2.addActionListener(this);
  19. panel.add(button1);
  20. panel.add(button2);
  21. }
  22. @Override
  23. public void actionPerformed(ActionEvent e) {
  24. JToggleButton button = ((JToggleButton) e.getSource());
  25. button.setText(button.getText().substring(0, button.getText().indexOf("(")) + "(" + (button.isSelected() ? "ON" : "OFF") + ")");
  26. if (e.getSource() == button1) {
  27. if (actionListener != null) {
  28. actionListener.actionPerformed(new ActionEvent(e.getSource(), ActionEvent.ACTION_PERFORMED, "button1"));// we send button1 as a command so we know what button was pressed
  29. }
  30. } else if (e.getSource() == button2) {
  31. if (actionListener != null) {
  32. actionListener.actionPerformed(new ActionEvent(e.getSource(), ActionEvent.ACTION_PERFORMED, "button2"));// we send button2 as a command so we know what button was pressed
  33. }
  34. }
  35. }
  36. public JPanel getPanel() {
  37. return panel;
  38. }
  39. void addActionListener(ActionListener actionListener) {
  40. this.actionListener = actionListener;
  41. }
  42. }
展开查看全部

相关问题