JFrame - 根据选择的JList特定操作

时间:2013-11-19 01:32:20

标签: java swing jlist

我创建了一个基本上从oracle站点复制'ListDemo.java'的列表。我收录了一张我的照片。

public static class BackpackList extends JPanel implements ListSelectionListener {

    private JList list;
    private DefaultListModel listModel;

    private static final String useString = "Use";
    private JButton useButton;

    public BackpackList() {
        super(new BorderLayout());

        listModel = new DefaultListModel();
        listModel.addElement("Flashlight");
        listModel.addElement("Health potion");
        listModel.addElement("Snacks");

        //Create the list and put it in a scroll pane.
        list = new JList(listModel);
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.setSelectedIndex(0);
        list.addListSelectionListener(this);
        list.setVisibleRowCount(10);
        JScrollPane listScrollPane = new JScrollPane(list);

        useButton = new JButton(useString);
        useButton.setActionCommand(useString);
        useButton.addActionListener(new UseListener());

        //Create a panel that uses BoxLayout.
        JPanel buttonPane = new JPanel();
        buttonPane.setLayout(new BoxLayout(buttonPane,
                                           BoxLayout.LINE_AXIS));
        buttonPane.add(useButton);
        buttonPane.add(Box.createHorizontalStrut(5));
        buttonPane.add(new JSeparator(SwingConstants.VERTICAL));
        buttonPane.add(Box.createHorizontalStrut(5));
        buttonPane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));

        add(listScrollPane, BorderLayout.CENTER);
        add(buttonPane, BorderLayout.PAGE_END);

    }

    class UseListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            //This method can be called only if
            //there's a valid selection
            //so go ahead and remove whatever's selected.
            int index = list.getSelectedIndex();
            listModel.remove(index);

            int size = listModel.getSize();

            if (size == 0) { //Nobody's left, disable firing.
                useButton.setEnabled(false);
            }
            else { //Select an index.
                if (index == listModel.getSize()) {
                    //removed item in last position
                    index--;
                }

                list.setSelectedIndex(index);
                list.ensureIndexIsVisible(index);
            }
        }
    }


    @Override
    public void valueChanged(ListSelectionEvent e) {
        if (e.getValueIsAdjusting() == false) {

            if (list.getSelectedIndex() == -1) {
            //No selection, disable fire button.
                useButton.setEnabled(false);
            }
            else {
            //Selection, enable the fire button.
                useButton.setEnabled(true);
            }
        }

    }
}

问题1:我正在为基本的基于文​​本的游戏设置背包。我想根据您在列表中选择的项目设置具体操作。制作它的代码是什么,以便健康药水会做出与零食不同的东西?

enter image description here

问题2:如果你有2个小吃或者“x3 Snacks”,我怎么能这样做呢?它会说出“x2 Snacks”的内容有3个小吃等。

1 个答案:

答案 0 :(得分:2)

背包需要跟踪其他地方定义的物品。 JList可以保存任何类型对象的列表,因此您需要做的是为库存项创建对象。下面显示了使用枚举的示例:

public class InventoryManager {

    public enum InventoryItem {
        LIGHT("Flashlight") {
            boolean isOn;
            @Override public void doAction() {
                isOn = !isOn;
            }
            @Override public String toString() {
                return name;
            }
        },
        POTION("Health Potions") {
            @Override public void doAction() {
                Game.getPlayer().setHealth(Game.getPlayer().getHealth() + 25);
                remove(1);
            }
        },
        SNACK("Snacks") {
            @Override public void doAction() {
                Game.getPlayer().setEnergy(Game.getPlayer().getEnergy() + 10);
                remove(1);
            }
        };

        private final String name;
        private int quantity = 0;

        private InventoryItem(String n) {
            name = n;
        }

        public abstract void doAction();

        public void add(int q) {
            if ((quantity += q) < 0) quantity = 0;
        }

        public void remove(int q) {
            add(-q);
        }

        @Override public String toString() {
            return name + " x" + quantity;
        }
    }

    public static InventoryItem[] getHeldItems() {
        EnumSet<InventoryItem> items = EnumSet.allOf(InventoryItem.class);

        Iterator<InventoryItem> it = items.iterator();
        while (it.hasNext()) {
            if (it.next().quantity < 1) {
                it.remove();
            }
        }

        return items.toArray(new InventoryItem[items.size()]);
    }
}

枚举示例完全是静态的,所以实际上这样做会有一些问题(我选择它主要是因为它是最短的代码)。但最终你将拥有一个带有抽象方法的超类Item,子类以不同的方式实现。然后,您将使用所持有的项填充JList。当用户从列表中选择一个项目时,list.getSelectedValue()会返回您可以在游戏中使用的Item对象。

// or Item can be an interface classes implement

public abstract class Item {
    public void doAction() {
        Game.updateState();
    }
}

public class Light extends InventoryItem {
    boolean lighted;
    @Override public void doAction() {
        lighted = !lighted;
        super.doAction();
    }
}

public class Potion extends InventoryItem {
    @Override public void doAction() {
        player.hp++;
        super.doAction();
    }
}

public class Snack extends InventoryItem {
    @Override public void doAction() {
        player.energy++;
        super.doAction();
    }
}

另一种方法是使用直接程序逻辑,例如:

switch (list.getSelectedItem()) {
    case "Flashlight": {
        toggleFlashlight();
        break;
    }

    case "Health Potion": {
        usePotion();
        break;
    }

    case "Snack": {
        useSnack();
        break;
    }
}

但我有一种感觉,试图用这样的逻辑做到这一切最终会变得更加复杂。