How can I make an upside-down list in Java?
I'd like to be able to display a mutable list (using Swing) such that the first item is at the bottom in a fixed position, and subsequent items appear above it. Just the way a stack of stuff would appear in reality. The behavior is that of a FIFO queue (add to the top, remove from the bottom).
I can imagine a solution involving "padding" the list and then sorting it in reverse, or something like that, but I wondered if there might be a more direct way.
Example:
item[0]="Adam"
item[1]="Baker"
item[2]="Charlie"
should appear in 5-row list as:
+----------
|
|
| Charlie
| Baker
| Adam
+-----开发者_运维知识库-----
If you don't want to create a custom model, then you can use the DefaultListModel. Then instead of using:
model.addElement( element );
you can use:
model.add(0, element);
and the elements will be displayed in the order you wish.
The following code also show how you might make the list look bigger than it really is:
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 );
}
}
Provide an implementation of ListModel and that can wrap whatever data structure is appropriate.
Just reverse your array. In one line: (This isn't exactly efficient, but it'll work):
JList list = new JList(Collections.reverse(Arrays.asList(items)).toArray());
Note: It doesn't make sense to have a different UI component which reads the data differently. A ListModel holds the data according to the contract between itself and JList. Creating a new contract is pointless, when its trivial to reorganize the data based on how you want to visualize it, and more importantly, based on UI standards of the operating system.
If anything, you want a reverse ListModel, but, on the same note, it doesn't make sense to have a full implementation of ListModel that just goes in the opposite direction, when really, all you need to do is reverse the order of the backing data structure.
So, that's what you do.
Edit to add:
I read more of what you're trying to do and it looks like you want a fixed size list where data starts at the end (like a stack). In that case, what you really need to do is implement your own ListModel. Take a look at AbstractListModel and you should be able to extend it and provide your own data.
If you do that, your class will then be essentially (consider this p-code, this may not be 100% right):
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;
}
}
Collections utility is enough to reverse a collections Collections.reverse(list)
精彩评论