Search in sources :

Example 1 with AbstractCellEditor

use of javax.swing.AbstractCellEditor in project JMRI by JMRI.

the class BlockTableAction method createModel.

/**
     * Create the JTable DataModel, along with the changes for the specific case
     * of Block objects.
     */
@Override
protected void createModel() {
    // load graphic state column display preference
    _graphicState = InstanceManager.getDefault(GuiLafPreferencesManager.class).isGraphicTableState();
    m = new BeanTableDataModel() {

        public static final int EDITCOL = NUMCOLUMN;

        public static final int DIRECTIONCOL = EDITCOL + 1;

        public static final int LENGTHCOL = DIRECTIONCOL + 1;

        public static final int CURVECOL = LENGTHCOL + 1;

        public static final int STATECOL = CURVECOL + 1;

        public static final int SENSORCOL = STATECOL + 1;

        public static final int REPORTERCOL = SENSORCOL + 1;

        public static final int CURRENTREPCOL = REPORTERCOL + 1;

        public static final int PERMISCOL = CURRENTREPCOL + 1;

        public static final int SPEEDCOL = PERMISCOL + 1;

        @Override
        public String getValue(String name) {
            if (name == null) {
                log.warn("requested getValue(null)");
                return "(no name)";
            }
            Block b = InstanceManager.getDefault(jmri.BlockManager.class).getBySystemName(name);
            if (b == null) {
                log.debug("requested getValue(\"" + name + "\"), Block doesn't exist");
                return "(no Block)";
            }
            Object m = b.getValue();
            if (m != null) {
                return m.toString();
            } else {
                return "";
            }
        }

        @Override
        public Manager getManager() {
            return InstanceManager.getDefault(jmri.BlockManager.class);
        }

        @Override
        public NamedBean getBySystemName(String name) {
            return InstanceManager.getDefault(jmri.BlockManager.class).getBySystemName(name);
        }

        @Override
        public NamedBean getByUserName(String name) {
            return InstanceManager.getDefault(jmri.BlockManager.class).getByUserName(name);
        }

        @Override
        protected String getMasterClassName() {
            return getClassName();
        }

        @Override
        public void clickOn(NamedBean t) {
        // don't do anything on click; not used in this class, because 
        // we override setValueAt
        }

        //Permissive and speed columns are temp disabled
        @Override
        public int getColumnCount() {
            return SPEEDCOL + 1;
        }

        @Override
        public Object getValueAt(int row, int col) {
            // some error checking
            if (row >= sysNameList.size()) {
                log.debug("requested getValueAt(\"" + row + "\"), row outside of range");
                return "Error table size";
            }
            Block b = (Block) getBySystemName(sysNameList.get(row));
            if (b == null) {
                log.debug("requested getValueAt(\"" + row + "\"), Block doesn't exist");
                return "(no Block)";
            }
            if (col == DIRECTIONCOL) {
                return jmri.Path.decodeDirection(b.getDirection());
            } else if (col == CURVECOL) {
                JComboBox<String> c = new JComboBox<String>(curveOptions);
                if (b.getCurvature() == Block.NONE) {
                    c.setSelectedItem(0);
                } else if (b.getCurvature() == Block.GRADUAL) {
                    c.setSelectedItem(gradualText);
                } else if (b.getCurvature() == Block.TIGHT) {
                    c.setSelectedItem(tightText);
                } else if (b.getCurvature() == Block.SEVERE) {
                    c.setSelectedItem(severeText);
                }
                return c;
            } else if (col == LENGTHCOL) {
                double len = 0.0;
                if (inchBox.isSelected()) {
                    len = b.getLengthIn();
                } else {
                    len = b.getLengthCm();
                }
                return (twoDigit.format(len));
            } else if (col == PERMISCOL) {
                boolean val = b.getPermissiveWorking();
                return Boolean.valueOf(val);
            } else if (col == SPEEDCOL) {
                String speed = b.getBlockSpeed();
                if (!speedList.contains(speed)) {
                    speedList.add(speed);
                }
                JComboBox<String> c = new JComboBox<String>(speedList);
                c.setEditable(true);
                c.setSelectedItem(speed);
                return c;
            } else if (col == STATECOL) {
                switch(b.getState()) {
                    case (Block.OCCUPIED):
                        return Bundle.getMessage("BlockOccupied");
                    case (Block.UNOCCUPIED):
                        return Bundle.getMessage("BlockUnOccupied");
                    case (Block.UNKNOWN):
                        return Bundle.getMessage("BlockUnknown");
                    default:
                        return Bundle.getMessage("BlockInconsistent");
                }
            } else if (col == SENSORCOL) {
                Sensor sensor = b.getSensor();
                JComboBox<String> c = new JComboBox<String>(sensorList);
                String name = "";
                if (sensor != null) {
                    name = sensor.getDisplayName();
                }
                c.setSelectedItem(name);
                return c;
            } else if (col == REPORTERCOL) {
                Reporter r = b.getReporter();
                return (r != null) ? r.getDisplayName() : null;
            } else if (col == CURRENTREPCOL) {
                return Boolean.valueOf(b.isReportingCurrent());
            } else if (col == EDITCOL) {
                //
                return Bundle.getMessage("ButtonEdit");
            } else {
                return super.getValueAt(row, col);
            }
        }

        @Override
        public void setValueAt(Object value, int row, int col) {
            // no setting of block state from table
            Block b = (Block) getBySystemName(sysNameList.get(row));
            if (col == VALUECOL) {
                b.setValue(value);
                fireTableRowsUpdated(row, row);
            } else if (col == LENGTHCOL) {
                float len = 0.0f;
                try {
                    len = jmri.util.IntlUtilities.floatValue(value.toString());
                } catch (java.text.ParseException ex2) {
                    log.error("Error parsing length value of \"{}\"", value);
                }
                if (inchBox.isSelected()) {
                    b.setLength(len * 25.4f);
                } else {
                    b.setLength(len * 10.0f);
                }
                fireTableRowsUpdated(row, row);
            } else if (col == CURVECOL) {
                @SuppressWarnings("unchecked") String cName = (String) ((JComboBox<String>) value).getSelectedItem();
                if (cName.equals(noneText)) {
                    b.setCurvature(Block.NONE);
                } else if (cName.equals(gradualText)) {
                    b.setCurvature(Block.GRADUAL);
                } else if (cName.equals(tightText)) {
                    b.setCurvature(Block.TIGHT);
                } else if (cName.equals(severeText)) {
                    b.setCurvature(Block.SEVERE);
                }
                fireTableRowsUpdated(row, row);
            } else if (col == PERMISCOL) {
                boolean boo = ((Boolean) value).booleanValue();
                b.setPermissiveWorking(boo);
                fireTableRowsUpdated(row, row);
            } else if (col == SPEEDCOL) {
                @SuppressWarnings("unchecked") String speed = (String) ((JComboBox<String>) value).getSelectedItem();
                try {
                    b.setBlockSpeed(speed);
                } catch (jmri.JmriException ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage() + "\n" + speed);
                    return;
                }
                if (!speedList.contains(speed) && !speed.contains("Global")) {
                    // NOI18N
                    speedList.add(speed);
                }
                fireTableRowsUpdated(row, row);
            } else if (col == REPORTERCOL) {
                Reporter r = null;
                if (value != null && !value.equals("")) {
                    r = jmri.InstanceManager.getDefault(jmri.ReporterManager.class).provideReporter((String) value);
                }
                b.setReporter(r);
                fireTableRowsUpdated(row, row);
            } else if (col == SENSORCOL) {
                @SuppressWarnings("unchecked") String strSensor = (String) ((JComboBox<String>) value).getSelectedItem();
                b.setSensor(strSensor);
                return;
            } else if (col == CURRENTREPCOL) {
                boolean boo = ((Boolean) value).booleanValue();
                b.setReportingCurrent(boo);
                fireTableRowsUpdated(row, row);
            } else if (col == EDITCOL) {
                class WindowMaker implements Runnable {

                    Block b;

                    WindowMaker(Block b) {
                        this.b = b;
                    }

                    @Override
                    public void run() {
                        // don't really want to stop Route w/o user action
                        editButton(b);
                    }
                }
                WindowMaker t = new WindowMaker(b);
                javax.swing.SwingUtilities.invokeLater(t);
            //editButton(b);
            } else {
                super.setValueAt(value, row, col);
            }
        }

        @Override
        public String getColumnName(int col) {
            if (col == DIRECTIONCOL) {
                return Bundle.getMessage("BlockDirection");
            }
            if (col == VALUECOL) {
                return Bundle.getMessage("BlockValue");
            }
            if (col == CURVECOL) {
                return Bundle.getMessage("BlockCurveColName");
            }
            if (col == LENGTHCOL) {
                return Bundle.getMessage("BlockLengthColName");
            }
            if (col == PERMISCOL) {
                return Bundle.getMessage("BlockPermColName");
            }
            if (col == SPEEDCOL) {
                return Bundle.getMessage("BlockSpeedColName");
            }
            if (col == STATECOL) {
                return Bundle.getMessage("BlockState");
            }
            if (col == REPORTERCOL) {
                return Bundle.getMessage("BlockReporter");
            }
            if (col == SENSORCOL) {
                return Bundle.getMessage("BlockSensor");
            }
            if (col == CURRENTREPCOL) {
                return Bundle.getMessage("BlockReporterCurrent");
            }
            if (col == EDITCOL) {
                return Bundle.getMessage("ButtonEdit");
            }
            return super.getColumnName(col);
        }

        @Override
        public Class<?> getColumnClass(int col) {
            if (col == DIRECTIONCOL) {
                return String.class;
            }
            if (col == VALUECOL) {
                // not a button
                return String.class;
            }
            if (col == CURVECOL) {
                return JComboBox.class;
            }
            if (col == LENGTHCOL) {
                return String.class;
            }
            if (col == PERMISCOL) {
                return Boolean.class;
            }
            if (col == SPEEDCOL) {
                return JComboBox.class;
            }
            if (col == STATECOL) {
                if (_graphicState) {
                    // use an image to show block state
                    return JLabel.class;
                } else {
                    return String.class;
                }
            }
            if (col == REPORTERCOL) {
                return String.class;
            }
            if (col == SENSORCOL) {
                return JComboBox.class;
            }
            if (col == CURRENTREPCOL) {
                return Boolean.class;
            }
            if (col == EDITCOL) {
                return JButton.class;
            } else {
                return super.getColumnClass(col);
            }
        }

        @Override
        public int getPreferredWidth(int col) {
            if (col == DIRECTIONCOL) {
                return new JTextField(7).getPreferredSize().width;
            }
            if (col == CURVECOL) {
                return new JTextField(8).getPreferredSize().width;
            }
            if (col == LENGTHCOL) {
                return new JTextField(7).getPreferredSize().width;
            }
            if (col == PERMISCOL) {
                return new JTextField(7).getPreferredSize().width;
            }
            if (col == SPEEDCOL) {
                return new JTextField(7).getPreferredSize().width;
            }
            if (col == STATECOL) {
                return new JTextField(8).getPreferredSize().width;
            }
            if (col == REPORTERCOL) {
                return new JTextField(8).getPreferredSize().width;
            }
            if (col == SENSORCOL) {
                return new JTextField(8).getPreferredSize().width;
            }
            if (col == CURRENTREPCOL) {
                return new JTextField(7).getPreferredSize().width;
            }
            if (col == EDITCOL) {
                return new JTextField(7).getPreferredSize().width;
            } else {
                return super.getPreferredWidth(col);
            }
        }

        @Override
        public void configValueColumn(JTable table) {
        // value column isn't button, so config is null
        }

        @Override
        public boolean isCellEditable(int row, int col) {
            if (col == CURVECOL) {
                return true;
            } else if (col == LENGTHCOL) {
                return true;
            } else if (col == PERMISCOL) {
                return true;
            } else if (col == SPEEDCOL) {
                return true;
            } else if (col == STATECOL) {
                return false;
            } else if (col == REPORTERCOL) {
                return true;
            } else if (col == SENSORCOL) {
                return true;
            } else if (col == CURRENTREPCOL) {
                return true;
            } else if (col == EDITCOL) {
                return true;
            } else {
                return super.isCellEditable(row, col);
            }
        }

        @Override
        public void configureTable(JTable table) {
            table.setDefaultRenderer(JComboBox.class, new jmri.jmrit.symbolicprog.ValueRenderer());
            table.setDefaultEditor(JComboBox.class, new jmri.jmrit.symbolicprog.ValueEditor());
            table.setDefaultRenderer(Boolean.class, new EnablingCheckboxRenderer());
            jmri.InstanceManager.sensorManagerInstance().addPropertyChangeListener(this);
            configStateColumn(table);
            super.configureTable(table);
        }

        @Override
        protected boolean matchPropertyName(java.beans.PropertyChangeEvent e) {
            return true;
        // return (e.getPropertyName().indexOf("alue")>=0);
        }

        @Override
        public JButton configureButton() {
            log.error("configureButton should not have been called");
            return null;
        }

        @Override
        public void propertyChange(java.beans.PropertyChangeEvent e) {
            if (e.getSource() instanceof jmri.SensorManager) {
                if (e.getPropertyName().equals("length") || e.getPropertyName().equals("DisplayListName")) {
                    updateSensorList();
                }
            }
            if (e.getPropertyName().equals("DefaultBlockSpeedChange")) {
                updateSpeedList();
            } else {
                super.propertyChange(e);
            }
        }

        @Override
        protected String getBeanType() {
            return Bundle.getMessage("BeanNameBlock");
        }

        @Override
        public synchronized void dispose() {
            super.dispose();
            jmri.InstanceManager.sensorManagerInstance().removePropertyChangeListener(this);
        }

        /**
             * Customize the block table State column to show an appropriate graphic for the block occupancy state
             * if _graphicState = true, or (default) just show the localized state text
             * when the TableDataModel is being called from ListedTableAction.
             *
             * @param table a JTable of Blocks
             */
        protected void configStateColumn(JTable table) {
            // have the state column hold a JPanel (icon)
            //setColumnToHoldButton(table, VALUECOL, new JLabel("1234")); // for small round icon, but cannot be converted to JButton
            // add extras, override BeanTableDataModel
            log.debug("Block configStateColumn (I am {})", super.toString());
            if (_graphicState) {
                // load icons, only once
                //table.setDefaultEditor(JLabel.class, new ImageIconRenderer()); // there's no editor for state column in BlockTable
                // item class copied from SwitchboardEditor panel
                table.setDefaultRenderer(JLabel.class, new ImageIconRenderer());
            // else, classic text style state indication, do nothing extra
            }
        }

        /**
             * Visualize state in table as a graphic, customized for Blocks (2 states).
             * Renderer and Editor are identical, as the cell contents are not actually edited.
             * @see jmri.jmrit.beantable.sensor.SensorTableDataModel.ImageIconRenderer
             * @see jmri.jmrit.beantable.TurnoutTableAction#createModel()
             * @see jmri.jmrit.beantable.LightTableAction#createModel()
             */
        class ImageIconRenderer extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {

            protected JLabel label;

            // also used in display.switchboardEditor
            protected String rootPath = "resources/icons/misc/switchboard/";

            // reuse Sensor icon for block state
            protected char beanTypeChar = 'S';

            protected String onIconPath = rootPath + beanTypeChar + "-on-s.png";

            protected String offIconPath = rootPath + beanTypeChar + "-off-s.png";

            protected BufferedImage onImage;

            protected BufferedImage offImage;

            protected ImageIcon onIcon;

            protected ImageIcon offIcon;

            protected int iconHeight = -1;

            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                log.debug("Renderer Item = {}, State = {}", row, value);
                if (iconHeight < 0) {
                    // load resources only first time, either for renderer or editor
                    loadIcons();
                    log.debug("icons loaded");
                }
                return updateLabel((String) value, row);
            }

            @Override
            public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
                log.debug("Renderer Item = {}, State = {}", row, value);
                if (iconHeight < 0) {
                    // load resources only first time, either for renderer or editor
                    loadIcons();
                    log.debug("icons loaded");
                }
                return updateLabel((String) value, row);
            }

            public JLabel updateLabel(String value, int row) {
                if (iconHeight > 0) {
                // if necessary, increase row height;
                //table.setRowHeight(row, Math.max(table.getRowHeight(), iconHeight - 5)); // TODO adjust table row height for Block icons
                }
                if (value.equals(Bundle.getMessage("BlockUnOccupied")) && offIcon != null) {
                    label = new JLabel(offIcon);
                    label.setVerticalAlignment(JLabel.BOTTOM);
                    log.debug("offIcon set");
                } else if (value.equals(Bundle.getMessage("BlockOccupied")) && onIcon != null) {
                    label = new JLabel(onIcon);
                    label.setVerticalAlignment(JLabel.BOTTOM);
                    log.debug("onIcon set");
                } else if (value.equals(Bundle.getMessage("BlockInconsistent"))) {
                    // centered text alignment
                    label = new JLabel("X", JLabel.CENTER);
                    label.setForeground(Color.red);
                    log.debug("Block state inconsistent");
                    iconHeight = 0;
                } else if (value.equals(Bundle.getMessage("BlockUnknown"))) {
                    // centered text alignment
                    label = new JLabel("?", JLabel.CENTER);
                    log.debug("Block state in transition");
                    iconHeight = 0;
                } else {
                    // failed to load icon
                    // centered text alignment
                    label = new JLabel(value, JLabel.CENTER);
                    log.warn("Error reading icons for BlockTable");
                    iconHeight = 0;
                }
                label.setToolTipText(value);
                label.addMouseListener(new MouseAdapter() {

                    @Override
                    public final void mousePressed(MouseEvent evt) {
                        log.debug("Clicked on icon in row {}", row);
                        stopCellEditing();
                    }
                });
                return label;
            }

            @Override
            public Object getCellEditorValue() {
                log.debug("getCellEditorValue, me = {})", this.toString());
                return this.toString();
            }

            /**
                 * Read and buffer graphics. Only called once for this table.
                 * @see #getTableCellEditorComponent(JTable, Object, boolean, int, int)
                 */
            protected void loadIcons() {
                try {
                    onImage = ImageIO.read(new File(onIconPath));
                    offImage = ImageIO.read(new File(offIconPath));
                } catch (IOException ex) {
                    log.error("error reading image from {} or {}", onIconPath, offIconPath, ex);
                }
                log.debug("Success reading images");
                int imageWidth = onImage.getWidth();
                int imageHeight = onImage.getHeight();
                // scale icons 50% to fit in table rows
                Image smallOnImage = onImage.getScaledInstance(imageWidth / 2, imageHeight / 2, Image.SCALE_DEFAULT);
                Image smallOffImage = offImage.getScaledInstance(imageWidth / 2, imageHeight / 2, Image.SCALE_DEFAULT);
                onIcon = new ImageIcon(smallOnImage);
                offIcon = new ImageIcon(smallOffImage);
                iconHeight = onIcon.getIconHeight();
            }
        }
    };
// end of custom data model
}
Also used : ImageIcon(javax.swing.ImageIcon) NamedBean(jmri.NamedBean) JButton(javax.swing.JButton) InstanceManager(jmri.InstanceManager) GuiLafPreferencesManager(apps.gui.GuiLafPreferencesManager) Manager(jmri.Manager) JTextField(javax.swing.JTextField) Image(java.awt.Image) BufferedImage(java.awt.image.BufferedImage) BufferedImage(java.awt.image.BufferedImage) AbstractCellEditor(javax.swing.AbstractCellEditor) TableCellEditor(javax.swing.table.TableCellEditor) TableCellRenderer(javax.swing.table.TableCellRenderer) MouseEvent(java.awt.event.MouseEvent) JComboBox(javax.swing.JComboBox) Reporter(jmri.Reporter) MouseAdapter(java.awt.event.MouseAdapter) JLabel(javax.swing.JLabel) IOException(java.io.IOException) JTable(javax.swing.JTable) Block(jmri.Block) File(java.io.File) Sensor(jmri.Sensor)

Example 2 with AbstractCellEditor

use of javax.swing.AbstractCellEditor in project JMRI by JMRI.

the class TurnoutTableAction method createModel.

/**
     * Create the JTable DataModel, along with the changes for the specific case
     * of Turnouts.
     */
@Override
protected void createModel() {
    // store the terminology
    closedText = turnManager.getClosedText();
    thrownText = turnManager.getThrownText();
    // load graphic state column display preference
    // from apps/GuiLafConfigPane.java
    _graphicState = InstanceManager.getDefault(GuiLafPreferencesManager.class).isGraphicTableState();
    // create the data model object that drives the table
    // note that this is a class creation, and very long
    m = new BeanTableDataModel() {

        @Override
        public int getColumnCount() {
            return DIVERGCOL + 1;
        }

        @Override
        public String getColumnName(int col) {
            if (col == INVERTCOL) {
                return Bundle.getMessage("Inverted");
            } else if (col == LOCKCOL) {
                return Bundle.getMessage("Locked");
            } else if (col == KNOWNCOL) {
                return Bundle.getMessage("Feedback");
            } else if (col == MODECOL) {
                return Bundle.getMessage("ModeLabel");
            } else if (col == SENSOR1COL) {
                return Bundle.getMessage("BlockSensor") + "1";
            } else if (col == SENSOR2COL) {
                return Bundle.getMessage("BlockSensor") + "2";
            } else if (col == OPSONOFFCOL) {
                return Bundle.getMessage("TurnoutAutomationMenu");
            } else if (col == OPSEDITCOL) {
                return "";
            } else if (col == LOCKOPRCOL) {
                return Bundle.getMessage("LockMode");
            } else if (col == LOCKDECCOL) {
                return Bundle.getMessage("Decoder");
            } else if (col == DIVERGCOL) {
                return Bundle.getMessage("ThrownSpeed");
            } else if (col == STRAIGHTCOL) {
                return Bundle.getMessage("ClosedSpeed");
            } else if (col == EDITCOL) {
                return "";
            } else {
                return super.getColumnName(col);
            }
        }

        @Override
        public Class<?> getColumnClass(int col) {
            if (col == INVERTCOL) {
                return Boolean.class;
            } else if (col == LOCKCOL) {
                return Boolean.class;
            } else if (col == KNOWNCOL) {
                return String.class;
            } else if (col == MODECOL) {
                return JComboBox.class;
            } else if (col == SENSOR1COL) {
                return JComboBox.class;
            } else if (col == SENSOR2COL) {
                return JComboBox.class;
            } else if (col == OPSONOFFCOL) {
                return JComboBox.class;
            } else if (col == OPSEDITCOL) {
                return JButton.class;
            } else if (col == EDITCOL) {
                return JButton.class;
            } else if (col == LOCKOPRCOL) {
                return JComboBox.class;
            } else if (col == LOCKDECCOL) {
                return JComboBox.class;
            } else if (col == DIVERGCOL) {
                return JComboBox.class;
            } else if (col == STRAIGHTCOL) {
                return JComboBox.class;
            } else if (col == VALUECOL && _graphicState) {
                // use an image to show turnout state
                return JLabel.class;
            } else {
                return super.getColumnClass(col);
            }
        }

        @Override
        public int getPreferredWidth(int col) {
            switch(col) {
                case INVERTCOL:
                    return new JTextField(6).getPreferredSize().width;
                case LOCKCOL:
                    return new JTextField(6).getPreferredSize().width;
                case LOCKOPRCOL:
                    return new JTextField(10).getPreferredSize().width;
                case LOCKDECCOL:
                    return new JTextField(10).getPreferredSize().width;
                case KNOWNCOL:
                    return new JTextField(10).getPreferredSize().width;
                case MODECOL:
                    return new JTextField(10).getPreferredSize().width;
                case SENSOR1COL:
                    return new JTextField(5).getPreferredSize().width;
                case SENSOR2COL:
                    return new JTextField(5).getPreferredSize().width;
                case OPSONOFFCOL:
                    return new JTextField(14).getPreferredSize().width;
                case OPSEDITCOL:
                    return new JTextField(7).getPreferredSize().width;
                case EDITCOL:
                    return new JTextField(7).getPreferredSize().width;
                case DIVERGCOL:
                    return new JTextField(14).getPreferredSize().width;
                case STRAIGHTCOL:
                    return new JTextField(14).getPreferredSize().width;
                default:
                    super.getPreferredWidth(col);
            }
            return super.getPreferredWidth(col);
        }

        @Override
        public boolean isCellEditable(int row, int col) {
            String name = sysNameList.get(row);
            TurnoutManager manager = turnManager;
            Turnout t = manager.getBySystemName(name);
            if (col == INVERTCOL) {
                return t.canInvert();
            } else if (col == LOCKCOL) {
                return t.canLock(Turnout.CABLOCKOUT + Turnout.PUSHBUTTONLOCKOUT);
            } else if (col == KNOWNCOL) {
                return false;
            } else if (col == MODECOL) {
                return true;
            } else if (col == SENSOR1COL) {
                return true;
            } else if (col == SENSOR2COL) {
                return true;
            } else if (col == OPSONOFFCOL) {
                return true;
            } else if (col == OPSEDITCOL) {
                return t.getTurnoutOperation() != null;
            } else if (col == LOCKOPRCOL) {
                return true;
            } else if (col == LOCKDECCOL) {
                return true;
            } else if (col == DIVERGCOL) {
                return true;
            } else if (col == STRAIGHTCOL) {
                return true;
            } else if (col == EDITCOL) {
                return true;
            } else {
                return super.isCellEditable(row, col);
            }
        }

        @Override
        public Object getValueAt(int row, int col) {
            // some error checking
            if (row >= sysNameList.size()) {
                log.debug("row is greater than name list");
                return "error";
            }
            String name = sysNameList.get(row);
            TurnoutManager manager = turnManager;
            Turnout t = manager.getBySystemName(name);
            if (t == null) {
                log.debug("error null turnout!");
                return "error";
            }
            if (col == INVERTCOL) {
                boolean val = t.getInverted();
                return Boolean.valueOf(val);
            } else if (col == LOCKCOL) {
                boolean val = t.getLocked(Turnout.CABLOCKOUT + Turnout.PUSHBUTTONLOCKOUT);
                return Boolean.valueOf(val);
            } else if (col == KNOWNCOL) {
                if (t.getKnownState() == Turnout.CLOSED) {
                    return closedText;
                }
                if (t.getKnownState() == Turnout.THROWN) {
                    return thrownText;
                }
                if (t.getKnownState() == Turnout.INCONSISTENT) {
                    return Bundle.getMessage("BeanStateInconsistent");
                } else {
                    // "Unknown"
                    return Bundle.getMessage("BeanStateUnknown");
                }
            } else if (col == MODECOL) {
                JComboBox<String> c = new JComboBox<String>(t.getValidFeedbackNames());
                c.setSelectedItem(t.getFeedbackModeName());
                c.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        comboBoxAction(e);
                    }
                });
                return c;
            } else if (col == SENSOR1COL) {
                return t.getFirstSensor();
            } else if (col == SENSOR2COL) {
                return t.getSecondSensor();
            } else if (col == OPSONOFFCOL) {
                return makeAutomationBox(t);
            } else if (col == OPSEDITCOL) {
                return Bundle.getMessage("EditTurnoutOperation");
            } else if (col == EDITCOL) {
                return Bundle.getMessage("ButtonEdit");
            } else if (col == LOCKDECCOL) {
                JComboBox<String> c = new JComboBox<String>(t.getValidDecoderNames());
                c.setSelectedItem(t.getDecoderName());
                c.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        comboBoxAction(e);
                    }
                });
                return c;
            } else if (col == LOCKOPRCOL) {
                JComboBox<String> c = new JComboBox<String>(lockOperations);
                if (t.canLock(Turnout.CABLOCKOUT) && t.canLock(Turnout.PUSHBUTTONLOCKOUT)) {
                    c.setSelectedItem(bothText);
                } else if (t.canLock(Turnout.PUSHBUTTONLOCKOUT)) {
                    c.setSelectedItem(pushbutText);
                } else if (t.canLock(Turnout.CABLOCKOUT)) {
                    c.setSelectedItem(cabOnlyText);
                } else {
                    c.setSelectedItem(noneText);
                }
                c.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        comboBoxAction(e);
                    }
                });
                return c;
            } else if (col == STRAIGHTCOL) {
                String speed = t.getStraightSpeed();
                if (!speedListClosed.contains(speed)) {
                    speedListClosed.add(speed);
                }
                JComboBox<String> c = new JComboBox<String>(speedListClosed);
                c.setEditable(true);
                c.setSelectedItem(speed);
                return c;
            } else if (col == DIVERGCOL) {
                String speed = t.getDivergingSpeed();
                if (!speedListThrown.contains(speed)) {
                    speedListThrown.add(speed);
                }
                JComboBox<String> c = new JComboBox<String>(speedListThrown);
                c.setEditable(true);
                c.setSelectedItem(speed);
                return c;
            // } else if (col == VALUECOL && _graphicState) { // not neeeded as the
            //  graphic ImageIconRenderer uses the same super.getValueAt(row, col) as classic bean state text button
            }
            return super.getValueAt(row, col);
        }

        @Override
        public void setValueAt(Object value, int row, int col) {
            String name = sysNameList.get(row);
            TurnoutManager manager = turnManager;
            Turnout t = manager.getBySystemName(name);
            if (col == INVERTCOL) {
                if (t.canInvert()) {
                    boolean b = ((Boolean) value).booleanValue();
                    t.setInverted(b);
                }
            } else if (col == LOCKCOL) {
                boolean b = ((Boolean) value).booleanValue();
                t.setLocked(Turnout.CABLOCKOUT + Turnout.PUSHBUTTONLOCKOUT, b);
            } else if (col == MODECOL) {
                @SuppressWarnings("unchecked") String modeName = (String) ((JComboBox<String>) value).getSelectedItem();
                t.setFeedbackMode(modeName);
            } else if (col == SENSOR1COL) {
                try {
                    t.provideFirstFeedbackSensor((String) value);
                } catch (jmri.JmriException e) {
                    JOptionPane.showMessageDialog(null, e.toString());
                }
                fireTableRowsUpdated(row, row);
            } else if (col == SENSOR2COL) {
                try {
                    t.provideSecondFeedbackSensor((String) value);
                } catch (jmri.JmriException e) {
                    JOptionPane.showMessageDialog(null, e.toString());
                }
                fireTableRowsUpdated(row, row);
            } else if (col == OPSONOFFCOL) {
            // do nothing as this is handled by the combo box listener
            } else if (col == OPSEDITCOL) {
                t.setInhibitOperation(false);
                // cast to JComboBox<String> required in OPSEDITCOL
                @SuppressWarnings("unchecked") JComboBox<String> cb = (JComboBox<String>) getValueAt(row, OPSONOFFCOL);
                log.debug("opsSelected = {}", getValueAt(row, OPSONOFFCOL).toString());
                editTurnoutOperation(t, cb);
            } else if (col == EDITCOL) {
                class WindowMaker implements Runnable {

                    Turnout t;

                    WindowMaker(Turnout t) {
                        this.t = t;
                    }

                    @Override
                    public void run() {
                        editButton(t);
                    }
                }
                WindowMaker w = new WindowMaker(t);
                javax.swing.SwingUtilities.invokeLater(w);
            } else if (col == LOCKOPRCOL) {
                @SuppressWarnings("unchecked") String lockOpName = (String) ((JComboBox<String>) value).getSelectedItem();
                if (lockOpName.equals(bothText)) {
                    t.enableLockOperation(Turnout.CABLOCKOUT + Turnout.PUSHBUTTONLOCKOUT, true);
                }
                if (lockOpName.equals(cabOnlyText)) {
                    t.enableLockOperation(Turnout.CABLOCKOUT, true);
                    t.enableLockOperation(Turnout.PUSHBUTTONLOCKOUT, false);
                }
                if (lockOpName.equals(pushbutText)) {
                    t.enableLockOperation(Turnout.CABLOCKOUT, false);
                    t.enableLockOperation(Turnout.PUSHBUTTONLOCKOUT, true);
                }
            } else if (col == LOCKDECCOL) {
                @SuppressWarnings("unchecked") String decoderName = (String) ((JComboBox<String>) value).getSelectedItem();
                t.setDecoderName(decoderName);
            } else if (col == STRAIGHTCOL) {
                @SuppressWarnings("unchecked") String speed = (String) ((JComboBox<String>) value).getSelectedItem();
                try {
                    t.setStraightSpeed(speed);
                } catch (jmri.JmriException ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage() + "\n" + speed);
                    return;
                }
                if ((!speedListClosed.contains(speed)) && !speed.contains("Global")) {
                    speedListClosed.add(speed);
                }
                fireTableRowsUpdated(row, row);
            } else if (col == DIVERGCOL) {
                @SuppressWarnings("unchecked") String speed = (String) ((JComboBox<String>) value).getSelectedItem();
                try {
                    t.setDivergingSpeed(speed);
                } catch (jmri.JmriException ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage() + "\n" + speed);
                    return;
                }
                if ((!speedListThrown.contains(speed)) && !speed.contains("Global")) {
                    speedListThrown.add(speed);
                }
                fireTableRowsUpdated(row, row);
            } else if (col == VALUECOL && _graphicState) {
                // respond to clicking on ImageIconRenderer CellEditor
                clickOn(t);
                fireTableRowsUpdated(row, row);
            } else {
                super.setValueAt(value, row, col);
            }
        }

        @Override
        public String getValue(String name) {
            int val = turnManager.getBySystemName(name).getCommandedState();
            switch(val) {
                case Turnout.CLOSED:
                    return closedText;
                case Turnout.THROWN:
                    return thrownText;
                case Turnout.UNKNOWN:
                    return Bundle.getMessage("BeanStateUnknown");
                case Turnout.INCONSISTENT:
                    return Bundle.getMessage("BeanStateInconsistent");
                default:
                    return "Unexpected value: " + val;
            }
        }

        @Override
        public Manager getManager() {
            return turnManager;
        }

        @Override
        public NamedBean getBySystemName(String name) {
            return turnManager.getBySystemName(name);
        }

        @Override
        public NamedBean getByUserName(String name) {
            return turnManager.getByUserName(name);
        }

        @Override
        protected String getMasterClassName() {
            return getClassName();
        }

        @Override
        public void clickOn(NamedBean t) {
            int state = ((Turnout) t).getCommandedState();
            if (state == Turnout.CLOSED) {
                ((Turnout) t).setCommandedState(Turnout.THROWN);
            } else {
                ((Turnout) t).setCommandedState(Turnout.CLOSED);
            }
        }

        @Override
        public void configureTable(JTable tbl) {
            table = tbl;
            table.setDefaultRenderer(Boolean.class, new EnablingCheckboxRenderer());
            table.setDefaultRenderer(JComboBox.class, new jmri.jmrit.symbolicprog.ValueRenderer());
            table.setDefaultEditor(JComboBox.class, new jmri.jmrit.symbolicprog.ValueEditor());
            setColumnToHoldButton(table, OPSEDITCOL, editButton());
            setColumnToHoldButton(table, EDITCOL, editButton());
            //Hide the following columns by default
            XTableColumnModel columnModel = (XTableColumnModel) table.getColumnModel();
            TableColumn column = columnModel.getColumnByModelIndex(STRAIGHTCOL);
            columnModel.setColumnVisible(column, false);
            column = columnModel.getColumnByModelIndex(DIVERGCOL);
            columnModel.setColumnVisible(column, false);
            column = columnModel.getColumnByModelIndex(KNOWNCOL);
            columnModel.setColumnVisible(column, false);
            column = columnModel.getColumnByModelIndex(MODECOL);
            columnModel.setColumnVisible(column, false);
            column = columnModel.getColumnByModelIndex(SENSOR1COL);
            columnModel.setColumnVisible(column, false);
            column = columnModel.getColumnByModelIndex(SENSOR2COL);
            columnModel.setColumnVisible(column, false);
            column = columnModel.getColumnByModelIndex(OPSONOFFCOL);
            columnModel.setColumnVisible(column, false);
            column = columnModel.getColumnByModelIndex(OPSEDITCOL);
            columnModel.setColumnVisible(column, false);
            column = columnModel.getColumnByModelIndex(LOCKOPRCOL);
            columnModel.setColumnVisible(column, false);
            column = columnModel.getColumnByModelIndex(LOCKDECCOL);
            columnModel.setColumnVisible(column, false);
            super.configureTable(table);
        }

        // update table if turnout lock or feedback changes
        @Override
        protected boolean matchPropertyName(java.beans.PropertyChangeEvent e) {
            if (e.getPropertyName().equals("locked")) {
                return true;
            }
            if (e.getPropertyName().equals("feedbackchange")) {
                return true;
            }
            if (e.getPropertyName().equals("TurnoutDivergingSpeedChange")) {
                return true;
            }
            if (e.getPropertyName().equals("TurnoutStraightSpeedChange")) {
                return true;
            } else {
                return super.matchPropertyName(e);
            }
        }

        public void comboBoxAction(ActionEvent e) {
            if (log.isDebugEnabled()) {
                log.debug("Combobox change");
            }
            if (table != null && table.getCellEditor() != null) {
                table.getCellEditor().stopCellEditing();
            }
        }

        @Override
        public void propertyChange(java.beans.PropertyChangeEvent e) {
            if (e.getPropertyName().equals("DefaultTurnoutClosedSpeedChange")) {
                updateClosedList();
            } else if (e.getPropertyName().equals("DefaultTurnoutThrownSpeedChange")) {
                updateThrownList();
            } else {
                super.propertyChange(e);
            }
        }

        @Override
        protected String getBeanType() {
            return Bundle.getMessage("BeanNameTurnout");
        }

        /**
             * Customize the turnout table Value (State) column to show an appropriate graphic for the turnout state
             * if _graphicState = true, or (default) just show the localized state text
             * when the TableDataModel is being called from ListedTableAction.
             *
             * @param table a JTable of Turnouts
             */
        @Override
        protected void configValueColumn(JTable table) {
            // have the value column hold a JPanel (icon)
            //setColumnToHoldButton(table, VALUECOL, new JLabel("12345678")); // for larger, wide round icon, but cannot be converted to JButton
            // add extras, override BeanTableDataModel
            log.debug("Turnout configValueColumn (I am {})", super.toString());
            if (_graphicState) {
                // load icons, only once
                // editor
                table.setDefaultEditor(JLabel.class, new ImageIconRenderer());
                // item class copied from SwitchboardEditor panel
                table.setDefaultRenderer(JLabel.class, new ImageIconRenderer());
            } else {
                // classic text style state indication
                super.configValueColumn(table);
            }
        }

        @Override
        public JTable makeJTable(@Nonnull String name, @Nonnull TableModel model, @Nullable RowSorter<? extends TableModel> sorter) {
            JTable table = this.makeJTable(model);
            table.setName(name);
            table.setRowSorter(sorter);
            table.getTableHeader().setReorderingAllowed(true);
            table.setColumnModel(new XTableColumnModel());
            table.createDefaultColumnsFromModel();
            addMouseListenerToHeader(table);
            return table;
        }

        @Override
        public JTable makeJTable(TableSorter sorter) {
            JTable table = this.makeJTable((TableModel) sorter);
            table.getTableHeader().setReorderingAllowed(true);
            table.setColumnModel(new XTableColumnModel());
            table.createDefaultColumnsFromModel();
            addMouseListenerToHeader(table);
            return table;
        }

        private JTable makeJTable(TableModel model) {
            return new JTable(model) {

                @Override
                public TableCellRenderer getCellRenderer(int row, int column) {
                    // Convert the displayed index to the model index, rather than the displayed index
                    int modelColumn = this.convertColumnIndexToModel(column);
                    if (modelColumn == SENSOR1COL || modelColumn == SENSOR2COL) {
                        return getRenderer(row, modelColumn);
                    } else {
                        return super.getCellRenderer(row, column);
                    }
                }

                @Override
                public TableCellEditor getCellEditor(int row, int column) {
                    //Convert the displayed index to the model index, rather than the displayed index
                    int modelColumn = this.convertColumnIndexToModel(column);
                    if (modelColumn == SENSOR1COL || modelColumn == SENSOR2COL) {
                        return getEditor(row, modelColumn);
                    } else {
                        return super.getCellEditor(row, column);
                    }
                }

                TableCellRenderer getRenderer(int row, int column) {
                    TableCellRenderer retval = null;
                    if (column == SENSOR1COL) {
                        retval = rendererMapSensor1.get(getModel().getValueAt(row, SYSNAMECOL));
                    } else if (column == SENSOR2COL) {
                        retval = rendererMapSensor2.get(getModel().getValueAt(row, SYSNAMECOL));
                    } else {
                        return null;
                    }
                    if (retval == null) {
                        Turnout t = turnManager.getBySystemName((String) getModel().getValueAt(row, SYSNAMECOL));
                        if (t == null) {
                            return null;
                        }
                        retval = new BeanBoxRenderer();
                        if (column == SENSOR1COL) {
                            ((JmriBeanComboBox) retval).setSelectedBean(t.getFirstSensor());
                            rendererMapSensor1.put(getModel().getValueAt(row, SYSNAMECOL), retval);
                        } else {
                            ((JmriBeanComboBox) retval).setSelectedBean(t.getSecondSensor());
                            rendererMapSensor2.put(getModel().getValueAt(row, SYSNAMECOL), retval);
                        }
                    }
                    return retval;
                }

                Hashtable<Object, TableCellRenderer> rendererMapSensor1 = new Hashtable<>();

                Hashtable<Object, TableCellRenderer> rendererMapSensor2 = new Hashtable<>();

                TableCellEditor getEditor(int row, int column) {
                    TableCellEditor retval = null;
                    switch(column) {
                        case SENSOR1COL:
                            retval = editorMapSensor1.get(getModel().getValueAt(row, SYSNAMECOL));
                            break;
                        case SENSOR2COL:
                            retval = editorMapSensor2.get(getModel().getValueAt(row, SYSNAMECOL));
                            break;
                        default:
                            return null;
                    }
                    if (retval == null) {
                        Turnout t = turnManager.getBySystemName((String) getModel().getValueAt(row, SYSNAMECOL));
                        if (t == null) {
                            return null;
                        }
                        JmriBeanComboBox c;
                        if (column == SENSOR1COL) {
                            c = new JmriBeanComboBox(InstanceManager.sensorManagerInstance(), t.getFirstSensor(), JmriBeanComboBox.DisplayOptions.DISPLAYNAME);
                            retval = new BeanComboBoxEditor(c);
                            editorMapSensor1.put(getModel().getValueAt(row, SYSNAMECOL), retval);
                        } else {
                            //Must be two
                            c = new JmriBeanComboBox(InstanceManager.sensorManagerInstance(), t.getSecondSensor(), JmriBeanComboBox.DisplayOptions.DISPLAYNAME);
                            retval = new BeanComboBoxEditor(c);
                            editorMapSensor2.put(getModel().getValueAt(row, SYSNAMECOL), retval);
                        }
                        c.setFirstItemBlank(true);
                    }
                    return retval;
                }

                Hashtable<Object, TableCellEditor> editorMapSensor1 = new Hashtable<>();

                Hashtable<Object, TableCellEditor> editorMapSensor2 = new Hashtable<>();
            };
        }

        /**
             * Visualize state in table as a graphic, customized for Turnouts (4 states).
             * Renderer and Editor are identical, as the cell contents are not actually edited,
             * only used to toggle state using {@link #clickOn(NamedBean)}.
             * @see jmri.jmrit.beantable.sensor.SensorTableDataModel.ImageIconRenderer
             * @see jmri.jmrit.beantable.BlockTableAction#createModel()
             * @see jmri.jmrit.beantable.LightTableAction#createModel()
             */
        class ImageIconRenderer extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {

            protected JLabel label;

            // also used in display.switchboardEditor
            protected String rootPath = "resources/icons/misc/switchboard/";

            // for Turnout
            protected char beanTypeChar = 'T';

            protected String onIconPath = rootPath + beanTypeChar + "-on-s.png";

            protected String offIconPath = rootPath + beanTypeChar + "-off-s.png";

            protected BufferedImage onImage;

            protected BufferedImage offImage;

            protected ImageIcon onIcon;

            protected ImageIcon offIcon;

            protected int iconHeight = -1;

            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                log.debug("Renderer Item = {}, State = {}", row, value);
                if (iconHeight < 0) {
                    // load resources only first time, either for renderer or editor
                    loadIcons();
                    log.debug("icons loaded");
                }
                return updateLabel((String) value, row);
            }

            @Override
            public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
                log.debug("Renderer Item = {}, State = {}", row, value);
                if (iconHeight < 0) {
                    // load resources only first time, either for renderer or editor
                    loadIcons();
                    log.debug("icons loaded");
                }
                return updateLabel((String) value, row);
            }

            public JLabel updateLabel(String value, int row) {
                if (iconHeight > 0) {
                    // if necessary, increase row height;
                    table.setRowHeight(row, Math.max(table.getRowHeight(), iconHeight - 5));
                }
                if (value.equals(closedText) && offIcon != null) {
                    label = new JLabel(offIcon);
                    label.setVerticalAlignment(JLabel.BOTTOM);
                    log.debug("offIcon set");
                } else if (value.equals(thrownText) && onIcon != null) {
                    label = new JLabel(onIcon);
                    label.setVerticalAlignment(JLabel.BOTTOM);
                    log.debug("onIcon set");
                } else if (value.equals(Bundle.getMessage("BeanStateInconsistent"))) {
                    // centered text alignment
                    label = new JLabel("X", JLabel.CENTER);
                    label.setForeground(Color.red);
                    log.debug("Turnout state inconsistent");
                    iconHeight = 0;
                } else if (value.equals(Bundle.getMessage("BeanStateUnknown"))) {
                    // centered text alignment
                    label = new JLabel("?", JLabel.CENTER);
                    log.debug("Turnout state unknown");
                    iconHeight = 0;
                } else {
                    // failed to load icon
                    // centered text alignment
                    label = new JLabel(value, JLabel.CENTER);
                    log.warn("Error reading icons for TurnoutTable");
                    iconHeight = 0;
                }
                label.setToolTipText(value);
                label.addMouseListener(new MouseAdapter() {

                    @Override
                    public final void mousePressed(MouseEvent evt) {
                        log.debug("Clicked on icon in row {}", row);
                        stopCellEditing();
                    }
                });
                return label;
            }

            @Override
            public Object getCellEditorValue() {
                log.debug("getCellEditorValue, me = {})", this.toString());
                return this.toString();
            }

            /**
                 * Read and buffer graphics. Only called once for this table.
                 * @see #getTableCellEditorComponent(JTable, Object, boolean, int, int)
                 */
            protected void loadIcons() {
                try {
                    onImage = ImageIO.read(new File(onIconPath));
                    offImage = ImageIO.read(new File(offIconPath));
                } catch (IOException ex) {
                    log.error("error reading image from {} or {}", onIconPath, offIconPath, ex);
                }
                log.debug("Success reading images");
                int imageWidth = onImage.getWidth();
                int imageHeight = onImage.getHeight();
                // scale icons 50% to fit in table rows
                Image smallOnImage = onImage.getScaledInstance(imageWidth / 2, imageHeight / 2, Image.SCALE_DEFAULT);
                Image smallOffImage = offImage.getScaledInstance(imageWidth / 2, imageHeight / 2, Image.SCALE_DEFAULT);
                onIcon = new ImageIcon(smallOnImage);
                offIcon = new ImageIcon(smallOffImage);
                iconHeight = onIcon.getIconHeight();
            }
        }
    };
// end of custom data model
}
Also used : ActionEvent(java.awt.event.ActionEvent) TurnoutOperationManager(jmri.TurnoutOperationManager) InstanceManager(jmri.InstanceManager) TurnoutManager(jmri.TurnoutManager) GuiLafPreferencesManager(apps.gui.GuiLafPreferencesManager) Manager(jmri.Manager) Image(java.awt.Image) BufferedImage(java.awt.image.BufferedImage) JmriBeanComboBox(jmri.util.swing.JmriBeanComboBox) TableCellEditor(javax.swing.table.TableCellEditor) TableCellRenderer(javax.swing.table.TableCellRenderer) TableColumn(javax.swing.table.TableColumn) ActionListener(java.awt.event.ActionListener) JTable(javax.swing.JTable) Turnout(jmri.Turnout) File(java.io.File) TableModel(javax.swing.table.TableModel) TableSorter(jmri.util.com.sun.TableSorter) ImageIcon(javax.swing.ImageIcon) NamedBean(jmri.NamedBean) JButton(javax.swing.JButton) JTextField(javax.swing.JTextField) BufferedImage(java.awt.image.BufferedImage) AbstractCellEditor(javax.swing.AbstractCellEditor) MouseEvent(java.awt.event.MouseEvent) JComboBox(javax.swing.JComboBox) Hashtable(java.util.Hashtable) MouseAdapter(java.awt.event.MouseAdapter) JLabel(javax.swing.JLabel) IOException(java.io.IOException) XTableColumnModel(jmri.util.swing.XTableColumnModel) TurnoutManager(jmri.TurnoutManager)

Example 3 with AbstractCellEditor

use of javax.swing.AbstractCellEditor in project JMRI by JMRI.

the class LightTableAction method createModel.

/**
     * Create the JTable DataModel, along with the changes for the specific case
     * of Lights.
     */
@Override
protected void createModel() {
    // load graphic state column display preference
    _graphicState = InstanceManager.getDefault(GuiLafPreferencesManager.class).isGraphicTableState();
    m = new BeanTableDataModel() {

        public static final int ENABLECOL = NUMCOLUMN;

        public static final int INTENSITYCOL = ENABLECOL + 1;

        public static final int EDITCOL = INTENSITYCOL + 1;

        protected String enabledString = Bundle.getMessage("ColumnHeadEnabled");

        protected String intensityString = Bundle.getMessage("ColumnHeadIntensity");

        @Override
        public int getColumnCount() {
            return NUMCOLUMN + 3;
        }

        @Override
        public String getColumnName(int col) {
            if (col == EDITCOL) {
                // no heading on "Edit"
                return "";
            }
            if (col == INTENSITYCOL) {
                return intensityString;
            }
            if (col == ENABLECOL) {
                return enabledString;
            } else {
                return super.getColumnName(col);
            }
        }

        @Override
        public Class<?> getColumnClass(int col) {
            if (col == EDITCOL) {
                return JButton.class;
            }
            if (col == INTENSITYCOL) {
                return Double.class;
            }
            if (col == ENABLECOL) {
                return Boolean.class;
            } else if (col == VALUECOL && _graphicState) {
                // use an image to show light state
                return JLabel.class;
            } else {
                return super.getColumnClass(col);
            }
        }

        @Override
        public int getPreferredWidth(int col) {
            // override default value for UserName column
            if (col == USERNAMECOL) {
                return new JTextField(16).getPreferredSize().width;
            }
            if (col == EDITCOL) {
                return new JTextField(6).getPreferredSize().width;
            }
            if (col == INTENSITYCOL) {
                return new JTextField(6).getPreferredSize().width;
            }
            if (col == ENABLECOL) {
                return new JTextField(6).getPreferredSize().width;
            } else {
                return super.getPreferredWidth(col);
            }
        }

        @Override
        public boolean isCellEditable(int row, int col) {
            if (col == EDITCOL) {
                return true;
            }
            if (col == INTENSITYCOL) {
                return ((Light) getBySystemName((String) getValueAt(row, SYSNAMECOL))).isIntensityVariable();
            }
            if (col == ENABLECOL) {
                return true;
            } else {
                return super.isCellEditable(row, col);
            }
        }

        @Override
        public String getValue(String name) {
            Light l = lightManager.getBySystemName(name);
            if (l == null) {
                return ("Failed to find " + name);
            }
            int val = l.getState();
            switch(val) {
                case Light.ON:
                    return Bundle.getMessage("LightStateOn");
                case Light.INTERMEDIATE:
                    return Bundle.getMessage("LightStateIntermediate");
                case Light.OFF:
                    return Bundle.getMessage("LightStateOff");
                case Light.TRANSITIONINGTOFULLON:
                    return Bundle.getMessage("LightStateTransitioningToFullOn");
                case Light.TRANSITIONINGHIGHER:
                    return Bundle.getMessage("LightStateTransitioningHigher");
                case Light.TRANSITIONINGLOWER:
                    return Bundle.getMessage("LightStateTransitioningLower");
                case Light.TRANSITIONINGTOFULLOFF:
                    return Bundle.getMessage("LightStateTransitioningToFullOff");
                default:
                    return "Unexpected value: " + val;
            }
        }

        @Override
        public Object getValueAt(int row, int col) {
            switch(col) {
                case EDITCOL:
                    return Bundle.getMessage("ButtonEdit");
                case INTENSITYCOL:
                    return ((Light) getBySystemName((String) getValueAt(row, SYSNAMECOL))).getTargetIntensity();
                case ENABLECOL:
                    return ((Light) getBySystemName((String) getValueAt(row, SYSNAMECOL))).getEnabled();
                default:
                    return super.getValueAt(row, col);
            }
        }

        @Override
        public void setValueAt(Object value, int row, int col) {
            switch(col) {
                case EDITCOL:
                    // Use separate Runnable so window is created on top
                    class WindowMaker implements Runnable {

                        int row;

                        WindowMaker(int r) {
                            row = r;
                        }

                        @Override
                        public void run() {
                            // set up to edit
                            addPressed(null);
                            fixedSystemName.setText((String) getValueAt(row, SYSNAMECOL));
                            // don't really want to stop Light w/o user action
                            editPressed();
                        }
                    }
                    WindowMaker t = new WindowMaker(row);
                    javax.swing.SwingUtilities.invokeLater(t);
                    break;
                case INTENSITYCOL:
                    // alternate
                    try {
                        Light l = (Light) getBySystemName((String) getValueAt(row, SYSNAMECOL));
                        double intensity = ((Double) value);
                        if (intensity < 0) {
                            intensity = 0;
                        }
                        if (intensity > 1.0) {
                            intensity = 1.0;
                        }
                        l.setTargetIntensity(intensity);
                    } catch (IllegalArgumentException e1) {
                        status1.setText(Bundle.getMessage("LightError16"));
                    }
                    break;
                case ENABLECOL:
                    // alternate
                    Light l = (Light) getBySystemName((String) getValueAt(row, SYSNAMECOL));
                    boolean v = l.getEnabled();
                    l.setEnabled(!v);
                    break;
                case VALUECOL:
                    if (_graphicState) {
                        // respond to clicking on ImageIconRenderer CellEditor
                        Light ll = (Light) getBySystemName((String) getValueAt(row, SYSNAMECOL));
                        clickOn(ll);
                        fireTableRowsUpdated(row, row);
                        break;
                    }
                //$FALL-THROUGH$
                default:
                    super.setValueAt(value, row, col);
                    break;
            }
        }

        /**
             * Delete the bean after all the checking has been done.
             * <P>
             * Deactivate the light, then use the superclass to delete it.
             */
        @Override
        void doDelete(NamedBean bean) {
            ((Light) bean).deactivateLight();
            super.doDelete(bean);
        }

        // all properties update for now
        @Override
        protected boolean matchPropertyName(java.beans.PropertyChangeEvent e) {
            return true;
        }

        @Override
        public Manager getManager() {
            return lightManager;
        }

        @Override
        public NamedBean getBySystemName(String name) {
            return lightManager.getBySystemName(name);
        }

        @Override
        public NamedBean getByUserName(String name) {
            return lightManager.getByUserName(name);
        }

        @Override
        protected String getMasterClassName() {
            return getClassName();
        }

        @Override
        public void clickOn(NamedBean t) {
            int oldState = ((Light) t).getState();
            int newState;
            switch(oldState) {
                case Light.ON:
                    newState = Light.OFF;
                    break;
                case Light.OFF:
                    newState = Light.ON;
                    break;
                default:
                    newState = Light.OFF;
                    log.warn("Unexpected Light state " + oldState + " becomes OFF");
                    break;
            }
            ((Light) t).setState(newState);
        }

        @Override
        public JButton configureButton() {
            return new JButton(" " + Bundle.getMessage("LightStateOff") + " ");
        }

        @Override
        protected String getBeanType() {
            return Bundle.getMessage("BeanNameLight");
        }

        /**
             * Customize the light table Value (State) column to show an appropriate graphic for the light state
             * if _graphicState = true, or (default) just show the localized state text
             * when the TableDataModel is being called from ListedTableAction.
             *
             * @param table a JTable of Lights
             */
        @Override
        protected void configValueColumn(JTable table) {
            // have the value column hold a JPanel (icon)
            //setColumnToHoldButton(table, VALUECOL, new JLabel("123456")); // for small round icon, but cannot be converted to JButton
            // add extras, override BeanTableDataModel
            log.debug("Light configValueColumn (I am {})", super.toString());
            if (_graphicState) {
                // load icons, only once
                // editor
                table.setDefaultEditor(JLabel.class, new ImageIconRenderer());
                // item class copied from SwitchboardEditor panel
                table.setDefaultRenderer(JLabel.class, new ImageIconRenderer());
            } else {
                // classic text style state indication
                super.configValueColumn(table);
            }
        }

        /**
             * Visualize state in table as a graphic, customized for Lights (2 states + ... for transitioning).
             * Renderer and Editor are identical, as the cell contents are not actually edited,
             * only used to toggle state using {@link #clickOn(NamedBean)}.
             * @see jmri.jmrit.beantable.sensor.SensorTableDataModel.ImageIconRenderer
             * @see jmri.jmrit.beantable.BlockTableAction#createModel()
             * @see jmri.jmrit.beantable.TurnoutTableAction#createModel()
             */
        class ImageIconRenderer extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {

            protected JLabel label;

            // also used in display.switchboardEditor
            protected String rootPath = "resources/icons/misc/switchboard/";

            // for Light
            protected char beanTypeChar = 'L';

            protected String onIconPath = rootPath + beanTypeChar + "-on-s.png";

            protected String offIconPath = rootPath + beanTypeChar + "-off-s.png";

            protected BufferedImage onImage;

            protected BufferedImage offImage;

            protected ImageIcon onIcon;

            protected ImageIcon offIcon;

            protected int iconHeight = -1;

            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                log.debug("Renderer Item = {}, State = {}", row, value);
                if (iconHeight < 0) {
                    // load resources only first time, either for renderer or editor
                    loadIcons();
                    log.debug("icons loaded");
                }
                return updateLabel((String) value, row);
            }

            @Override
            public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
                log.debug("Renderer Item = {}, State = {}", row, value);
                if (iconHeight < 0) {
                    // load resources only first time, either for renderer or editor
                    loadIcons();
                    log.debug("icons loaded");
                }
                return updateLabel((String) value, row);
            }

            public JLabel updateLabel(String value, int row) {
                if (iconHeight > 0) {
                // if necessary, increase row height;
                //table.setRowHeight(row, Math.max(table.getRowHeight(), iconHeight - 5)); // TODO adjust table row height for Lights
                }
                if (value.equals(Bundle.getMessage("LightStateOff")) && offIcon != null) {
                    label = new JLabel(offIcon);
                    label.setVerticalAlignment(JLabel.BOTTOM);
                    log.debug("offIcon set");
                } else if (value.equals(Bundle.getMessage("LightStateOn")) && onIcon != null) {
                    label = new JLabel(onIcon);
                    label.setVerticalAlignment(JLabel.BOTTOM);
                    log.debug("onIcon set");
                } else if (value.equals(Bundle.getMessage("BeanStateInconsistent"))) {
                    // centered text alignment
                    label = new JLabel("X", JLabel.CENTER);
                    label.setForeground(Color.red);
                    log.debug("Light state inconsistent");
                    iconHeight = 0;
                } else if (value.equals(Bundle.getMessage("LightStateIntermediate"))) {
                    // centered text alignment
                    label = new JLabel("...", JLabel.CENTER);
                    log.debug("Light state in transition");
                    iconHeight = 0;
                } else {
                    // failed to load icon
                    // centered text alignment
                    label = new JLabel(value, JLabel.CENTER);
                    log.warn("Error reading icons for LightTable");
                    iconHeight = 0;
                }
                label.setToolTipText(value);
                label.addMouseListener(new MouseAdapter() {

                    @Override
                    public final void mousePressed(MouseEvent evt) {
                        log.debug("Clicked on icon in row {}", row);
                        stopCellEditing();
                    }
                });
                return label;
            }

            @Override
            public Object getCellEditorValue() {
                log.debug("getCellEditorValue, me = {})", this.toString());
                return this.toString();
            }

            /**
                 * Read and buffer graphics. Only called once for this table.
                 * @see #getTableCellEditorComponent(JTable, Object, boolean, int, int)
                 */
            protected void loadIcons() {
                try {
                    onImage = ImageIO.read(new File(onIconPath));
                    offImage = ImageIO.read(new File(offIconPath));
                } catch (IOException ex) {
                    log.error("error reading image from {} or {}", onIconPath, offIconPath, ex);
                }
                log.debug("Success reading images");
                int imageWidth = onImage.getWidth();
                int imageHeight = onImage.getHeight();
                // scale icons 50% to fit in table rows
                Image smallOnImage = onImage.getScaledInstance(imageWidth / 2, imageHeight / 2, Image.SCALE_DEFAULT);
                Image smallOffImage = offImage.getScaledInstance(imageWidth / 2, imageHeight / 2, Image.SCALE_DEFAULT);
                onIcon = new ImageIcon(smallOnImage);
                offIcon = new ImageIcon(smallOffImage);
                iconHeight = onIcon.getIconHeight();
            }
        }
    };
// end of custom data model
}
Also used : ImageIcon(javax.swing.ImageIcon) NamedBean(jmri.NamedBean) JButton(javax.swing.JButton) JTextField(javax.swing.JTextField) LightManager(jmri.LightManager) InstanceManager(jmri.InstanceManager) GuiLafPreferencesManager(apps.gui.GuiLafPreferencesManager) Manager(jmri.Manager) Image(java.awt.Image) BufferedImage(java.awt.image.BufferedImage) BufferedImage(java.awt.image.BufferedImage) Light(jmri.Light) AbstractCellEditor(javax.swing.AbstractCellEditor) TableCellEditor(javax.swing.table.TableCellEditor) TableCellRenderer(javax.swing.table.TableCellRenderer) MouseEvent(java.awt.event.MouseEvent) MouseAdapter(java.awt.event.MouseAdapter) JLabel(javax.swing.JLabel) IOException(java.io.IOException) JTable(javax.swing.JTable) File(java.io.File)

Example 4 with AbstractCellEditor

use of javax.swing.AbstractCellEditor in project gate-core by GateNLP.

the class LuceneDataStoreSearchGUI method initGui.

/**
 * Initialize the GUI.
 */
protected void initGui() {
    // see the global layout schema at the end
    setLayout(new BorderLayout());
    stringCollator = java.text.Collator.getInstance();
    stringCollator.setStrength(java.text.Collator.TERTIARY);
    Comparator<String> lastWordComparator = new Comparator<String>() {

        @Override
        public int compare(String o1, String o2) {
            if (o1 == null || o2 == null) {
                return 0;
            }
            return stringCollator.compare(o1.substring(o1.trim().lastIndexOf(' ') + 1), o2.substring(o2.trim().lastIndexOf(' ') + 1));
        }
    };
    integerComparator = new Comparator<Integer>() {

        @Override
        public int compare(Integer o1, Integer o2) {
            if (o1 == null || o2 == null) {
                return 0;
            }
            return o1.compareTo(o2);
        }
    };
    /**
     ********************************
     * Stack view configuration frame *
     *********************************
     */
    configureStackViewFrame = new ConfigureStackViewFrame("Stack view configuration");
    configureStackViewFrame.setIconImage(((ImageIcon) MainFrame.getIcon("WindowNew")).getImage());
    configureStackViewFrame.setLocationRelativeTo(LuceneDataStoreSearchGUI.this);
    configureStackViewFrame.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("ESCAPE"), "close row manager");
    configureStackViewFrame.getRootPane().getActionMap().put("close row manager", new AbstractAction() {

        @Override
        public void actionPerformed(ActionEvent e) {
            configureStackViewFrame.setVisible(false);
        }
    });
    configureStackViewFrame.validate();
    configureStackViewFrame.setSize(200, 300);
    configureStackViewFrame.pack();
    // called when Gate is exited, in case the user doesn't close the
    // datastore
    MainFrame.getInstance().addWindowListener(new WindowAdapter() {

        @Override
        public void windowClosed(WindowEvent e) {
            // no parent so need to be disposed explicitly
            configureStackViewFrame.dispose();
        }
    });
    /**
     ***********
     * Top panel *
     ************
     */
    JPanel topPanel = new JPanel(new GridBagLayout());
    topPanel.setOpaque(false);
    topPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 0, 3));
    GridBagConstraints gbc = new GridBagConstraints();
    // first column, three rows span
    queryTextArea = new QueryTextArea();
    queryTextArea.setToolTipText("<html>Enter a query to search the datastore." + "<br><small>'{' or '.' activate auto-completion." + "<br>Ctrl+Enter add a new line.</small></html>");
    queryTextArea.setLineWrap(true);
    gbc.gridheight = 3;
    gbc.weightx = 1;
    gbc.weighty = 1;
    gbc.fill = GridBagConstraints.BOTH;
    gbc.insets = new Insets(0, 0, 0, 4);
    topPanel.add(new JScrollPane(queryTextArea), gbc);
    gbc.gridheight = 1;
    gbc.weightx = 0;
    gbc.weighty = 0;
    gbc.insets = new Insets(0, 0, 0, 0);
    // second column, first row
    gbc.gridx = GridBagConstraints.RELATIVE;
    topPanel.add(new JLabel("Corpus: "), gbc);
    corpusToSearchIn = new JComboBox<String>();
    corpusToSearchIn.addItem(Constants.ENTIRE_DATASTORE);
    corpusToSearchIn.setPrototypeDisplayValue(Constants.ENTIRE_DATASTORE);
    corpusToSearchIn.setToolTipText("Select the corpus to search in.");
    if (target == null || target instanceof Searcher) {
        corpusToSearchIn.setEnabled(false);
    }
    corpusToSearchIn.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent ie) {
            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    updateAnnotationSetsList();
                }
            });
        }
    });
    topPanel.add(corpusToSearchIn, gbc);
    topPanel.add(Box.createHorizontalStrut(4), gbc);
    topPanel.add(new JLabel("Annotation set: "), gbc);
    annotationSetsToSearchIn = new JComboBox<String>();
    annotationSetsToSearchIn.setPrototypeDisplayValue(Constants.COMBINED_SET);
    annotationSetsToSearchIn.setToolTipText("Select the annotation set to search in.");
    annotationSetsToSearchIn.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent ie) {
            updateAnnotationTypesList();
        }
    });
    topPanel.add(annotationSetsToSearchIn, gbc);
    // refresh button
    topPanel.add(Box.createHorizontalStrut(4), gbc);
    RefreshAnnotationSetsAndFeaturesAction refreshAction = new RefreshAnnotationSetsAndFeaturesAction();
    JButton refreshTF = new ButtonBorder(new Color(240, 240, 240), new Insets(4, 2, 4, 3), false);
    refreshTF.setAction(refreshAction);
    topPanel.add(refreshTF, gbc);
    // second column, second row
    gbc.gridy = 1;
    JLabel noOfResultsLabel = new JLabel("Results: ");
    topPanel.add(noOfResultsLabel, gbc);
    numberOfResultsSlider = new JSlider(1, 1100, 50);
    numberOfResultsSlider.setToolTipText("50 results per page");
    numberOfResultsSlider.addChangeListener(new ChangeListener() {

        @Override
        public void stateChanged(ChangeEvent e) {
            if (numberOfResultsSlider.getValue() > (numberOfResultsSlider.getMaximum() - 100)) {
                numberOfResultsSlider.setToolTipText("Retrieve all results.");
                nextResults.setText("Retrieve all results.");
                nextResultsAction.setEnabled(false);
            } else {
                numberOfResultsSlider.setToolTipText("Retrieve " + numberOfResultsSlider.getValue() + " results per page.");
                nextResults.setText("Next page of " + numberOfResultsSlider.getValue() + " results");
                if (searcher.getHits().length == noOfResults) {
                    nextResultsAction.setEnabled(true);
                }
            }
            // show the tooltip each time the value change
            ToolTipManager.sharedInstance().mouseMoved(new MouseEvent(numberOfResultsSlider, MouseEvent.MOUSE_MOVED, 0, 0, 0, 0, 0, false));
        }
    });
    // always show the tooltip for this component
    numberOfResultsSlider.addMouseListener(new MouseAdapter() {

        ToolTipManager toolTipManager = ToolTipManager.sharedInstance();

        int initialDelay, reshowDelay, dismissDelay;

        boolean enabled;

        @Override
        public void mouseEntered(MouseEvent e) {
            initialDelay = toolTipManager.getInitialDelay();
            reshowDelay = toolTipManager.getReshowDelay();
            dismissDelay = toolTipManager.getDismissDelay();
            enabled = toolTipManager.isEnabled();
            toolTipManager.setInitialDelay(0);
            toolTipManager.setReshowDelay(0);
            toolTipManager.setDismissDelay(Integer.MAX_VALUE);
            toolTipManager.setEnabled(true);
        }

        @Override
        public void mouseExited(MouseEvent e) {
            toolTipManager.setInitialDelay(initialDelay);
            toolTipManager.setReshowDelay(reshowDelay);
            toolTipManager.setDismissDelay(dismissDelay);
            toolTipManager.setEnabled(enabled);
        }
    });
    gbc.insets = new Insets(5, 0, 0, 0);
    topPanel.add(numberOfResultsSlider, gbc);
    gbc.insets = new Insets(0, 0, 0, 0);
    topPanel.add(Box.createHorizontalStrut(4), gbc);
    JLabel contextWindowLabel = new JLabel("Context size: ");
    topPanel.add(contextWindowLabel, gbc);
    contextSizeSlider = new JSlider(1, 50, 5);
    contextSizeSlider.setToolTipText("Display 5 tokens of context in the results.");
    contextSizeSlider.addChangeListener(new ChangeListener() {

        @Override
        public void stateChanged(ChangeEvent e) {
            contextSizeSlider.setToolTipText("Display " + contextSizeSlider.getValue() + " tokens of context in the results.");
            ToolTipManager.sharedInstance().mouseMoved(new MouseEvent(contextSizeSlider, MouseEvent.MOUSE_MOVED, 0, 0, 0, 0, 0, false));
        }
    });
    // always show the tooltip for this component
    contextSizeSlider.addMouseListener(new MouseAdapter() {

        ToolTipManager toolTipManager = ToolTipManager.sharedInstance();

        int initialDelay, reshowDelay, dismissDelay;

        boolean enabled;

        @Override
        public void mouseEntered(MouseEvent e) {
            initialDelay = toolTipManager.getInitialDelay();
            reshowDelay = toolTipManager.getReshowDelay();
            dismissDelay = toolTipManager.getDismissDelay();
            enabled = toolTipManager.isEnabled();
            toolTipManager.setInitialDelay(0);
            toolTipManager.setReshowDelay(0);
            toolTipManager.setDismissDelay(Integer.MAX_VALUE);
            toolTipManager.setEnabled(true);
        }

        @Override
        public void mouseExited(MouseEvent e) {
            toolTipManager.setInitialDelay(initialDelay);
            toolTipManager.setReshowDelay(reshowDelay);
            toolTipManager.setDismissDelay(dismissDelay);
            toolTipManager.setEnabled(enabled);
        }
    });
    gbc.insets = new Insets(5, 0, 0, 0);
    topPanel.add(contextSizeSlider, gbc);
    gbc.insets = new Insets(0, 0, 0, 0);
    // second column, third row
    gbc.gridy = 2;
    JPanel panel = new JPanel();
    panel.setBorder(new EmptyBorder(new Insets(0, 0, 0, 0)));
    executeQueryAction = new ExecuteQueryAction();
    JButton executeQuery = new ButtonBorder(new Color(240, 240, 240), new Insets(0, 2, 0, 3), false);
    executeQuery.setAction(executeQueryAction);
    panel.add(executeQuery);
    ClearQueryAction clearQueryAction = new ClearQueryAction();
    JButton clearQueryTF = new ButtonBorder(new Color(240, 240, 240), new Insets(4, 2, 4, 3), false);
    clearQueryTF.setAction(clearQueryAction);
    panel.add(Box.createHorizontalStrut(5));
    panel.add(clearQueryTF);
    nextResultsAction = new NextResultsAction();
    nextResultsAction.setEnabled(false);
    nextResults = new ButtonBorder(new Color(240, 240, 240), new Insets(0, 0, 0, 3), false);
    nextResults.setAction(nextResultsAction);
    panel.add(Box.createHorizontalStrut(5));
    panel.add(nextResults);
    gbc.fill = GridBagConstraints.NONE;
    gbc.anchor = GridBagConstraints.WEST;
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    topPanel.add(panel, gbc);
    // will be added to the GUI via a split panel
    /**
     **************
     * Center panel *
     ***************
     */
    // these components will be used in updateStackView()
    centerPanel = new AnnotationStack(150, 30);
    configureStackViewButton = new ButtonBorder(new Color(250, 250, 250), new Insets(0, 0, 0, 3), true);
    configureStackViewButton.setHorizontalAlignment(SwingConstants.LEFT);
    configureStackViewButton.setAction(new ConfigureStackViewAction());
    // will be added to the GUI via a split panel
    /**
     *******************
     * Bottom left panel *
     ********************
     */
    JPanel bottomLeftPanel = new JPanel(new GridBagLayout());
    bottomLeftPanel.setOpaque(false);
    gbc = new GridBagConstraints();
    // title of the table, results options, export and next results
    // button
    gbc.gridy = 0;
    panel = new JPanel();
    panel.setBorder(new EmptyBorder(new Insets(0, 0, 0, 0)));
    titleResults = new JLabel("Results");
    titleResults.setBorder(new EmptyBorder(new Insets(0, 0, 0, 0)));
    panel.add(titleResults);
    panel.add(Box.createHorizontalStrut(5), gbc);
    exportResultsAction = new ExportResultsAction();
    exportResultsAction.setEnabled(false);
    JButton exportToHTML = new ButtonBorder(new Color(240, 240, 240), new Insets(0, 0, 0, 3), false);
    exportToHTML.setAction(exportResultsAction);
    panel.add(exportToHTML, gbc);
    bottomLeftPanel.add(panel, gbc);
    // table of results
    resultTableModel = new ResultTableModel();
    resultTable = new XJTable(resultTableModel);
    resultTable.setDefaultRenderer(String.class, new ResultTableCellRenderer());
    resultTable.setEnableHidingColumns(true);
    resultTable.addMouseListener(new MouseAdapter() {

        private JPopupMenu mousePopup;

        JMenuItem menuItem;

        @Override
        public void mousePressed(MouseEvent e) {
            int row = resultTable.rowAtPoint(e.getPoint());
            if (e.isPopupTrigger() && !resultTable.isRowSelected(row)) {
                // if right click outside the selection then reset selection
                resultTable.getSelectionModel().setSelectionInterval(row, row);
            }
            if (e.isPopupTrigger()) {
                createPopup();
                mousePopup.show(e.getComponent(), e.getX(), e.getY());
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            if (e.isPopupTrigger()) {
                createPopup();
                mousePopup.show(e.getComponent(), e.getX(), e.getY());
            }
        }

        private void createPopup() {
            mousePopup = new JPopupMenu();
            menuItem = new JMenuItem("Remove the selected result" + (resultTable.getSelectedRowCount() > 1 ? "s" : ""));
            mousePopup.add(menuItem);
            menuItem.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent ae) {
                    int[] rows = resultTable.getSelectedRows();
                    for (int i = 0; i < rows.length; i++) {
                        rows[i] = resultTable.rowViewToModel(rows[i]);
                    }
                    Arrays.sort(rows);
                    for (int i = rows.length - 1; i >= 0; i--) {
                        results.remove(rows[i]);
                    }
                    resultTable.clearSelection();
                    resultTableModel.fireTableDataChanged();
                    mousePopup.setVisible(false);
                }
            });
            if (target instanceof LuceneDataStoreImpl && SwingUtilities.getRoot(LuceneDataStoreSearchGUI.this) instanceof MainFrame) {
                menuItem = new JMenuItem("Open the selected document" + (resultTable.getSelectedRowCount() > 1 ? "s" : ""));
                menuItem.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent ae) {
                        Set<Pattern> patterns = new HashSet<Pattern>();
                        Set<String> documentIds = new HashSet<String>();
                        for (int rowView : resultTable.getSelectedRows()) {
                            // create and display the document for this result
                            int rowModel = resultTable.rowViewToModel(rowView);
                            Pattern pattern = (Pattern) results.get(rowModel);
                            if (!documentIds.contains(pattern.getDocumentID())) {
                                patterns.add(pattern);
                                documentIds.add(pattern.getDocumentID());
                            }
                        }
                        if (patterns.size() > 10) {
                            Object[] possibleValues = { "Open the " + patterns.size() + " documents", "Don't open" };
                            int selectedValue = JOptionPane.showOptionDialog(LuceneDataStoreSearchGUI.this, "Do you want to open " + patterns.size() + " documents in the central tabbed pane ?", "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, possibleValues, possibleValues[1]);
                            if (selectedValue == 1 || selectedValue == JOptionPane.CLOSED_OPTION) {
                                return;
                            }
                        }
                        for (final Pattern pattern : patterns) {
                            // create and display the document for this result
                            FeatureMap features = Factory.newFeatureMap();
                            features.put(DataStore.DATASTORE_FEATURE_NAME, target);
                            features.put(DataStore.LR_ID_FEATURE_NAME, pattern.getDocumentID());
                            final Document doc;
                            try {
                                doc = (Document) Factory.createResource("gate.corpora.DocumentImpl", features);
                            } catch (gate.util.GateException e) {
                                e.printStackTrace();
                                return;
                            }
                            // show the expression in the document
                            SwingUtilities.invokeLater(new Runnable() {

                                @Override
                                public void run() {
                                    MainFrame.getInstance().select(doc);
                                }
                            });
                            if (patterns.size() == 1) {
                                // wait some time for the document to be displayed
                                Date timeToRun = new Date(System.currentTimeMillis() + 2000);
                                Timer timer = new Timer("Annic show document timer", true);
                                timer.schedule(new TimerTask() {

                                    @Override
                                    public void run() {
                                        showResultInDocument(doc, pattern);
                                    }
                                }, timeToRun);
                            }
                        }
                    }
                });
                mousePopup.add(menuItem);
            }
        }
    });
    // resultTable.addMouseListener
    // when selection change in the result table
    // update the stack view and export button
    resultTable.getSelectionModel().addListSelectionListener(new javax.swing.event.ListSelectionListener() {

        @Override
        public void valueChanged(javax.swing.event.ListSelectionEvent e) {
            if (!e.getValueIsAdjusting()) {
                updateStackView();
            }
        }
    });
    resultTable.setColumnSelectionAllowed(false);
    resultTable.setRowSelectionAllowed(true);
    resultTable.setSortable(true);
    resultTable.setComparator(ResultTableModel.LEFT_CONTEXT_COLUMN, lastWordComparator);
    resultTable.setComparator(ResultTableModel.RESULT_COLUMN, stringCollator);
    resultTable.setComparator(ResultTableModel.RIGHT_CONTEXT_COLUMN, stringCollator);
    JScrollPane tableScrollPane = new JScrollPane(resultTable, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    gbc.fill = GridBagConstraints.BOTH;
    gbc.anchor = GridBagConstraints.NORTH;
    gbc.gridy = 1;
    gbc.gridx = 0;
    gbc.insets = new Insets(0, 0, 0, 0);
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    gbc.gridheight = GridBagConstraints.REMAINDER;
    gbc.weightx = 1;
    gbc.weighty = 1;
    bottomLeftPanel.add(tableScrollPane, gbc);
    /**
     ************************
     * Statistics tabbed pane *
     *************************
     */
    statisticsTabbedPane = new JTabbedPane();
    globalStatisticsTable = new XJTable() {

        @Override
        public boolean isCellEditable(int rowIndex, int vColIndex) {
            return false;
        }
    };
    globalStatisticsTableModel = new DefaultTableModel(new Object[] { "Annotation Type", "Count" }, 0);
    globalStatisticsTable.setModel(globalStatisticsTableModel);
    globalStatisticsTable.setComparator(0, stringCollator);
    globalStatisticsTable.setComparator(1, integerComparator);
    globalStatisticsTable.setSortedColumn(1);
    globalStatisticsTable.setAscending(false);
    globalStatisticsTable.addMouseListener(new MouseInputAdapter() {

        @Override
        public void mousePressed(MouseEvent e) {
            if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
                updateQuery();
            }
        }

        private void updateQuery() {
            int caretPosition = queryTextArea.getCaretPosition();
            String query = queryTextArea.getText();
            String type = (String) globalStatisticsTable.getValueAt(globalStatisticsTable.getSelectedRow(), globalStatisticsTable.convertColumnIndexToView(0));
            String queryMiddle = "{" + type + "}";
            String queryLeft = (queryTextArea.getSelectionStart() == queryTextArea.getSelectionEnd()) ? query.substring(0, caretPosition) : query.substring(0, queryTextArea.getSelectionStart());
            String queryRight = (queryTextArea.getSelectionStart() == queryTextArea.getSelectionEnd()) ? query.substring(caretPosition, query.length()) : query.substring(queryTextArea.getSelectionEnd(), query.length());
            queryTextArea.setText(queryLeft + queryMiddle + queryRight);
        }
    });
    statisticsTabbedPane.addTab("Global", null, new JScrollPane(globalStatisticsTable), "Global statistics on the Corpus and Annotation Set selected.");
    statisticsTabbedPane.addMouseListener(new MouseAdapter() {

        private JPopupMenu mousePopup;

        JMenuItem menuItem;

        @Override
        public void mousePressed(MouseEvent e) {
            int tabIndex = statisticsTabbedPane.indexAtLocation(e.getX(), e.getY());
            if (e.isPopupTrigger() && tabIndex > 0) {
                createPopup(tabIndex);
                mousePopup.show(e.getComponent(), e.getX(), e.getY());
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            int tabIndex = statisticsTabbedPane.indexAtLocation(e.getX(), e.getY());
            if (e.isPopupTrigger() && tabIndex > 0) {
                createPopup(tabIndex);
                mousePopup.show(e.getComponent(), e.getX(), e.getY());
            }
        }

        private void createPopup(final int tabIndex) {
            mousePopup = new JPopupMenu();
            if (tabIndex == 1) {
                menuItem = new JMenuItem("Clear table");
                menuItem.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent ie) {
                        oneRowStatisticsTableModel.setRowCount(0);
                    }
                });
            } else {
                menuItem = new JMenuItem("Close tab");
                menuItem.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent ie) {
                        statisticsTabbedPane.remove(tabIndex);
                    }
                });
            }
            mousePopup.add(menuItem);
        }
    });
    class RemoveCellEditorRenderer extends AbstractCellEditor implements TableCellRenderer, TableCellEditor, ActionListener {

        private JButton button;

        public RemoveCellEditorRenderer() {
            button = new JButton();
            button.setHorizontalAlignment(SwingConstants.CENTER);
            button.setIcon(MainFrame.getIcon("Delete"));
            button.setToolTipText("Remove this row.");
            button.setContentAreaFilled(false);
            button.setBorderPainted(false);
            button.setMargin(new Insets(0, 0, 0, 0));
            button.addActionListener(this);
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object color, boolean isSelected, boolean hasFocus, int row, int col) {
            button.setSelected(isSelected);
            return button;
        }

        @Override
        public boolean shouldSelectCell(EventObject anEvent) {
            return false;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            int editingRow = oneRowStatisticsTable.getEditingRow();
            fireEditingStopped();
            oneRowStatisticsTableModel.removeRow(oneRowStatisticsTable.rowViewToModel(editingRow));
        }

        @Override
        public Object getCellEditorValue() {
            return null;
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int col) {
            button.setSelected(isSelected);
            return button;
        }
    }
    oneRowStatisticsTable = new XJTable() {

        @Override
        public boolean isCellEditable(int rowIndex, int vColIndex) {
            return vColIndex == 2;
        }

        @Override
        public Component prepareRenderer(TableCellRenderer renderer, int row, int col) {
            Component c = super.prepareRenderer(renderer, row, col);
            if (c instanceof JComponent && col != 2) {
                // display a custom tooltip saved when adding statistics
                ((JComponent) c).setToolTipText("<html>" + oneRowStatisticsTableToolTips.get(rowViewToModel(row)) + "</html>");
            }
            return c;
        }
    };
    oneRowStatisticsTableModel = new DefaultTableModel(new Object[] { "Annotation Type/Feature", "Count", "" }, 0);
    oneRowStatisticsTable.setModel(oneRowStatisticsTableModel);
    oneRowStatisticsTable.getColumnModel().getColumn(2).setCellEditor(new RemoveCellEditorRenderer());
    oneRowStatisticsTable.getColumnModel().getColumn(2).setCellRenderer(new RemoveCellEditorRenderer());
    oneRowStatisticsTable.setComparator(0, stringCollator);
    oneRowStatisticsTable.setComparator(1, integerComparator);
    statisticsTabbedPane.addTab("One item", null, new JScrollPane(oneRowStatisticsTable), "<html>One item statistics.<br>" + "Right-click on an annotation<br>" + "to add statistics here.");
    oneRowStatisticsTableToolTips = new Vector<String>();
    // will be added to the GUI via a split panel
    /**
     ************************************************************
     * Vertical splits between top, center panel and bottom panel *
     *************************************************************
     */
    /**
     * ________________________________________
     * |               topPanel                 |
     * |__________________3_____________________|
     * |                                        |
     * |             centerPanel                |
     * |________2________ __________2___________|
     * |                 |                      |
     * | bottomLeftPanel 1 statisticsTabbedPane |
     * |_________________|______________________|
     *
     * 1 bottomSplitPane 2 centerBottomSplitPane 3 topBottomSplitPane
     */
    bottomSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
    Dimension minimumSize = new Dimension(0, 0);
    bottomLeftPanel.setMinimumSize(minimumSize);
    statisticsTabbedPane.setMinimumSize(minimumSize);
    bottomSplitPane.add(bottomLeftPanel);
    bottomSplitPane.add(statisticsTabbedPane);
    bottomSplitPane.setOneTouchExpandable(true);
    bottomSplitPane.setResizeWeight(0.75);
    bottomSplitPane.setContinuousLayout(true);
    JSplitPane centerBottomSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
    centerBottomSplitPane.add(new JScrollPane(centerPanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
    centerBottomSplitPane.add(bottomSplitPane);
    centerBottomSplitPane.setResizeWeight(0.5);
    centerBottomSplitPane.setContinuousLayout(true);
    JSplitPane topBottomSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
    topBottomSplitPane.add(topPanel);
    topBottomSplitPane.add(centerBottomSplitPane);
    topBottomSplitPane.setContinuousLayout(true);
    add(topBottomSplitPane, BorderLayout.CENTER);
}
Also used : AnnotationStack(gate.gui.docview.AnnotationStack) JPanel(javax.swing.JPanel) GridBagConstraints(java.awt.GridBagConstraints) ActionEvent(java.awt.event.ActionEvent) Document(gate.Document) Comparator(java.util.Comparator) BorderLayout(java.awt.BorderLayout) JSlider(javax.swing.JSlider) TableCellEditor(javax.swing.table.TableCellEditor) EmptyBorder(javax.swing.border.EmptyBorder) AbstractAction(javax.swing.AbstractAction) HashSet(java.util.HashSet) TableCellRenderer(javax.swing.table.TableCellRenderer) DefaultTableCellRenderer(javax.swing.table.DefaultTableCellRenderer) ToolTipManager(javax.swing.ToolTipManager) Searcher(gate.creole.annic.Searcher) Color(java.awt.Color) EventObject(java.util.EventObject) ActionListener(java.awt.event.ActionListener) JTable(javax.swing.JTable) XJTable(gate.swing.XJTable) EventObject(java.util.EventObject) JSplitPane(javax.swing.JSplitPane) MouseInputAdapter(javax.swing.event.MouseInputAdapter) Insets(java.awt.Insets) GridBagLayout(java.awt.GridBagLayout) XJTable(gate.swing.XJTable) JTabbedPane(javax.swing.JTabbedPane) DefaultTableModel(javax.swing.table.DefaultTableModel) JButton(javax.swing.JButton) WindowAdapter(java.awt.event.WindowAdapter) TimerTask(java.util.TimerTask) ChangeListener(javax.swing.event.ChangeListener) AbstractCellEditor(javax.swing.AbstractCellEditor) JMenuItem(javax.swing.JMenuItem) Component(java.awt.Component) JComponent(javax.swing.JComponent) JScrollPane(javax.swing.JScrollPane) Pattern(gate.creole.annic.Pattern) MouseEvent(java.awt.event.MouseEvent) MouseAdapter(java.awt.event.MouseAdapter) JComponent(javax.swing.JComponent) JLabel(javax.swing.JLabel) LuceneDataStoreImpl(gate.persist.LuceneDataStoreImpl) Dimension(java.awt.Dimension) JPopupMenu(javax.swing.JPopupMenu) Date(java.util.Date) FeatureMap(gate.FeatureMap) ChangeEvent(javax.swing.event.ChangeEvent) Timer(java.util.Timer) WindowEvent(java.awt.event.WindowEvent)

Aggregations

MouseAdapter (java.awt.event.MouseAdapter)4 MouseEvent (java.awt.event.MouseEvent)4 AbstractCellEditor (javax.swing.AbstractCellEditor)4 JButton (javax.swing.JButton)4 JLabel (javax.swing.JLabel)4 JTable (javax.swing.JTable)4 GuiLafPreferencesManager (apps.gui.GuiLafPreferencesManager)3 Image (java.awt.Image)3 BufferedImage (java.awt.image.BufferedImage)3 File (java.io.File)3 IOException (java.io.IOException)3 ImageIcon (javax.swing.ImageIcon)3 JTextField (javax.swing.JTextField)3 TableCellEditor (javax.swing.table.TableCellEditor)3 TableCellRenderer (javax.swing.table.TableCellRenderer)3 InstanceManager (jmri.InstanceManager)3 Manager (jmri.Manager)3 NamedBean (jmri.NamedBean)3 ActionEvent (java.awt.event.ActionEvent)2 ActionListener (java.awt.event.ActionListener)2