Java Swing - 编写一个Ui,它将根据对自定义数据对象的更改重新绘制自身 [英] Java Swing -- Writing a Ui that will repaint itself based on changes to a custom data object

查看:130
本文介绍了Java Swing - 编写一个Ui,它将根据对自定义数据对象的更改重新绘制自身的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先要做的事情 - 我在之前发布了一个问题其中我曾请求帮助,为什么我的代码不起作用,这个问题是根据我在该问题中得到的建议。

First things first -- I had posted a question earlier wherein i had asked for help as to why my code was not working and this question is acting upon the advice i got in that question.

我的用例是这个。

My use case is this.

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

Im writing a MethodEditor module wherein every Method is denoted by a custom data object that has 2 data members --


  1. 输入变量名称列表

  2. String(此方法设置的结果变量的名称)。

这些方法由于在 JDialog 上填写一些数据而生成对象。

这些方法对象存储在一个容器中,该容器具有1个数据成员,该数据成员是 List< Method>
容器位于控制器 JPanel 来自上述地方调用oned JDialog

These Method objects are generated as a result of filling out some data on a JDialog.
These Method objects are stored in a container that has 1 data member that is a List<Method> The container resides in a controller JPanel from where the aforementioned JDialog is invoked.

从UI的角度来看,我希望在点击时以Jbutton的形式显示每个方法对象其中 JDialog 将打开并允许用户编辑它。


From a UI perspective I want to display every Method object in the form of a Jbutton on click of which a JDialog will open and allow the user to edit it.

MethodEditor 作用于List并生成垂直排列JButtons, List< Method> 中的每个方法为1。此列表<方法> 从上述控制器 JPane MethodEditor c $ c>。

The MethodEditor acts on a List and generated a vertical arrangement of JButtons, 1 for each Method in List<Method>. This List<Method> is passed to the MethodEditor from the aforementioned controller JPane.

我在之前的问题 MethodEditor 实现为 JPanel ,它将添加 PropertyChangeListener 列表<方法> 并且每次都会重绘是一个 PropertyChange 事件,但我的方法不起作用,重绘不会发生。

I had in my earlier question implemented the MethodEditor as a JPanel that would add a PropertyChangeListener to the List<Method> and would repaint itself everytime there was a PropertyChange event but my approach did not work, the repaint would not happen.

还有另外一种方法得到我的用例实现,或者我可以对我之前发布的代码进行任何修复问题

Is there another way to get my use case implemented or is there any fix that i could do to my code posted in the earlier question ?

推荐答案

之前已经提到过您的问题及其解决方案。您必须实际在PropertyChangeListener中向观察者面板添加或删除组件。调用 revalidate() repaint()不会神奇地添加或删除组件,除非你之前明确地这样做这些方法称为

Your problem has been mentioned before as has its solution. You must actually add or remove the component to your observer panel from within the PropertyChangeListener. Calling revalidate() and repaint() will not magically add or remove components unless you explicitly do this before these methods are called.

例如:

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();
   }
}

这篇关于Java Swing - 编写一个Ui,它将根据对自定义数据对象的更改重新绘制自身的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆