ComboBoxModel с динамическими прокси-объектамиJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 ComboBoxModel с динамическими прокси-объектами

Сообщение Anonymous »

Как мы знаем, интерфейс ComboBoxModel используется для создания класса в witch, мы можем указать, как связать коллекции объектов (модель) с полем со списком, в основном путем предоставления необходимой «информации» о том, как получать элементы и устанавливать текущий элемент.
Обычно я писал эти классы, объявляя их членами коллекции , и просто делегировал некоторые функции объекту коллекции в реализованных методах.
Когда фактический класс из всех содержащихся объектов являются непроксируемыми объектами, все идет нормально (вероятно, в 90% случаев у нас возникает такая ситуация), но на этот раз мы сталкиваемся с фактом наличия ссылок на проксируемые объекты, и все идет странно неправильно.
Поведение JComboBox идет не так, поскольку он не может изменить текущий выбор.
Я пытаюсь получить дополнительную информацию, но на данный момент я знаю только, что метод setSelectedItem Интерфейс ComboBoxModel, который реализует любой конкретный класс, не вызывается, когда вокруг есть прокси-объекты. Вот мой вопрос: что происходит и, что более важно, поправимо ли это?
Оставляю пример, готов посмотреть и убедиться самому.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;

/**
*
* @author Administrador
*/
public class AComboBoxWithProxyProblem extends JFrame implements ActionListener
{
ComboBoxModel modelWithProxies = new ItemComboBoxModelWithProxies();
ComboBoxModel modelWithoutProxies = new ItemComboBoxModelWithoutProxies();

public AComboBoxWithProxyProblem()
{
final JComboBox comboBox = new JComboBox();
comboBox.addActionListener( this );

getContentPane().setLayout(new BoxLayout(this.getContentPane(),BoxLayout.LINE_AXIS));
getContentPane().add(comboBox);

JRadioButton btnProxy = new JRadioButton("Proxy model");
btnProxy.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e)
{
comboBox.setModel(modelWithProxies);
comboBox.setSelectedIndex(0);
}
});

getContentPane().add(btnProxy);

JRadioButton btnNoProxy = new JRadioButton("Non Proxy model");
btnNoProxy.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e)
{
comboBox.setModel(modelWithoutProxies);
comboBox.setSelectedIndex(0);
}
});

getContentPane().add(btnNoProxy);

ButtonGroup group = new ButtonGroup();
group.add(btnProxy);
group.add(btnNoProxy);

setTitle("Mmmm...");
}

@Override
public void actionPerformed(ActionEvent e)
{
JComboBox comboBox = (JComboBox)e.getSource();
Item item = (Item)comboBox.getSelectedItem();
System.out.println("[actionPerformed] - " + item.getId() + " : " + item.getDescription() );
}

interface ItemInterface
{

String getDescription();

int getId();

@Override
String toString();

}

class Item implements AComboBoxWithProxyProblem.ItemInterface
{
private int id;
private String description;

public Item(int id, String description)
{
this.id = id;
this.description = description;
}

@Override
public int getId()
{
return id;
}

@Override
public String getDescription()
{
return description;
}

@Override
public String toString()
{
return description;
}

}

private class ItemComboBoxModelWithoutProxies extends AbstractListModel implements ComboBoxModel
{
List foos;
ItemInterface selected;

public ItemComboBoxModelWithoutProxies()
{
foos = new ArrayList ();
foos.add(new Item(1,"One"));
foos.add(new Item(2,"Two"));
foos.add(new Item(3,"Three"));
}

@Override
public Object getSelectedItem()
{
return selected;
}

@Override
public void setSelectedItem(Object tournament)
{
System.out.println("[setSelectedItem] " + tournament);
selected = (ItemInterface) tournament;
}

@Override
public int getSize()
{
return this.foos.size();
}

@Override
public Object getElementAt(int i)
{
return this.foos.get(i);
}
}

private class ItemComboBoxModelWithProxies extends AbstractListModel implements ComboBoxModel
{
List foos;
Object selected;

public ItemComboBoxModelWithProxies()
{
foos = new ArrayList ();
ItemInterface item;
item = (ItemInterface) Proxy.newProxyInstance(Item.class.getClassLoader(),
Item.class.getInterfaces(),
new ItemInvocationHandler (new Item(1,"One")));
foos.add(item);

item = (ItemInterface) Proxy.newProxyInstance(Item.class.getClassLoader(),
Item.class.getInterfaces(),
new ItemInvocationHandler (new Item(2,"Two")));
foos.add(item);

item = (ItemInterface) Proxy.newProxyInstance(Item.class.getClassLoader(),
Item.class.getInterfaces(),
new ItemInvocationHandler (new Item(3,"Three")));
foos.add(item);
}

@Override
public Object getSelectedItem()
{
return selected;
}

@Override
public void setSelectedItem(Object tournament)
{
System.out.println("[setSelectedItem] " + tournament);
selected = (ItemInterface) tournament;
}

@Override
public int getSize()
{
return this.foos.size();
}

@Override
public Object getElementAt(int i)
{
return this.foos.get(i);
}

private class ItemInvocationHandler implements InvocationHandler {
Item item;

public ItemInvocationHandler(Item item)
{
this.item = item;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
return method.invoke(this.item, args);
}
}
}

public static void main(String[] args)
{
JFrame frame = new AComboBoxWithProxyProblem();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible( true );
}

}


Подробнее здесь: https://stackoverflow.com/questions/179 ... ed-objects
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»