Java Swing —— 编写一个可根据自定义数据对象的更改重新绘制自身的 Ui

2023-11-30

首先,我已经发布了一个问题earlier其中我曾就为什么我的代码无法工作而寻求帮助,并且这个问题是根据我在该问题中得到的建议采取的。

我的用例是这样的。

我正在写一个MethodEditor模块其中每个Method由具有 2 个数据成员的自定义数据对象表示 --

  1. 输入变量名称列表
  2. String(此方法设置的结果变量的名称)。

These Method对象是通过在 a 上填写一些数据而生成的JDialog.
These Method对象存储在一个容器中,该容器有 1 个数据成员,即List<Method>容器驻留在控制器中JPanel从上述的地方JDialog被调用。

从用户界面的角度来看,我想显示每一个Method对象以 Jbutton 的形式单击,其中JDialog将打开并允许用户对其进行编辑。

The MethodEditor作用于 List 并生成 JButton 的垂直排列,每个 JButton 1 个Method in List<Method>. This List<Method>被传递到MethodEditor来自上述控制器JPane.

我之前有过question实施了MethodEditor as a JPanel这会添加一个PropertyChangeListener to the List<Method>并且会repaint每当有一个PropertyChange事件,但我的方法不起作用,重画不会发生。

是否有另一种方法来实现我的用例,或者我可以对之前发布的代码进行任何修复question ?


之前已经提到过您的问题及其解决方案。您实际上必须从 PropertyChangeListener 中向观察者面板添加或删除组件。呼唤revalidate() and repaint()不会神奇地添加或删除组件,除非您在调用这些方法之前明确执行此操作.

例如:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.IndexedPropertyChangeEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;

public class ListenToTest {
   public static final String[] ITEMS = {"Sunday", "Monday", "Tuesday", "Wednesday", 
      "Thursday", "Friday", "Saturday"};
   private JPanel mainPanel = new JPanel();
   private ObserverPanel observerPanel = new ObserverPanel();
   private ListenToModel model = new ListenToModel();

   public ListenToTest() {
      observerPanel.setModel(model);

      for (String item : ITEMS) {
         model.addItem(item);
      }

      JPanel btnPanel = new JPanel();
      btnPanel.add(new JButton(new AddAction("Add")));
      btnPanel.add(new JButton(new RemoveAction("Remove")));

      mainPanel.setLayout(new BorderLayout());
      mainPanel.add(new JScrollPane(observerPanel.getMainComponent()));
      mainPanel.add(btnPanel, BorderLayout.PAGE_END);
   }

   public JComponent getMainComponent() {
      return mainPanel;
   }

   private class AddAction extends AbstractAction {
      public AddAction(String title) {
         super(title);
      }

      @Override
      public void actionPerformed(ActionEvent arg0) {
         String text = JOptionPane.showInputDialog(mainPanel, "Enter a String");
         if (text != null) {
            model.addItem(text);
         }
      }
   }

   private class RemoveAction extends AbstractAction {
      public RemoveAction(String title) {
         super(title);
      }

      @Override
      public void actionPerformed(ActionEvent arg0) {
         int index = observerPanel.getSelectedIndex();
         if (index >= 0) {
            model.removeItem(index);
         }
      }
   }

   private static void createAndShowGui() {
      ListenToTest mainPanel = new ListenToTest();

      JFrame frame = new JFrame("ListenToModelTest");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel.getMainComponent());
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class ObserverPanel {
   public static final Font LABEL_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 18);
   protected static final Color SELECTED_COLOR = new Color(150, 150, 255);
   private JPanel mainPanel = new JPanel();
   private ListenToModel model;
   private GridLayout gridLayout = new GridLayout(0, 1);
   private int selectedIndex = -1;

   public ObserverPanel() {
      mainPanel.setLayout(gridLayout);
      mainPanel.addMouseListener(new MouseAdapter() {
         @Override
         public void mousePressed(MouseEvent e) {
            Point p = e.getPoint();
            Component[] components = mainPanel.getComponents();
            for (int i = 0; i < components.length; i++) {
               if (mainPanel.getComponentAt(p).equals(components[i])) {
                  selectedIndex = i;
                  components[i].setBackground(SELECTED_COLOR);
               } else {
                  components[i].setBackground(null);
               }
            }
         }
      });
   }

   public int getSelectedIndex() {
      return selectedIndex;
   }

   public void setModel(ListenToModel model) {
      this.model = model;
      model.addPropertyChangeListener(new ObserverPanelListener());
   }

   public JComponent getMainComponent() {
      return mainPanel;
   }

   private class ObserverPanelListener implements PropertyChangeListener {
      public void propertyChange(PropertyChangeEvent evt) {
         if (evt.getPropertyName().equals(ListenToModel.ADD)) {
            JLabel label = createLabel(evt);
            for (Component comp : mainPanel.getComponents()) {
               comp.setBackground(null);
            }
            int index = ((IndexedPropertyChangeEvent)evt).getIndex();
            mainPanel.add(label, index);
            label.setBackground(SELECTED_COLOR);
            selectedIndex = index;
         } else if (evt.getPropertyName().equals(ListenToModel.REMOVE)) {
            int index = ((IndexedPropertyChangeEvent)evt).getIndex();
            mainPanel.remove(index);
            for (Component comp : mainPanel.getComponents()) {
               comp.setBackground(null);
            }
            selectedIndex = -1;
         } else if (evt.getPropertyName().equals(ListenToModel.REMOVE_ALL)) {
            mainPanel.removeAll();
            selectedIndex = -1;
         }
         mainPanel.revalidate();
         mainPanel.repaint();
      }

      private JLabel createLabel(PropertyChangeEvent evt) {
         String newValue = evt.getNewValue().toString();
         JLabel label = new JLabel(newValue);
         label.setFont(LABEL_FONT);
         int eb = 20;
         label.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.blue), 
               BorderFactory.createEmptyBorder(eb , eb, eb, eb)));
         label.setFocusable(true);
         label.setOpaque(true);
         return label;
      }
   }
}

class ListenToModel implements Iterable<String> {
   public static final String ADD = "add";
   public static final String REMOVE = "remove";
   public static final String REMOVE_ALL = "remove all";
   private SwingPropertyChangeSupport spcSupport = new SwingPropertyChangeSupport(
         this);
   private List<String> modelNucleus = new ArrayList<String>();

   public void addItem(String item) {
      modelNucleus.add(item);
      spcSupport.fireIndexedPropertyChange(ADD, modelNucleus.size() - 1, null,
            item);
   }

   public void addItem(int index, String item) {
      if (index < 0 || index > modelNucleus.size()) {
         // TODO: throw an exception
      } else {
         modelNucleus.add(index, item);
         spcSupport.fireIndexedPropertyChange(REMOVE, index, null, item);
      }

   }

   public void removeItem(int index) {
      if (index < 0 || index >= modelNucleus.size()) {
         // TODO: throw an exception
      } else {
         String oldValue = modelNucleus.remove(index);
         spcSupport.fireIndexedPropertyChange(REMOVE, index, oldValue, null);
      }
   }

   public void removeAll() {
      modelNucleus.clear();
      spcSupport.firePropertyChange(REMOVE_ALL, null, null);
   }

   public void addPropertyChangeListener(PropertyChangeListener listener) {
      spcSupport.addPropertyChangeListener(listener);
   }

   public void removePropertyChangeListener(PropertyChangeListener listener) {
      spcSupport.removePropertyChangeListener(listener);
   }

   @Override
   public Iterator<String> iterator() {
      return modelNucleus.iterator();
   }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java Swing —— 编写一个可根据自定义数据对象的更改重新绘制自身的 Ui 的相关文章

随机推荐

  • 根据单元格中的数据保护行(是/否)

    我有一张带桌子的床单 当我或我的一位编辑更改 F 列中单元格的数据 使其不为空 时 我需要row为除我 所有者 之外的所有人提供保护 我在这里看到了几个类似的问题 但没有人提供工作脚本 我将不胜感激任何帮助 我相信您目前的情况和您的目标如下
  • 使用 $map 进行 MongoDB 嵌套数组搜索

    我有包含嵌套数组的集合 我需要根据以下条件获取数据 empId 19107 address country AUS group primaryGroup primary Y group subGroup primarySubGroup pr
  • Rxjs - DistinctUntilChanged() 与 keyup 事件

    我正在使用 Rxjs 6 它根据表单字段中的 keyup 事件过滤 Firebase 返回的可观察值 当用户在表单字段中没有值的情况下不断按退格键时 我遇到一个问题 然后看起来可观察对象不断刷新 使用 DistinctUntilChange
  • 在 HBase 之上的 solr 中创建索引

    无论如何 我可以在 Solr 中创建索引来从 HBase 执行近实时全文搜索 我不想将整个文本存储在我的 solr 索引中 制成 stored false 注意 请记住 我正在处理大型数据集 并且想要进行近实时搜索 我们正在谈论 TB PB
  • 格式化字典键:AttributeError:'dict'对象没有属性'keys()'

    在字符串中格式化字典键的正确方法是什么 当我这样做时 gt gt gt foo one key one value second key second value gt gt gt In the middle of a string foo
  • 生成并下载网页截图而不丢失样式

    我想生成并下载网页的屏幕截图而不丢失样式 我有一个网页 在该网页中我有一个下载按钮 当用户单击下载按钮时 整个页面的屏幕截图需要作为图像下载到用户计算机中 我怎样才能做到这一点 请检查我的代码 索引 html h1 Scrrenshot h
  • 在用作指针的结构中嵌入结构与指向结构的指针

    如果我有一个结构类型A用作指针 仅具有指针接收器 构造函数返回 A等 嵌入结构类型有什么区别B as B versus B 也就是说 有什么区别 type B struct type A struct B and type B struct
  • Windows XP 上有多个版本的 Safari? [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 有没有办法在Windows XP下运行多个版本的Safari 我有兴趣运行 Safari 版本 3 1 和 4 具体来说 我想用 Safari 3 1 调试此类问题 但在我当前的版本
  • Python - 如何将 ttkthemes 包中的主题添加到 guizero 应用程序?

    我正在开发多个 guizero 项目 并且尝试从 Python 包 ttkthemes 添加主题 准确地说是 arc 我尝试使用以下代码将主题添加到应用程序小部件 from guizero import App Text PushButto
  • 相机捕获图像的形状检测(圆形、正方形、矩形、三角形、椭圆形)+ iOS 5 + Open CV

    我是 OpenCV 新手 需要了解 OpenCV 检测 iPhone 相机拍摄图像中不同形状 圆形 正方形 矩形 三角形 椭圆形 的方法 那么 有人可以指导我正确的方向 参考文献 文章 任何东西 哪些技术可以更好地完成它 Thanks iO
  • Haskell 函数的参数数量

    当我尝试用以下命令编译它时ghc它抱怨函数定义左侧的参数数量不同 module Example where import Data Maybe from maybe a gt Maybe a gt a from maybe a Nothin
  • Python:Plt 条形图 - 不同颜色

    在Python中 我怎样才能使 reported 绿色条形 以及 UNREPORTED 酒吧红色 我想为图表中每个已报告和未报告的条形赋予不同的颜色 new AXIN 37 reported LGR 30 UNREPORTED NKD 24
  • YouTube iframe 事件

    我尝试捕获 YouTube iframe 的事件 http lab joergpfeiffer de videofull youtube php 所以我首先调用api 我设置了 iframe
  • 具有重复的递归排列

    我正在尝试编写一个递归函数 该函数通过给定列表的重复来获取所有排列 Eg set ABC 1 AAA 2 AAB 3 AAC 4 ABA N CCC 我想要此代码的递归版本 以便我可以获得任何大小的集合的排列 for i 0 i
  • 0..9 约束在 GCC 内联汇编中起什么作用?

    手册 says 允许使用与指定操作数编号匹配的操作数 如果一个数字 在同一个选项中与字母一起使用 数字应该放在最后 我不确定这意味着什么 示例代码 asm volatile swap 0 r value 0 value 堆栈溢出的内联汇编标
  • Chrome 扩展程序仅在单击某些网页时起作用

    我正在尝试让我的 Chrome 扩展程序在用户打开时弹出警报http google com 并单击扩展图标 我有以下清单 manifest version 2 name One Megahurt version 0 1 permission
  • 我想制作一个像 WhatsApp 个人资料照片对话框屏幕一样的对话框屏幕

    大家好 我目前正在尝试使用隐式意图创建一个对话框 我想在其中显示我的对话框 例如 WhatsApp 个人资料照片屏幕 并且在此屏幕中 WhatsApp 使用名为 删除照片 的额外字段 当我尝试制作相同类型的屏幕对话框时 我无法添加此额外字段
  • 如何更改 vue-cli 的分隔符?

    我安装了 vue cli webpack simple src main js import Vue from vue import App from App vue new Vue delimiters here delimiters s
  • 为 Javascript 制作文件

    有人可以告诉我如何使用 make 文件来组合和合并不同的 javascript 文件 我见过许多不同的项目使用不同的 javascript 文件 后来使用 MAKE 实用程序进行合并 Deep None
  • Java Swing —— 编写一个可根据自定义数据对象的更改重新绘制自身的 Ui

    首先 我已经发布了一个问题earlier其中我曾就为什么我的代码无法工作而寻求帮助 并且这个问题是根据我在该问题中得到的建议采取的 我的用例是这样的 我正在写一个MethodEditor模块其中每个Method由具有 2 个数据成员的自定义