package hirondelle.stocks.preferences;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import java.awt.event.*;
import hirondelle.stocks.util.Args;
import hirondelle.stocks.util.Consts;
import hirondelle.stocks.util.ui.UiConsts;
import hirondelle.stocks.util.ui.UiUtil;
final class OrderEditor extends JPanel {
OrderEditor(String aUpButtonText, String aDownButtonText){
Args.checkForContent(aUpButtonText);
Args.checkForContent(aDownButtonText);
fUpButtonText = aUpButtonText;
fDownButtonText = aDownButtonText;
buildGui();
}
OrderEditor(Icon aUpButtonIcon, Icon aDownButtonIcon){
Args.checkForNull(aUpButtonIcon);
Args.checkForNull(aDownButtonIcon);
fUpButtonIcon = aUpButtonIcon;
fDownButtonIcon = aDownButtonIcon;
buildGui();
}
void setItems(Set<Object> aItems) {
Args.checkForEmpty(aItems);
fModel = new DefaultListModel();
for(Object item : aItems){
fModel.addElement(item);
}
fList.setModel(fModel);
}
Set<Object> getItems(){
Set<Object> result = new LinkedHashSet<Object>();
List<?> elements = Collections.list(fModel.elements());
for ( Object element : elements) {
result.add(element);
}
assert result.size() == fModel.size();
return result;
}
public void requestFocus(){
fList.requestFocus();
}
private String fUpButtonText;
private String fDownButtonText;
private Icon fUpButtonIcon;
private Icon fDownButtonIcon;
private JList fList;
private DefaultListModel fModel;
private void buildGui(){
setLayout( new BoxLayout(this, BoxLayout.X_AXIS) );
fList = new JList();
fList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
fList.setSelectedIndex(0);
fList.setToolTipText ("Choose item, then move using buttons");
add( Box.createHorizontalGlue() );
add( new JScrollPane(fList) );
add( Box.createHorizontalStrut(UiConsts.ONE_SPACE) );
add( getButtons() );
add( Box.createHorizontalGlue() );
UiUtil.alignAllY(this, UiUtil.AlignY.CENTER );
}
private JComponent getButtons() {
Action upAction = (
hasIcons() ?
new UpAction(fUpButtonIcon) :
new UpAction(fUpButtonText)
);
JButton up = new JButton(upAction);
Action downAction = (
hasIcons() ?
new DownAction(fDownButtonIcon) :
new DownAction(fDownButtonText)
);
JButton down = new JButton(downAction);
java.util.List<JComponent> buttons = new ArrayList<>();
buttons.add(up);
buttons.add(down);
JComponent result = UiUtil.getCommandColumn(buttons);
result.setBorder( BorderFactory.createEmptyBorder(0,0,0,0) );
return result;
}
private void swapWithPredecessor(){
int selectedIdx = fList.getSelectedIndex();
if ( selectedIdx == 0 ) return;
int predecessorIdx = selectedIdx - 1;
Object predecessor = fModel.getElementAt( predecessorIdx );
Object mover = fModel.getElementAt( selectedIdx );
fModel.setElementAt( mover, predecessorIdx );
fModel.setElementAt( predecessor, selectedIdx );
fList.setSelectedIndex(predecessorIdx);
}
private void swapWithSuccessor(){
int selectedIdx = fList.getSelectedIndex();
if ( selectedIdx== fModel.getSize() - 1 ) return;
int successorIdx = selectedIdx + 1;
Object successor = fModel.getElementAt( successorIdx );
Object mover = fModel.getElementAt( selectedIdx );
fModel.setElementAt( mover, successorIdx );
fModel.setElementAt( successor, selectedIdx);
fList.setSelectedIndex( successorIdx );
}
private boolean hasIcons(){
return (fUpButtonIcon != null);
}
private boolean isSelectionPresent() {
return ! fList.getSelectionModel().isSelectionEmpty();
}
private abstract class EditAction extends AbstractAction implements ListSelectionListener{
EditAction(String aText){
super(aText);
init();
}
EditAction(Icon aIcon){
super(Consts.EMPTY_STRING, aIcon);
init();
}
@Override public final void valueChanged(ListSelectionEvent event) {
setEnabled( isSelectionPresent() );
}
private final void init(){
setEnabled(false);
fList.getSelectionModel().addListSelectionListener(this);
}
}
private final class UpAction extends EditAction {
UpAction(String aText){
super(aText);
}
UpAction(Icon aIcon){
super(aIcon);
}
@Override public void actionPerformed(ActionEvent event) {
swapWithPredecessor();
}
}
private final class DownAction extends EditAction {
DownAction(String aText){
super(aText);
}
DownAction(Icon aIcon){
super(aIcon);
}
@Override public void actionPerformed(ActionEvent event) {
swapWithSuccessor();
}
}
}