【问题标题】:How can I make an upside-down list in Java?如何在 Java 中制作倒置列表?
【发布时间】:2011-09-27 09:45:56
【问题描述】:

我希望能够显示一个可变列表(使用 Swing),这样第一个项目位于底部固定位置,后续项目显示在其上方。就像一堆东西在现实中出现的方式一样。行为是 FIFO 队列的行为(添加到顶部,从底部移除)。

我可以想象一个解决方案,涉及“填充”列表,然后将其反向排序,或者类似的东西,但我想知道是否有更直接的方法。

Example:
item[0]="Adam"
item[1]="Baker"
item[2]="Charlie"

should appear in 5-row list as:

+----------
|
|
| Charlie
| Baker
| Adam
+----------

【问题讨论】:

  • @Chap:如果我理解正确,那么您可以使用一些基于 LIFO 的集合,以相反的顺序输入元素,因此最后一个元素将是 JList 的第一个元素。您可以使用此link 进行后进先出收集。

标签: java swing list reverse


【解决方案1】:

集合实用程序足以反转集合Collections.reverse(list)

【讨论】:

    【解决方案2】:

    如果您不想创建自定义模型,则可以使用 DefaultListModel。然后代替使用:

    model.addElement( element );
    

    你可以使用:

    model.add(0, element);
    

    元素将按照您希望的顺序显示。

    以下代码还显示了如何使列表看起来比实际更大:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.border.*;
    
    public class ListBottom2 extends JFrame
    {
        JList list;
        JTextField textField;
    
        public ListBottom2()
        {
            DefaultListModel model = new DefaultListModel();
            model.add(0, "Adam");
            model.add(0, "Baker");
            model.add(0, "Charlie");
            list = new JList(model);
            list.setVisibleRowCount(5);
    
            JPanel box = new JPanel( new BorderLayout() );
            box.setBackground( list.getBackground() );
            box.add(list, BorderLayout.SOUTH);
    
            JScrollPane scrollPane = new JScrollPane( box );
            scrollPane.setPreferredSize(new Dimension(200, 95));
            add( scrollPane );
    
            textField = new JTextField("Use Enter to Add");
            getContentPane().add(textField, BorderLayout.NORTH );
            textField.addActionListener( new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {
                    JTextField textField = (JTextField)e.getSource();
                    DefaultListModel model = (DefaultListModel)list.getModel();
    //              model.addElement( textField.getText() );
                    model.add(0, textField.getText());
                    int size = model.getSize() - 1;
                    list.scrollRectToVisible( list.getCellBounds(size, size) );
                    textField.setText("");
                }
            });
        }
    
        public static void main(String[] args)
        {
            ListBottom2 frame = new ListBottom2();
            frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
            frame.pack();
            frame.setLocationRelativeTo( null );
            frame.setVisible( true );
        }
    }
    

    【讨论】:

    • 这就是我想要的。我收集到 model.add(0,"Charlie") 将元素添加到列表的 beginning 中。但是,我不太确定您如何设法使列表“底部合理”。 BorderLayout.SOUTH 是解决方案的关键吗?
    • 是的,BorderLayout 就是诀窍。该列表显示在南部。如果“框”面板有任何额外空间可用,则将其分配给 BorderLayout 的“中心”。随着盒子高度的增长/缩小,中心的空间会增长/缩小,而列表保持不变。
    • 好吧,这正是我所希望的。
    【解决方案3】:

    只需反转您的数组。一句话:(这不是很有效,但它会起作用):

    JList list = new JList(Collections.reverse(Arrays.asList(items)).toArray());
    

    注意:使用不同的 UI 组件以不同的方式读取数据是没有意义的。 ListModel 根据自身与 JList 之间的约定保存数据。创建一个新合约是没有意义的,因为根据您想要的可视化方式重新组织数据是微不足道的,更重要的是,基于操作系统的 UI 标准。

    如果有的话,你想要一个反向的 ListModel,但是,同样地,完全实现 ListModel 只是朝着相反的方向发展是没有意义的,实际上,你需要做的就是反向支持数据结构的顺序。

    所以,这就是你要做的。

    编辑添加:

    我阅读了更多您正在尝试做的事情,看起来您想要一个固定大小的列表,其中数据从末尾开始(如堆栈)。在这种情况下,您真正​​需要做的是实现您自己的 ListModel。看看AbstractListModel,你应该可以扩展它并提供你自己的数据。

    如果你这样做,那么你的课程本质上就是(考虑这个 p 代码,这可能不是 100% 正确):

    class ReverseListModel extends AbstractListModel {
    
      public Object getElementAt(int i) {
        int dataIndex = fixedSize - i;
        if(dataIndex > data.length) 
          return "";
        else
          return data[dataIndex];
      }
    
      public int getSize() {
        return fixedSize;
      }
    }
    

    【讨论】:

    • 我不想把自己束缚在一个固定大小的列表中,但我还没有决定。我正在模拟一个老式读卡器,带有一个包含 Decks(卡片)的 Hopper。 “第一层”总是在底部,从那里读取卡片。从逻辑上讲,它只是一个队列,但在物理上它受制于 IBM 读卡器的设计(以及万有引力定律 :-)。我不确定为什么“不同的 UI”组件是个坏主意 - 它只需要“在其头部”显示一个普通列表。
    【解决方案4】:

    提供ListModel 的实现,它可以包装任何合适的数据结构。

    【讨论】:

    • ListModel 不只是说明 JList 中有哪些项目以及按什么顺序排列?如果你有一个项目,JList 仍然会在顶部显示它,但我认为 Chap 想要它在底部。
    • 是的 - 我已经更新了原始帖子,以直观地展示我所追求的。
    • JList 假定“第一个”项目应显示在 顶部。我想我正在寻找一个“JUpsideDownList”,它在底部显示第一个项目,而不是我不得不巧妙地重新排列模型中的数据。
    • 您可以在 ListModel 中执行此操作。假设 theList 是 java.util.List,您的 ListModel 实现可以返回 theList.get( theList.size() - index ) 以便以相反的顺序返回对象。这样,您的实际 List 类可以维护第 0 个索引中的第 0 个项目,但它会出现在最后,因为 ListModel 会翻转它。
    • @Jesse Barnum 是正确的。通过提供 impl。你在控制之中。例如以相反的顺序返回一个填充列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多