/* * Copyright (c) 2014-2020, Draque Thompson, [email protected] * All rights reserved. * * Licensed under: MIT Licence * See LICENSE.TXT included with this code to read the full license agreement. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ package org.darisadesigns.polyglotlina.CustomControls; import org.darisadesigns.polyglotlina.DictCore; import org.darisadesigns.polyglotlina.PGTUtil; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.font.TextAttribute; import javax.swing.AbstractCellEditor; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.event.DocumentListener; import javax.swing.table.TableCellEditor; /** * * @author draque */ public final class PCellEditor extends AbstractCellEditor implements TableCellEditor, Cloneable { private final JComponent component = new JTextField(); private final Font myFont; private DocumentListener docListener; private boolean ignoreListenerSilencing = false; private final boolean useConFont; private final DictCore core; public PCellEditor(boolean _useConFont, DictCore _core) { core = _core; useConFont = _useConFont; double preSize = core.getPropertiesManager().getFontSize(); Font defFont = useConFont ? core.getPropertiesManager().getFontCon() : core.getPropertiesManager().getFontLocal(); double fontSize = useConFont ? preSize : core.getOptionsManager().getMenuFontSize(); myFont = PGTUtil.addFontAttribute(TextAttribute.SIZE, (float)fontSize, defFont); final JTextField setupText = (JTextField) component; setupRightClickMenu(setupText); setupText.setBorder(BorderFactory.createBevelBorder(1)); this.setupTextFieldListener(setupText); } public void setDocuListener(DocumentListener _listener) { docListener = _listener; ((JTextField) component).getDocument().addDocumentListener(docListener); } public Component tableColumnEditor(JTable table, Object value, boolean isSelected, int rowIndex, int vColIndex) { ((JTextField) component).setText((String) value); component.setFont(myFont); return component; } /** * Gets textfield component (to maintain listeners and text position) * @return jtextfield component */ public JTextField getTextFieldComponent() { return (JTextField)component; } // This method is called when a cell value is edited by the user. @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int rowIndex, int vColIndex) { JTextField curComp = (JTextField) component; setValue(curComp, (String) value); curComp.setFont(myFont); return component; } public void setValue(String value) { setValue((JTextField) component, value); } private void setValue(JTextField curComp, String value) { if (ignoreListenerSilencing) { curComp.setText(value); } else { curComp.getDocument().removeDocumentListener(docListener); curComp.setText(value); curComp.getDocument().addDocumentListener(docListener); } } /** * Allows user to set initial value (helps avoid unnecessary listener firing * later * * @param value The value to set. */ public void setInitialValue(String value) { JTextField curComp = (JTextField) component; curComp.setText(value); } // This method is called when editing is completed. // It must return the new value to be stored in the cell. @Override public Object getCellEditorValue() { JTextField myField = (JTextField) component; myField.setFont(myFont); return myField.getText(); } @Override public PCellEditor clone() throws CloneNotSupportedException { JTextField myTextField = (JTextField)component; myTextField.setFont(myFont); PCellEditor clone = (PCellEditor)super.clone(); setupTextFieldListener(clone.getTextFieldComponent()); return clone; } /** * Adds relevant keylisteners to passed text field * @param textField */ private void setupTextFieldListener(final JTextField textField) { // handle character replacement textField.addKeyListener(new KeyListener() { @Override public void keyTyped(KeyEvent e) { // only use replacement if writing in confont if (useConFont) { PTextField.handleCharacterReplacement(core, e, textField); } } @Override public void keyPressed(KeyEvent e) { // do nothing } @Override public void keyReleased(KeyEvent e) { // do nothing } }); } private void setupRightClickMenu(JTextField editor) { final JPopupMenu ruleMenu = new JPopupMenu(); final JMenuItem cut = new JMenuItem("Cut"); final JMenuItem copy = new JMenuItem("Copy"); final JMenuItem paste = new JMenuItem("Paste"); final JTextField parentField = editor; cut.addActionListener((ActionEvent ae) -> { parentField.cut(); }); copy.addActionListener((ActionEvent ae) -> { parentField.copy(); }); paste.addActionListener((ActionEvent ae) -> { parentField.paste(); }); ruleMenu.add(cut); ruleMenu.add(copy); ruleMenu.add(paste); editor.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { if (e.isPopupTrigger() && parentField.isEnabled()) { cut.setEnabled(true); copy.setEnabled(true); paste.setEnabled(true); ruleMenu.show(e.getComponent(), e.getX(), e.getY()); } } @Override public void mouseReleased(MouseEvent e) { if (e.isPopupTrigger() && parentField.isEnabled()) { cut.setEnabled(true); copy.setEnabled(true); paste.setEnabled(true); ruleMenu.show(e.getComponent(), e.getX(), e.getY()); } } }); } /** * @param _ignoreListenerSilencing the ignoreListenerSilencing to set */ public void setIgnoreListenerSilencing(boolean _ignoreListenerSilencing) { this.ignoreListenerSilencing = _ignoreListenerSilencing; } public void setBackground(Color bg) { component.setBackground(bg); } }