001package jmri.jmrit.picker;
002
003import java.awt.*;
004import java.awt.event.*;
005import javax.swing.*;
006import javax.swing.event.*;
007import jmri.*;
008import jmri.util.swing.JmriJOptionPane;
009
010/**
011 * Container with a single PickList table
012 * <p>
013 * See also PickTabbedPanel for multiple panes with multiple tables
014 *
015 * @author Bob Jacobsen  Copyright (c) 2017
016 * @author Pete Cressman Copyright (c) 2010
017 */
018public class PickSinglePanel<T extends NamedBean> extends JPanel {
019
020    private int ROW_HEIGHT;
021
022    PickListModel<T> _model;
023
024    JPanel _addPanel;
025    JPanel _cantAddPanel;
026    JTextField _sysNametext;
027    JTextField _userNametext;
028    JTable _table;
029    JScrollPane _scroll;
030
031    public PickSinglePanel(PickListModel<T> model) {
032        _model = model;
033        _table = _model.makePickTable();
034        _table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
035        _table.setCellSelectionEnabled(true);
036        _table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
037            @Override
038            public void valueChanged(ListSelectionEvent e) {
039                int row = getTable().getSelectedRow();
040                int col = getTable().getSelectedColumn(); // might be -1 if just inserted
041                if (col != 1) return;
042                if (row >= 0) {
043                    String username = (String) _model.getTable().getValueAt(row, 1);
044                    if (username != null) return;
045                }
046                // have to set selection to col 0
047                _model.getTable().setColumnSelectionInterval(0,0);
048            }
049        });
050
051        JPanel p = new JPanel();
052        p.setLayout(new BorderLayout(5, 5));
053        p.add(new JLabel(_model.getName(), SwingConstants.CENTER), BorderLayout.NORTH);
054        p.add(_scroll = new JScrollPane(_table), BorderLayout.CENTER);
055        ROW_HEIGHT = _table.getRowHeight();
056
057        setLayout(new BorderLayout(5, 5));
058        add(p, BorderLayout.CENTER);
059        add(makeAddToTablePanel(), BorderLayout.SOUTH);
060
061        if (_model.canAddBean()) {
062            _cantAddPanel.setVisible(false);
063            _addPanel.setVisible(true);
064        } else {
065            _addPanel.setVisible(false);
066            _cantAddPanel.setVisible(true);
067        }
068    }
069
070    public NamedBeanHandle<T> getSelectedBeanHandle() {
071        int row = getTable().getSelectedRow();
072        int col = getTable().getSelectedColumn(); // might be -1 if just inserted
073        log.debug("PickSinglePanel: r = {}, c = {}", row, col);
074
075        // are we sure this is always col 0 for sysname and col 1 for user name?
076        String sysname = _model.getTable().getValueAt(row, 0).toString();
077        String username = (String) _model.getTable().getValueAt(row, 1);
078
079        String beanName = sysname;
080        if (col == 1 && username != null) beanName = username;
081        T bean = _model.addBean(sysname, username);
082        if (bean == null) {
083            return null;
084        }
085        return InstanceManager.getDefault(NamedBeanHandleManager.class)
086                        .getNamedBeanHandle(beanName, bean);
087    }
088
089    public JTable getTable() { return _table; }
090
091    private JPanel makeAddToTablePanel() {
092        _sysNametext = new JTextField();
093        _userNametext = new JTextField();
094
095        ActionListener cancelListener = new ActionListener() {
096            @Override
097            public void actionPerformed(ActionEvent a) {
098                //do nothing as Cancel button is hidden on Pick Lists
099            }
100        };
101
102        ActionListener okListener = new ActionListener() {
103            @Override
104            public void actionPerformed(ActionEvent a) {
105                addToTable();
106            }
107        };
108        _addPanel = new jmri.jmrit.beantable.AddNewDevicePanel(
109                _sysNametext, _userNametext, "addToTable", okListener, cancelListener); // No I18N
110        // hide Cancel button as not handled by Picker Panel
111
112        _cantAddPanel = new JPanel();
113        _cantAddPanel.setLayout(new BorderLayout(5, 5));
114        _cantAddPanel.add(new JLabel(Bundle.getMessage("CantAddNew"), SwingConstants.CENTER), BorderLayout.NORTH);
115        _cantAddPanel.add(new JLabel(Bundle.getMessage("OpenToAdd"), SwingConstants.CENTER), BorderLayout.SOUTH);
116        JPanel p = new JPanel();
117        p.add(_addPanel);
118        p.add(_cantAddPanel);
119        int width = Math.max(100, this.getPreferredSize().width);
120        _sysNametext.setPreferredSize(new java.awt.Dimension(width, _sysNametext.getPreferredSize().height));
121        return p;
122    }
123
124    void addToTable() {
125        String sysname = _sysNametext.getText();
126        if (sysname.length() > 1) {
127            String uname = NamedBean.normalizeUserName(_userNametext.getText());
128            if (uname != null && uname.trim().length() == 0) {
129                uname = null;
130            }
131            T bean = null;
132            try {
133                bean = _model.addBean(sysname, uname);
134            } catch (IllegalArgumentException ex) {
135                JmriJOptionPane.showMessageDialog(this.getRootPane(),
136                    Bundle.getMessage("PickAddFailed", ex.getMessage()),  // NOI18N
137                    Bundle.getMessage("WarningTitle"),  // NOI18N
138                    JmriJOptionPane.WARNING_MESSAGE);
139            }
140            if (bean != null) {
141                int setRow = _model.getIndexOf(bean);
142                _model.getTable().setRowSelectionInterval(setRow, setRow);
143                _scroll.getVerticalScrollBar().setValue(setRow * ROW_HEIGHT);
144                _sysNametext.setText("");
145            }
146        }
147    }
148
149    // initialize logging
150    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(PickSinglePanel.class);
151}