Java / Swing: обновление данных на stateChange - PullRequest
2 голосов
/ 23 сентября 2010

У меня есть список Map.Entry<String,Integer> s, по которым я зацикливаюсь, и для каждого из них создается JLabel / JSpinner, представляющий эту конкретную запись.

Как сделать так, чтобы при срабатывании ChangeListener на JSpinner обновлялась эта запись, отражая новое значение?

Мой код выглядит как

for (Map.Entry<String,Integer> entry : graph.getData()) {
    SpinnerNumberModel model = new SpinnerNumberModel(
      entry.getValue(),(Integer)0,(Integer)100,(Integer)5);
    JSpinner spinner = new JSpinner(model);

    JLabel label = new JLabel(entry.getKey());

    spinner.addChangeListener(new ChangeListener() {
        public void stateChanged(ChangeEvent e) {
            entry.setValue((Integer)((JSpinner)e.getSource()).getValue());
        }
    });

    // more stuff
}

Однако это не работает, потому что запись должна быть конечной или на уровне объекта, и это не так.

Есть ли более простой способ, например, C # 1015 *, который напрямую связывает объект с вращателем? Или как я могу сделать эту работу?

Ответы [ 3 ]

2 голосов
/ 23 сентября 2010

Есть несколько вариантов, если вы хотите придерживаться отдельных JLabel и JSpinner.Используйте ответ @ trashgod, если карта может стать большой.

  1. НЕПРАВИЛЬНО Для комментария @Suresh Kumar: final Map.Entry<String,Integer> entry
  2. НЕПРАВИЛЬНО Добавить spinner.putClientProperty("MyEntryKey", entry), затем в вашем ChangeListener получите запись сspinner.getClientProperty.
  3. Добавьте spinner.putClientProperty("MyEntryKey", entry.getKey()), затем в свой список изменений graph.put(spinner.getClientProperty(), ...).
  4. Из ответа @ Майкла (не уверен, что это этично): Добавьте final String key = entry.getKey(), затем в свойChangeListener graph.put(key, ...).
  5. Позвольте вашему классу реализации реализовать ChangeListener, чтобы избежать одного ChangeListener на JSpinner:

    public void stateChanged (ChangeEvent e) {JSpinner spinner =(JSpinner) e.getSource ();graph.put ((String) spinner.getClientProperty ("MyEntryKey"), (Integer) spinner.getValue ());}

Кстати graph.getData() выглядит немного странно.Если graph реализует Map, вы должны использовать graph.entrySet().

1 голос
/ 23 сентября 2010

@ Суреш прав в использовании final в цикле for, но поскольку значения Map.Entry не являются жизнеспособными вне итератора, это может привести к проблемам.Другая возможность для этой односторонней привязки может быть

for (Map.Entry<String, Integer> entry : graph.getData()) {
    ...
    final String key = entry.getKey();

    spinner.addChangeListener(new ChangeListener() {
        public void stateChanged(ChangeEvent e) {
            graph.put(key, (Integer)((JSpinner)e.getSource()).getValue());
        }
    });

. Для более полной привязки данных вы можете захотеть связать более сложный объект.См., Например, jgoodies API связывания ValueModel и SpinnerAdapterFactory.

1 голос
/ 23 сентября 2010

В частности, если количество Map записей велико, рассмотрите возможность использования JTable, с вашим Map в качестве ядра модели данных и пользовательским рендером / редактором, расширяющим JSpinner,Есть похожий пример здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...