001package jmri.jmrit.logixng.actions.swing;
002
003import java.awt.Dimension;
004import java.awt.event.ActionEvent;
005import java.util.*;
006
007import javax.annotation.CheckForNull;
008import javax.annotation.Nonnull;
009import javax.swing.*;
010import javax.swing.table.TableColumn;
011
012import jmri.InstanceManager;
013import jmri.jmrit.logixng.*;
014import jmri.jmrit.logixng.actions.ActionListenOnBeans;
015import jmri.jmrit.logixng.actions.NamedBeanType;
016import jmri.jmrit.logixng.actions.ActionListenOnBeans.NamedBeanReference;
017import jmri.util.table.ButtonEditor;
018import jmri.util.table.ButtonRenderer;
019
020/**
021 * Configures an ActionListenOnBeans object with a Swing JPanel.
022 *
023 * @author Daniel Bergqvist Copyright 2021
024 */
025public class ActionListenOnBeansSwing extends AbstractDigitalActionSwing {
026
027    private JTable _listenOnBeansTable;
028    private ListenOnBeansTableModel _listenOnBeansTableModel;
029    private JTextField _localVariableNamedBean;
030    private JTextField _localVariableEvent;
031    private JTextField _localVariableNewValue;
032
033    @Override
034    protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) {
035        if ((object != null) && (! (object instanceof ActionListenOnBeans))) {
036            throw new IllegalArgumentException("object is not a ActionListenOnBeans: " + object.getClass().getName());
037        }
038        ActionListenOnBeans listenOnBeans = (ActionListenOnBeans)object;
039
040        panel = new JPanel();
041
042        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
043
044        _listenOnBeansTable = new JTable();
045
046        if (listenOnBeans != null) {
047            List<NamedBeanReference> namedBeanReference
048                    = new ArrayList<>(listenOnBeans.getReferences());
049
050            namedBeanReference.sort((o1, o2) -> {
051                if (o1.getType() == null) return o2.getType() == null ? 0 : -1;
052                if (o2.getType() == null) return 1;
053
054                int result = o1.getType().toString().compareTo(o2.getType().toString());
055                if (result == 0) {
056                    if (o1.getName() == null) return o2.getName() == null ? 0 : -1;
057                    if (o2.getName() == null) return 1;
058                    result = o1.getName().compareTo(o2.getName());
059                }
060                return result;
061            });
062            _listenOnBeansTableModel = new ListenOnBeansTableModel(namedBeanReference);
063        } else {
064            _listenOnBeansTableModel = new ListenOnBeansTableModel(null);
065        }
066
067        _listenOnBeansTable.setModel(_listenOnBeansTableModel);
068        _listenOnBeansTable.setDefaultRenderer(NamedBeanType.class,
069                new ListenOnBeansTableModel.CellRenderer());
070        _listenOnBeansTable.setDefaultEditor(NamedBeanType.class,
071                new ListenOnBeansTableModel.NamedBeanTypeCellEditor());
072        _listenOnBeansTable.setDefaultEditor(
073                ActionListenOnBeans.NamedBeanReference.class,
074                _listenOnBeansTableModel.getNamedBeanCellEditor());
075        _listenOnBeansTableModel.setColumnsForComboBoxes(_listenOnBeansTable);
076        _listenOnBeansTable.setDefaultRenderer(JButton.class, new ButtonRenderer());
077        _listenOnBeansTable.setDefaultEditor(JButton.class, new ButtonEditor(new JButton()));
078
079        JButton testButton = new JButton("XXXXXX");  // NOI18N
080        _listenOnBeansTable.setRowHeight(testButton.getPreferredSize().height);
081        TableColumn deleteColumn = _listenOnBeansTable.getColumnModel()
082                .getColumn(ListenOnBeansTableModel.COLUMN_DUMMY);
083        deleteColumn.setMinWidth(testButton.getPreferredSize().width);
084        deleteColumn.setMaxWidth(testButton.getPreferredSize().width);
085        deleteColumn.setResizable(false);
086
087        // The dummy column is used to be able to force update of the
088        // other columns when the panel is closed.
089        TableColumn dummyColumn = _listenOnBeansTable.getColumnModel()
090                .getColumn(ListenOnBeansTableModel.COLUMN_DUMMY);
091        dummyColumn.setMinWidth(0);
092        dummyColumn.setPreferredWidth(0);
093        dummyColumn.setMaxWidth(0);
094
095        JScrollPane scrollpane = new JScrollPane(_listenOnBeansTable);
096        scrollpane.setPreferredSize(new Dimension(400, 200));
097        panel.add(scrollpane);
098
099        JPanel localVariableNamedBeanPanel = new JPanel();
100        localVariableNamedBeanPanel.add(new JLabel(Bundle.getMessage("ActionListenOnBeansSwing_LocalVariableNamedBean")));
101        _localVariableNamedBean = new JTextField(20);
102        localVariableNamedBeanPanel.add(_localVariableNamedBean);
103        panel.add(localVariableNamedBeanPanel);
104
105        JPanel localVariableNamedEventPanel = new JPanel();
106        localVariableNamedEventPanel.add(new JLabel(Bundle.getMessage("ActionListenOnBeansSwing_LocalVariableEvent")));
107        _localVariableEvent = new JTextField(20);
108        localVariableNamedEventPanel.add(_localVariableEvent);
109        panel.add(localVariableNamedEventPanel);
110
111        JPanel localVariableNewValuePanel = new JPanel();
112        localVariableNewValuePanel.add(new JLabel(Bundle.getMessage("ActionListenOnBeansSwing_LocalVariableNewValue")));
113        _localVariableNewValue = new JTextField(20);
114        localVariableNewValuePanel.add(_localVariableNewValue);
115        panel.add(localVariableNewValuePanel);
116
117        if (listenOnBeans != null) {
118            _localVariableNamedBean.setText(listenOnBeans.getLocalVariableNamedBean());
119            _localVariableEvent.setText(listenOnBeans.getLocalVariableEvent());
120            _localVariableNewValue.setText(listenOnBeans.getLocalVariableNewValue());
121        }
122
123        // Add parameter
124        JButton add = new JButton(Bundle.getMessage("ActionListenOnBeans_TableAddReference"));
125        buttonPanel.add(add);
126        add.addActionListener((ActionEvent e) -> {
127            _listenOnBeansTableModel.add();
128        });
129    }
130
131    /** {@inheritDoc} */
132    @Override
133    public boolean validate(@Nonnull List<String> errorMessages) {
134        return true;
135    }
136
137    /** {@inheritDoc} */
138    @Override
139    public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) {
140        ActionListenOnBeans action = new ActionListenOnBeans(systemName, userName);
141        updateObject(action);
142        return InstanceManager.getDefault(DigitalActionManager.class).registerAction(action);
143    }
144
145    /** {@inheritDoc} */
146    @Override
147    public void updateObject(@Nonnull Base object) {
148        if (! (object instanceof ActionListenOnBeans)) {
149            throw new IllegalArgumentException("object is not a ActionListenOnBeans: " + object.getClass().getName());
150        }
151        ActionListenOnBeans listenOnBeans = (ActionListenOnBeans)object;
152
153        // Do this to force update of the table
154        _listenOnBeansTable.editCellAt(0, 2);
155
156        listenOnBeans.clearReferences();
157
158        for (NamedBeanReference reference : _listenOnBeansTableModel.getReferences()) {
159            listenOnBeans.addReference(reference);
160        }
161
162        listenOnBeans.setLocalVariableNamedBean(_localVariableNamedBean.getText());
163        listenOnBeans.setLocalVariableEvent(_localVariableEvent.getText());
164        listenOnBeans.setLocalVariableNewValue(_localVariableNewValue.getText());
165    }
166
167    /** {@inheritDoc} */
168    @Override
169    public String toString() {
170        return Bundle.getMessage("ActionListenOnBeans_Short");
171    }
172
173    @Override
174    public void dispose() {
175    }
176
177}