Я должен использовать Слушателя или Наблюдателя?

Это то, что вы ищете? Чтобы все бары были одинаковой ширины, мне пришлось заполнить data дополнительной строкой, поскольку в Car == 'BMW X5' нет Country == 'US'. Канал подготовки данных %>% был полностью вдохновлен в на этот ответ .

library(tidyverse)
library(ggplot2)


data %>% 
  spread(key = Car, value = Value, fill = NA) %>% 
  gather(key = Car, value = Value, -Country) %>% 
  ggplot(aes(x = Car, y = Value, fill = Country)) +
  geom_col(position = position_dodge())

Данные.

data <- read.table(text = "
Car      Country      Value
'Audi A6'  US           23
'Audi A6'  UK           12
'Audi A6'  DE           19
'BMW X5'   UK           8
'BMW X5'   DE           5
", header = TRUE)

16
задан Matt Ball 1 February 2012 в 16:39
поделиться

6 ответов

Два решения по сути являются реализациями одного и того же корневого шаблона проектирования (шаблон «Наблюдатель», как определено Группой Четыре.) В первом случае вы делаете сам ArrayList «наблюдаемым», во втором вы делаете объект домена, который использует список массивов, «наблюдаемым».

Моя тенденция заключалась бы в том, чтобы сделать второй: сделать доменный объект наблюдаемый. Это в первую очередь потому, что у вас могут появиться другие вещи, которые могут измениться в доменном объекте (для которого GUI должен быть обновлен). Если он уже наблюдаемый, вы уже настроены.

Обратите внимание, что у вас нет строго расширить java.util.Observable - вы можете реализовать шаблон проектирования без этого.

11
ответ дан 30 November 2019 в 21:54
поделиться

Реализация Observable в Java редко используется и плохо взаимодействует с Качели. Вместо этого используйте EventListener .

В частности, есть ли причина не расширять AbstractListModel или даже не использовать DefaultListModel непосредственно при управлении содержимым списка «в другом месте в GUI»? Тогда ваше поле со списком может использовать ComboBoxModel , который делегирует тот же экземпляр ListModel , добавляя свою собственную реализацию для отслеживания состояния выбора.

Я имею в виду нечто подобное (но Я не проверял это):

final class MyComboBoxModel 
  extends AbstractListModel 
  implements ComboBoxModel 
{

  private final ListModel data;

  private volatile Object selection;

  MyComboBoxModel(ListModel data) { 
    /* 
     * Construct this object with a reference to your list, 
     * which contents are managed somewhere else in the UI.
     */
    this.data = data;
    data.addListDataListener(new ListDataListener() {
      public void contentsChanged(ListDataEvent evt) { 
        fireContentsChanged(this, evt.getIndex0(), evt.getIndex1()); 
      }
      public void intervalAdded(ListDataEvent evt) { 
        fireContentsChanged(this, evt.getIndex0(), evt.getIndex1()); 
      }
      public void intervalRemoved(ListDataEvent evt) { 
        fireContentsChanged(this, evt.getIndex0(), evt.getIndex1()); 
      }
    });
  }

  public void setSelectedItem(Object selection) { 
    this.selection = selection;
    fireContentsChanged(this, 0, data.getSize() - 1);
  }

  public Object getSelectedItem() { return selection; }

  public int getSize() { return data.getSize(); }

  public Object getElementAt(int idx) { return data.getElementAt(idx); }

}
9
ответ дан 30 November 2019 в 21:54
поделиться

Почему бы не использовать привязки?

http://wiki.eclipse.org/index.php/JFace_Data_Binding

Свяжите свой графический виджет с вашим списком. Изменения будут распространяться между двумя объектами прозрачно. Обязательно оберните вашу модель подходящей наблюдаемой, например WritableList (если вы используете ArrayList напрямую).

2
ответ дан 30 November 2019 в 21:54
поделиться

Always prefer composition over extension (my reference is effective java and my personal experience). extending ArrayList is simply a promise that you will not violate any of the classes invariants. It also binds you to the specific list implementation you are extending.

1
ответ дан 30 November 2019 в 21:54
поделиться

Вы можете переключиться на использование шаблона проектирования GUI . Или создайте ограниченную реализацию.

Создайте интерфейс формы графического интерфейса, который имеет метод DrawXArrayList (где X - какое-то значимое имя. Он имеет параметры типа ArrayList

. Создайте новый класс с именем GUIView. Он имеет по крайней мере два метода. : UpdateXArrayList и RegisterForm

Когда вы инициализируете свое приложение, форма GUI зарегистрируется в классе, реализующем GUIView. Сделайте класс, реализующий GUIView, видимым для формы.

Когда что-либо в вашей форме GUI обновляет массив, его вызовите UpdateXArrayList - последнее, что он делает. Метод UpdateXArrayList в классе, реализующем GUIView, в свою очередь будет вызывать DrawXArrayList, передавая обновленный массив. DrawXArrayList в классе формы, реализующем GUIFormInterface, затем предпримет шаги, необходимые для обновления элемента управления, отображающего ArrayList.

Хотя это кажется большим количеством шагов по сравнению с настройкой наблюдателя и слушателя. Вы имеете больше контроля над тем, как различные пользовательские действия влияют на пользовательский интерфейс, чем шаблон наблюдателя-слушателя. Кроме того, вы задокументировали в коде взаимодействие между действием пользователя и обновлениями пользовательского интерфейса.

0
ответ дан 30 November 2019 в 21:54
поделиться

Если вы можете добавить новый jar в приложение, проверьте глазированные списки

0
ответ дан 30 November 2019 в 21:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: