Package de.t68.utils.keyboard

Source Code of de.t68.utils.keyboard.VKeyboard

/**
* Copyright (c) 2009, Till Woitendorf (t68)

Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:<BR>

1. Redistributions of source code must retain the above copyright notice, this list of conditions
and the following disclaimer.<BR>
2. Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials provided with
the distribution.<BR>

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 FREEBSD PROJECT 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.
Contact me via http://jvkeyboard.sourceforge.net if you discover any bugs or if you have a suggestion
*/
package de.t68.utils.keyboard;

import de.t68.utils.keyboard.button.KeyboardButton;
import de.t68.utils.keyboard.event.ImeKeyEvent;
import de.t68.utils.keyboard.event.VirtualKeyAdapter;
import de.t68.utils.keyboard.event.VirtualKeyEvent;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.FocusTraversalPolicy;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentListener;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.LinkedList;
import java.util.Vector;

import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.ButtonModel;
import javax.swing.FocusManager;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.ChangeListener;
import javax.swing.text.JTextComponent;

import org.apache.log4j.Logger;

/**
* @author t68
*/
public class VKeyboard extends JPanel {

    public class KeyboardKeyAdapter extends VirtualKeyAdapter {

        private final KeyboardKey kk;

        public KeyboardKeyAdapter(KeyboardKey kk)
        {
            this.kk = kk;
        }

        @Override
        public void keyTyped(VirtualKeyEvent e)
        {
            kk.doAction(textField, VKeyboard.this, e.getID());
            switchOffModifier();
            if (e.getKeyCode() != KeyEvent.VK_TAB && e.getKeyCode() != KeyEvent.VK_ENTER)
                textField.requestFocus();
        }

        @Override
        public void keyPressed(VirtualKeyEvent e)
        {
            if (KeyEvent.VK_SHIFT == e.getKeyCode())
            {
                AbstractButton pressedButton = (AbstractButton) e.getSource();
                if (pressedButton != null)
                    pressedButton.getModel().setSelected(true);
            }
            if (e.getKeyCode() == KeyEvent.VK_TAB || e.getKeyCode() == KeyEvent.VK_ENTER)
                try
                {
                    Container ancestor = textField.getFocusCycleRootAncestor();
                    if (ancestor.isFocusTraversalPolicySet())
                    {
                        FocusTraversalPolicy policy = ancestor.getFocusTraversalPolicy();
                        Component focusOwner = FocusManager.getCurrentManager().getFocusOwner();
                        focusOwner = focusOwner == null ? textField : focusOwner;
                        Component nextComponent;
                        if (modifier == KeyboardModifier.shift)
                            nextComponent = policy.getComponentBefore(ancestor, focusOwner);
                        else
                            nextComponent = policy.getComponentAfter(ancestor, focusOwner);
                        if (nextComponent != focusOwner)
                            nextComponent.requestFocus();
                        else
                            kk.doAction(textField, VKeyboard.this, e.getID());
                        return;
                    }
                } catch (Exception e1)
                {
                    logger.info("Could not execute focus cycling.");
                    logger.debug("Catched exception for cycling: ", e1);
                }
            if (e.getKeyChar() == KeyEvent.CHAR_UNDEFINED)
                kk.doAction(textField, VKeyboard.this, e.getID());
            if (e.getKeyCode() != KeyEvent.VK_TAB && e.getKeyCode() != KeyEvent.VK_ENTER)
                textField.requestFocus();
        }

        @Override
        public void keyReleased(VirtualKeyEvent e)
        {
            if (e.getKeyChar() == KeyEvent.CHAR_UNDEFINED)
                kk.doAction(textField, VKeyboard.this, e.getID());

            if (e.getKeyCode() != KeyEvent.VK_TAB && e.getKeyCode() != KeyEvent.VK_ENTER)
                textField.requestFocus();
        }

        @Override
        public void imeKeyActivated(ImeKeyEvent e)
        {
            // Auswahl des IME Layouts
            int iTmp = 0;
            if ((iTmp = keyboardLayout.getNumberByKeyboardID(e.getImeString())) >= 0
                    && keyboardLayout.currentKeyboard != iTmp)
            {
                cleanUp();
                keyboardLayout.currentKeyboard = iTmp;
                applyCurrentKeyboardLayout();
            }
            textField.requestFocus();
        }
    }

    public void setTextField(JTextField textField)
    {
        this.textField = textField;
    }

    public JPanel getKeyPanel()
    {
        return keyPanel;
    }

    KeyboardModifier modifier = KeyboardModifier.normal;

    protected boolean capsLock = false;

    KeyboardLayout keyboardLayout;

    protected int keyFontSize = 18;

    JPanel keyPanel = new JPanel();

    JTextComponent textField = new JTextField(40);

    ButtonGroup group = null;

    private ButtonModel shiftModel = null;

    private ButtonModel altModel;

    private ButtonModel altgrModel;

    final Logger logger = Logger.getLogger(VKeyboard.class);

    public VKeyboard(BorderLayout layout)
    {
        super(layout);
    }

    public VKeyboard(KeyboardLayout keyboardLayout)
    {
        this(keyboardLayout, 18);
    }

    public VKeyboard(KeyboardLayout keyboardLayout, int tb)
    {
        super(new BorderLayout());
        this.keyFontSize = tb;
        textField.setFont(getFont().deriveFont(24f));
        add(textField, BorderLayout.NORTH);
        add(keyPanel, BorderLayout.CENTER);
        setKeyboardLayout(keyboardLayout);
    }

    public VKeyboard(KeyboardLayout layout, int keyFontSize, final JTextComponent destClone)
    {
        this(layout, keyFontSize);
        remove(textField);
        this.textField = destClone;
        add(textField, BorderLayout.NORTH);
    }

    public VKeyboard(KeyboardLayout layout, final JTextComponent destClone)
    {
        this(layout, 18, destClone);
    }

    @Override
    public void setFont(Font font)
    {
        super.setFont(font);
        if (textField != null)
            textField.setFont(font);
    }

    /**
     * @param layout
     */
    public void setKeyboardLayout(KeyboardLayout layout)
    {
        this.keyboardLayout = layout;
        applyCurrentKeyboardLayout();
    }

    protected void switchOffModifier()
    {
        if (shiftModel != null)
            shiftModel.setSelected(false);
        if (altModel != null)
            altModel.setSelected(false);
        if (altgrModel != null)
            altgrModel.setSelected(false);
    }

    /**
     * f�r den Fall das mehrere KeyboardLayout in einen Objekt gespeichert sind und dieses gewechselt werden
     * soll.
     * */
    public void applyCurrentKeyboardLayout()
    {
        keyPanel.removeAll();
        keyPanel.setLayout(new GridBagLayout());
        GridBagConstraints gc = new GridBagConstraints();
        gc.weightx = 1;
        gc.weighty = 1;
        gc.gridx = 0;
        gc.gridy = 0;
        gc.fill = GridBagConstraints.BOTH;

        for (LinkedList<KeyboardKey> row : keyboardLayout.get(keyboardLayout.currentKeyboard))
        {
            gc.gridx = 0;
            for (final KeyboardKey kk : row)
            {
                gc.gridwidth = kk.getKeyWidth();
                kk.setKeyFontSize(keyFontSize);
                final AbstractButton button = kk.getComponent(new KeyboardKeyAdapter(kk), this);
                if (button.getText() != "" && keyboardLayout.getNumberByKeyboardID(button.getText()) >= 0)
                    addButtonToGroup(button);
                button.setFocusable(false);
                keyPanel.add(button, gc);
                gc.gridx += kk.getKeyWidth();
            }
            gc.gridy++;
        }

        setModifier(KeyboardModifier.normal);
        if (keyboardLayout.keyboardID.size() > 0)
            for (Component comp : keyPanel.getComponents())
            {
                AbstractButton btn = (AbstractButton) comp;

                if (btn != null
                        && btn.getText()
                                .equals(keyboardLayout.keyboardID.get(keyboardLayout.currentKeyboard)))
                    btn.setSelected(true);
            }

        keyPanel.revalidate();
        keyPanel.repaint();
    }

    /**
     * Removes all listeners from all {@link KeyboardKey#keyboardButton}.
     */
    public void cleanUp()
    {
        for (LinkedList<KeyboardKey> row : keyboardLayout.get(keyboardLayout.currentKeyboard))
            for (KeyboardKey kk : row)
                if (kk.keyboardButton != null)
                {
                    KeyListener l[] = kk.keyboardButton.getKeyListeners();
                    for (KeyListener k : l)
                        kk.keyboardButton.removeKeyListener(k);

                    ActionListener ak[] = kk.keyboardButton.getActionListeners();
                    for (ActionListener k : ak)
                        kk.keyboardButton.removeActionListener(k);

                    ItemListener ik[] = kk.keyboardButton.getItemListeners();
                    for (ItemListener k : ik)
                        kk.keyboardButton.removeItemListener(k);

                    ChangeListener ck[] = kk.keyboardButton.getChangeListeners();
                    for (ChangeListener k : ck)
                        kk.keyboardButton.removeChangeListener(k);

                    ComponentListener clk[] = kk.keyboardButton.getComponentListeners();
                    for (ComponentListener k : clk)
                        kk.keyboardButton.removeComponentListener(k);

                    kk.keyboardButton = null;
                }
    }

    /**
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception
    {
        try
        {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (Exception ex)
        {
            ex.printStackTrace();
        }
        final JFrame frame = new JFrame("Keyboard-Test");

        LanguageMap lm = LanguageMap.getInstance();
        final VKeyboard keyboard = new VKeyboard(lm.getKeyboardLayoutForLocale("ja", "JP"), 18);

        JPanel panel = new JPanel(new BorderLayout());
        panel.add(keyboard, BorderLayout.CENTER);

        final JComboBox<KeyboardLayout> combo = new JComboBox<>(new Vector<KeyboardLayout>(lm.values()));
        combo.setSelectedItem(lm.getKeyboardLayoutForCurrentLocale());
        combo.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e)
            {
                SwingUtilities.invokeLater(new Runnable() {

                    public void run()
                    {
                        keyboard.setKeyboardLayout((KeyboardLayout) combo.getSelectedItem());
                        frame.pack();
                    }
                });
            }
        });

        panel.add(combo, BorderLayout.SOUTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(panel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    /**
     * Adds a button to {@link #group}. The first button will be selected.
     *
     * @param button
     */
    public void addButtonToGroup(AbstractButton button)
    {
        if (group == null)
        {
            group = new ButtonGroup();
            group.add(button);
            button.setSelected(true);
        } else
            group.add(button);
    }

    public KeyboardModifier getModifier()
    {
        return modifier;
    }

    /**
     * Sets the modifier to all {@link KeyboardButton}s too.
     *
     * @param modifier
     */
    public void setModifier(KeyboardModifier modifier)
    {
        if (this.modifier.equals(modifier))
            return;
        this.modifier = modifier;
        for (LinkedList<KeyboardKey> row : keyboardLayout.get(keyboardLayout.currentKeyboard))
            for (KeyboardKey kk : row)
                kk.setKeyboardModifier(modifier);
    }

    public boolean isCapsLock()
    {
        return capsLock;
    }

    /**
     * It updates the shift modifier as well.
     *
     * @param capsLock
     */
    public void setCapsLock(boolean capsLock)
    {
        this.capsLock = capsLock;
        setModifier(isCapsLock() ? KeyboardModifier.shift : KeyboardModifier.normal);
    }

    /**
     * @return the buttonSize
     */
    public int getKeyFontSize()
    {
        return keyFontSize;
    }

    /**
     * @param keyFontSize
     *            the buttonSize to set
     */
    public void setKeyFontSize(int keyFontSize)
    {
        this.keyFontSize = keyFontSize;
    }

    /**
     * @return the shiftModel
     */
    public ButtonModel getShiftModel()
    {
        return shiftModel;
    }

    /**
     * @param shiftModel
     *            the shiftModel to set
     */
    public void setShiftModel(ButtonModel shiftModel)
    {
        this.shiftModel = shiftModel;
    }

    /**
     * @return the altModel
     */
    public ButtonModel getAltModel()
    {
        return altModel;
    }

    /**
     * @param altModel
     *            the altModel to set
     */
    public void setAltModel(ButtonModel altModel)
    {
        this.altModel = altModel;
    }

    /**
     * @return the altgrModel
     */
    public ButtonModel getAltgrModel()
    {
        return altgrModel;
    }

    /**
     * @param altgrModel
     *            the altgrModel to set
     */
    public void setAltgrModel(ButtonModel altgrModel)
    {
        this.altgrModel = altgrModel;
    }

    /**
     * @param specialKey
     *            TODO
     */
    public void selectKeyboardLayout(SpecialKey specialKey)
    {
        int iTmp = keyboardLayout.getNumberByKeyboardID(specialKey.textToShow);
        if (keyboardLayout.currentKeyboard != iTmp)
        {
            keyboardLayout.currentKeyboard = iTmp;
            applyCurrentKeyboardLayout();
        }
    }

}
TOP

Related Classes of de.t68.utils.keyboard.VKeyboard

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.