Package com.nexirius.framework.dataeditor

Source Code of com.nexirius.framework.dataeditor.SelectorEditor$Repainter

//{HEADER
/**
* This class is part of jnex 'Nexirius Application Framework for Java'
* Copyright (C) Nexirius GmbH, CH-4450 Sissach, Switzerland (www.nexirius.ch)
*
* <p>This library is free software; you can redistribute it and/or<br>
* modify it under the terms of the GNU Lesser General Public<br>
* License as published by the Free Software Foundation; either<br>
* version 2.1 of the License, or (at your option) any later version.</p>
*
* <p>This library is distributed in the hope that it will be useful,<br>
* but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU<br>
* Lesser General Public License for more details.</p>
*
* <p>You should have received a copy of the GNU Lesser General Public<br>
* License along with this library; if not, write to the Free Software<br>
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA</p>
* </blockquote>
*
* <p>
* Nexirius GmbH, hereby disclaims all copyright interest in<br>
* the library jnex' 'Nexirius Application Framework for Java' written<br>
* by Marcel Baumann.</p>
*/
//}HEADER
package com.nexirius.framework.dataeditor;

import com.nexirius.framework.datamodel.*;
import com.nexirius.framework.dataviewer.DataViewer;
import com.nexirius.framework.textselector.TextSelector;
import com.nexirius.framework.textselector.TextSelectorManager;
import com.nexirius.util.StringVector;

import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.*;
import java.util.StringTokenizer;

/**
* This class is used to display a button for a simple model which in turn is used to select a
* value for the simple model from a list (see TextSelector)
* This class creates a tool tip like completion tip for the target SimpleModel instance (method create tipComponent)
*/
public class SelectorEditor extends DataViewer {



    public static final String s_viewername = "SelectorEditor";

    DataModelCommand command;

    /**
     * Creates a new SelectorEditor which is will be displayed as a JButton
     */
    public SelectorEditor(SelectorModel model) {
        super(model);
        init();
    }

    private void init() {
        SimpleModel target = getSelectorModel().getTarget();

        if (target == null) {

            return;
        }

        target.addDataModelListener(new TargetListener());

        command = getSelectorModel().getPopupCommand();
    }

    public SelectorModel getSelectorModel() {
        return (SelectorModel) getDataModel();
    }

    public String getTargetText() {
        SimpleModel target = getSelectorModel().getTarget();

        if (target == null) {

            return "";
        }

        return target.getText();
    }

    /**
     * Creates the actual Swing JButton
     */
    public void create() {
        try {
            setJComponent(factory.createViewer(command, true).getJComponent());
        } catch (Exception ex) {
            // should never happen
            ex.printStackTrace();
        }
    }

    /**
     * Empty implementation
     */
    public void update() {
    }

    /**
     * Only for debugging
     */
    public String getViewerName() {
        return s_viewername;
    }

    public TextSelector getTextSelector() {
        return TextSelectorManager.getInstance().getTextSelector(getSelectorModel().getTextSelectorName());
    }

    public TipComponent createTipComponent(StringVector tipText, boolean hasMore) {
        return new TipComponent(tipText, hasMore);
    }

    class TipComponent extends JPanel {
        StringVector tipText;
        int selected = 0;
        boolean hasMore;

        public TipComponent(StringVector tipText, boolean hasMore) {
            super(new GridLayout(1, 1));
            this.tipText = tipText;
            this.selected = 0;
            this.hasMore = hasMore;
            init();
        }

        private void init() {
            if (hasMore) {
                tipText.append("...");
            }

            setOpaque(true);
            setBorder(new BevelBorder(BevelBorder.LOWERED));
            update();
        }                          

        public void increment() {
            setSelectedIndex(getSelectedIndex() + 1);
        }

        public void decrement() {
            setSelectedIndex(getSelectedIndex() - 1);
        }

        public int getSelectedIndex() {
            return selected;
        }

        public String getSelected() {
            if (hasMore && selected == tipText.size() - 1) {

                return null;
            }

            String ret = tipText.getItem(selected);
            int index = ret.indexOf(';');

            if (index >= 0) {

                ret = ret.substring(0, index);
            }

            return ret;
        }

        public int setSelectedIndex(int n) {
            if (n < 0) {

                n = tipText.size() - 1;
            }

            selected = n % tipText.size();

            update();

            return selected;
        }

        public void update() {
            JPanel panel = new JPanel(new GridBagLayout());
            int i = 0;
            int columns = 1;

            panel.setOpaque(true);

            GridBagConstraints constr = new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0);

            for (String s = tipText.firstItem(); s != null; s = tipText.nextItem()) {
                if (i == 0) {
                    if (s.indexOf(';') > 0) {
                        columns = new StringTokenizer(s, ";").countTokens();
                    }
                }

                String label[] = new String[columns];

                if (columns > 1) {
                    StringTokenizer st = new StringTokenizer(s, ";");
                    int labelcount = 0;

                    while (labelcount < columns) {

                        if (st.hasMoreTokens()) {
                            label[labelcount] = st.nextToken();

                            if (label[labelcount].length() == 0) {
                                label[labelcount] = " ";
                            }
                        } else {
                            label[labelcount] = " ";
                        }

                        ++labelcount;
                    }

                } else {
                    label[0] = s;
                }

                for (int col = 0; col < columns; ++col) {
                    JLabel jlabel = new JLabel(label[col]);

                    jlabel.setOpaque(true);
                    jlabel.setBorder(new EmptyBorder(1, 4, 1, 4));

                    if (i == selected) {
                        jlabel.setBackground(Color.lightGray);
                        jlabel.setForeground(Color.red);
                    } else {
                        jlabel.setBackground(Color.gray);
                        jlabel.setForeground(Color.white);
                    }

                    constr.gridx = col;
                    constr.gridy = i;
                    panel.add(jlabel, constr);
                }

                ++i;
            }

            this.removeAll();
            setLayout(new GridLayout(1, 1));
            add(panel);
            SwingUtilities.invokeLater(new Repainter(this));
        }
    }

    class Repainter implements Runnable {
        JComponent comp;

        public Repainter(JComponent comp) {
            this.comp = comp;
        }

        public void run() {
            comp.revalidate();
        }
    }

    class TargetListener extends DataModelAdaptor {
        StringVector tip = null;
        Object viewer = null;
        JComponent component = null;
        TipComponent tipComponent = null;
        KeyListener popupSelector = null;
        TextSelectorThread thread = null;

        public synchronized JComponent getTextFieldComponent() {
            if (viewer instanceof DataViewer) {

                if (((DataViewer) viewer).isCreated()) {
                    component = ((DataViewer) viewer).getJComponent();
                }
            }

            return component;
        }


        public synchronized void removeTip() {
            JComponent comp = getTextFieldComponent();

            if (comp != null && tipComponent != null) {
                tipComponent.setVisible(false);
                comp.getRootPane().getLayeredPane().remove(tipComponent);
                tipComponent = null;
                tip = null;
            }
        }

        public synchronized void setTip(StringVector tipText, boolean hasMore) {
            if (tipText == null && tip == null) {

                return;
            }

            removeTip();

            tip = tipText;

            JComponent comp = getTextFieldComponent();

            if (comp != null) {

                if (tip == null || tip.size() == 0) {

                    return;
                }

                tipComponent = createTipComponent(tip, hasMore);

                tipComponent.setSize(tipComponent.getPreferredSize());

                Dimension dim = comp.getSize();
                Point p1 = comp.getLocationOnScreen();
                Point p2 = comp.getRootPane().getLocationOnScreen();

                tipComponent.setLocation(p1.x - p2.x, p1.y - p2.y + dim.height);

                comp.getRootPane().getLayeredPane().add(tipComponent, JLayeredPane.POPUP_LAYER);

                comp.requestFocus();
                //tipComponent.addMouseMotionListener(new MouseMotionListener());

                tipComponent.addMouseListener(new MouseListener() {

                    public void mouseClicked(MouseEvent e) {
                        System.out.println("e = " + e);
                    }

                    public void mouseEntered(MouseEvent e) {
                        System.out.println("e = " + e);
                    }

                    public void mouseExited(MouseEvent e) {
                        System.out.println("e = " + e);
                    }

                    public void mousePressed(MouseEvent e) {
                        System.out.println("e = " + e);
                    }

                    public void mouseReleased(MouseEvent e) {
                        System.out.println("e = " + e);
                    }
                });

                SwingUtilities.invokeLater(new Repainter(tipComponent));
            }
        }

        class PopupSelector extends KeyAdapter {
            public void accept() {
                try {
                    if (tipComponent != null) {
                        if (tipComponent.getSelected() == null) {
                            getTextFieldComponent().transferFocus();
                            command.doAction();
                            getTextFieldComponent().requestFocus();
                        } else {
                            getSelectorModel().setText(tipComponent.getSelected());
                            getTextFieldComponent().transferFocus();
                            getTextFieldComponent().requestFocus();
                        }
                    }
                } catch (Exception ex) {
                    System.out.println(ex);
                }
            }

            public void keyPressed(KeyEvent ev) {
                if (ev.getKeyCode() == KeyEvent.VK_RIGHT) {
                    accept();
                } else if (ev.getKeyCode() == KeyEvent.VK_UP && tipComponent != null) {
                    tipComponent.decrement();
                } else if (ev.getKeyCode() == KeyEvent.VK_DOWN && tipComponent != null) {
                    tipComponent.increment();
                } else if (ev.getKeyCode() == KeyEvent.VK_F2) {
                    getTextFieldComponent().transferFocus();
                    command.doAction();
                    getTextFieldComponent().requestFocus();
                }
            }
        }

        class TextSelectorThread extends Thread {
            String text;

            public TextSelectorThread(String text) {
                this.text = text;
                start();
            }

            public void run() {
                try {
                    sleep(300);
                } catch (InterruptedException ex) {
                    return;
                }

                TextSelector textSelector = getTextSelector();
                StringVector tipText = new StringVector();

                boolean hasMore = textSelector.getCompletionListFor(text, tipText);

                if (isInterrupted() || this != thread) {
                    return;
                }

                if (tipText.size() == 1 && text.equals(tipText.firstItem())) {
                    removeTip();
                } else {
                    setTip(tipText, hasMore);
                }
            }
        }

        public void dataModelChangeStructure(DataModelEvent event) {
        }

        public void dataModelGrabFocus(DataModelEvent event) {
        }

        public void dataModelEdit(DataModelEvent event) {
            switch (event.getId()) {

                case DataModelEvent.START_EDIT:
                    viewer = event.getViewer();

                    if (getTextFieldComponent() != null) {
                        getTextFieldComponent().addKeyListener(popupSelector = new PopupSelector());
                    }
                    break;

                case DataModelEvent.FINISH_EDIT:
                case DataModelEvent.CANCEL_EDIT:
                    if (getTextFieldComponent() != null) {
                        getTextFieldComponent().removeKeyListener(popupSelector);
                    }
                    removeTip();
                    viewer = null;
                    break;

                case DataModelEvent.VALUE_EDIT:
                    TextSelector textSelector = getTextSelector();

                    if (textSelector != null) {
                        String text = getTargetText();

                        if (text != null && text.length() >= textSelector.getMinCharsForPopup()) {
                            synchronized (this) {

                                if (thread != null) {
                                    thread.interrupt();
                                }

                                removeTip();

                                thread = new TextSelectorThread(text);
                            }
                        } else {
                            synchronized (this) {

                                if (thread != null) {
                                    thread.interrupt();
                                }

                                removeTip();

                                thread = null;
                            }
                        }
                    }
                    break;
                default:
                    return;
            }
        }
    }
}
TOP

Related Classes of com.nexirius.framework.dataeditor.SelectorEditor$Repainter

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.
script>