Κυριακή 24 Απριλίου 2022

java Python Simple and Light Editor

 Still on building....comsi-comsa !!!
open source (find in below .jar the .java files) 

(
και οταν και αμα το δεις αυτο και το χρησιμοποιησεις...παρε τηλεφωνο !!!

...αναρχικε της ΠΟΥΤΣΑΣ εφοσον οχι μονο δεν 'ηθελες' να το χρησιμοποιησεις
μιας και οπως ειπες 'αν δεν θελεις να χρησιμοποιησεις κατι τοτε δε το χρησιμοποιεις'
-τυφλα να εχει δηλαδη η δηθενια των 'αναρχικων' του συναφιου σου
..... της αλληλο-καλυψης αγαθων
..και περιμενεις απο τους αμερικανους να σου φτιαξουν τα βασικα IDE ...ΜΑΛΑΚΑ
αλλα και ΟΥΤΕ να κερασεις λιγο ιντερνετ δε μπορεσες ...
για να κατεβασει ο αλλος windows....(και να μπορει να εχει υπολογιστη δηλαδη)
.......που να σου ζηταγαμε και λιγο φαι που θα το πληρωνες...
..και μετα σου φταει ο Δενδιας....βλαμμενε !!!!
Ε ΑΙ στο διαολο λοιπον !!!!!!!
)

///supports opening-editing-compiling-running simple java files






 

 

 

May 10

tested on windows 10  with old-low jre-jdk (must be ok for win 7 also)
https://drive.google.com/file/d/1jOve36EsLmhcCZdqItdKkq7NZtkGP7Jx/view?usp=sharing

-----------
May3 -does not support change backup file to usb like the previus

tested on ubuntu 20.04 with hight jre-jdk

 https://drive.google.com/file/d/1I7JcphPnbKJsvOQh_YGwmIp-DlNpZG4r/view?usp=sharing


 


Σάββατο 23 Απριλίου 2022

JTextPane oracle saved me A LOT

 
/*
https://docs.oracle.com/javase/tutorial/uiswing/examples/components/index.html#TextComponentDemo
https://docs.oracle.com/javase/tutorial/displayCode.html?code=https://docs.oracle.com/javase/tutorial/uiswing/examples/components/TextComponentDemoProject/src/components/TextComponentDemo.java
https://docs.oracle.com/javase/tutorial/displayCode.html?code=https://docs.oracle.com/javase/tutorial/uiswing/examples/components/TextComponentDemoProject/src/components/DocumentSizeFilter.java

 */
 
import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
 
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
import javax.swing.undo.*;
 
public class TextComponentDemo extends JFrame {
    JTextPane textPane;
    AbstractDocument doc;
    static final int MAX_CHARACTERS = 300;
    JTextArea changeLog;
    String newline = "\n";
    HashMap<Object, Action> actions;
 
    //undo helpers
    protected UndoAction undoAction;
    protected RedoAction redoAction;
    protected UndoManager undo = new UndoManager();
 
    public TextComponentDemo() {
        super("TextComponentDemo");
 
        //Create the text pane and configure it.
        textPane = new JTextPane();
        textPane.setCaretPosition(0);
        textPane.setMargin(new Insets(5,5,5,5));
        StyledDocument styledDoc = textPane.getStyledDocument();
        if (styledDoc instanceof AbstractDocument) {
            doc = (AbstractDocument)styledDoc;
            doc.setDocumentFilter(new DocumentSizeFilter(MAX_CHARACTERS));
        } else {
            System.err.println("Text pane's document isn't an AbstractDocument!");
            System.exit(-1);
        }
        JScrollPane scrollPane = new JScrollPane(textPane);
        scrollPane.setPreferredSize(new Dimension(200, 200));
 
        //Create the text area for the status log and configure it.
        changeLog = new JTextArea(5, 30);
        changeLog.setEditable(false);
        JScrollPane scrollPaneForLog = new JScrollPane(changeLog);
 
        //Create a split pane for the change log and the text area.
        JSplitPane splitPane = new JSplitPane(
                                       JSplitPane.VERTICAL_SPLIT,
                                       scrollPane, scrollPaneForLog);
        splitPane.setOneTouchExpandable(true);
 
        //Create the status area.
        JPanel statusPane = new JPanel(new GridLayout(1, 1));
        CaretListenerLabel caretListenerLabel =
                new CaretListenerLabel("Caret Status");
        statusPane.add(caretListenerLabel);
 
        //Add the components.
        getContentPane().add(splitPane, BorderLayout.CENTER);
        getContentPane().add(statusPane, BorderLayout.PAGE_END);
 
        //Set up the menu bar.
        actions=createActionTable(textPane);
        JMenu editMenu = createEditMenu();
        JMenu styleMenu = createStyleMenu();
        JMenuBar mb = new JMenuBar();
        mb.add(editMenu);
        mb.add(styleMenu);
        setJMenuBar(mb);
 
        //Add some key bindings.
        addBindings();
 
        //Put the initial text into the text pane.
        initDocument();
        textPane.setCaretPosition(0);
 
        //Start watching for undoable edits and caret changes.
        doc.addUndoableEditListener(new MyUndoableEditListener());
        textPane.addCaretListener(caretListenerLabel);
        doc.addDocumentListener(new MyDocumentListener());
    }
 
    //This listens for and reports caret movements.
    protected class CaretListenerLabel extends JLabel
                                       implements CaretListener {
        public CaretListenerLabel(String label) {
            super(label);
        }
 
        //Might not be invoked from the event dispatch thread.
        public void caretUpdate(CaretEvent e) {
            displaySelectionInfo(e.getDot(), e.getMark());
        }
 
        //This method can be invoked from any thread.  It
        //invokes the setText and modelToView methods, which
        //must run on the event dispatch thread. We use
        //invokeLater to schedule the code for execution
        //on the event dispatch thread.
        protected void displaySelectionInfo(final int dot,
                                            final int mark) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    if (dot == mark) {  // no selection
                        try {
                            Rectangle caretCoords = textPane.modelToView(dot);
                            //Convert it to view coordinates.
                            setText("caret: text position: " + dot
                                    + ", view location = ["
                                    + caretCoords.x + ", "
                                    + caretCoords.y + "]"
                                    + newline);
                        } catch (BadLocationException ble) {
                            setText("caret: text position: " + dot + newline);
                        }
                    } else if (dot < mark) {
                        setText("selection from: " + dot
                                + " to " + mark + newline);
                    } else {
                        setText("selection from: " + mark
                                + " to " + dot + newline);
                    }
                }
            });
        }
    }
 
    //This one listens for edits that can be undone.
    protected class MyUndoableEditListener
                    implements UndoableEditListener {
        public void undoableEditHappened(UndoableEditEvent e) {
            //Remember the edit and update the menus.
            undo.addEdit(e.getEdit());
            undoAction.updateUndoState();
            redoAction.updateRedoState();
        }
    }
 
    //And this one listens for any changes to the document.
    protected class MyDocumentListener
                    implements DocumentListener {
        public void insertUpdate(DocumentEvent e) {
            displayEditInfo(e);
        }
        public void removeUpdate(DocumentEvent e) {
            displayEditInfo(e);
        }
        public void changedUpdate(DocumentEvent e) {
            displayEditInfo(e);
        }
        private void displayEditInfo(DocumentEvent e) {
            Document document = e.getDocument();
            int changeLength = e.getLength();
            changeLog.append(e.getType().toString() + ": " +
                changeLength + " character" +
                ((changeLength == 1) ? ". " : "s. ") +
                " Text length = " + document.getLength() +
                "." + newline);
        }
    }
 
    //Add a couple of emacs key bindings for navigation.
    protected void addBindings() {
        InputMap inputMap = textPane.getInputMap();
 
        //Ctrl-b to go backward one character
        KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_B, Event.CTRL_MASK);
        inputMap.put(key, DefaultEditorKit.backwardAction);
 
        //Ctrl-f to go forward one character
        key = KeyStroke.getKeyStroke(KeyEvent.VK_F, Event.CTRL_MASK);
        inputMap.put(key, DefaultEditorKit.forwardAction);
 
        //Ctrl-p to go up one line
        key = KeyStroke.getKeyStroke(KeyEvent.VK_P, Event.CTRL_MASK);
        inputMap.put(key, DefaultEditorKit.upAction);
 
        //Ctrl-n to go down one line
        key = KeyStroke.getKeyStroke(KeyEvent.VK_N, Event.CTRL_MASK);
        inputMap.put(key, DefaultEditorKit.downAction);
    }
 
    //Create the edit menu.
    protected JMenu createEditMenu() {
        JMenu menu = new JMenu("Edit");
 
        //Undo and redo are actions of our own creation.
        undoAction = new UndoAction();
        menu.add(undoAction);
 
        redoAction = new RedoAction();
        menu.add(redoAction);
 
        menu.addSeparator();
 
        //These actions come from the default editor kit.
        //Get the ones we want and stick them in the menu.
        menu.add(getActionByName(DefaultEditorKit.cutAction));
        menu.add(getActionByName(DefaultEditorKit.copyAction));
        menu.add(getActionByName(DefaultEditorKit.pasteAction));
 
        menu.addSeparator();
 
        menu.add(getActionByName(DefaultEditorKit.selectAllAction));
        return menu;
    }
 
    //Create the style menu.
    protected JMenu createStyleMenu() {
        JMenu menu = new JMenu("Style");
 
        Action action = new StyledEditorKit.BoldAction();
        action.putValue(Action.NAME, "Bold");
        menu.add(action);
 
        action = new StyledEditorKit.ItalicAction();
        action.putValue(Action.NAME, "Italic");
        menu.add(action);
 
        action = new StyledEditorKit.UnderlineAction();
        action.putValue(Action.NAME, "Underline");
        menu.add(action);
 
        menu.addSeparator();
 
        menu.add(new StyledEditorKit.FontSizeAction("12", 12));
        menu.add(new StyledEditorKit.FontSizeAction("14", 14));
        menu.add(new StyledEditorKit.FontSizeAction("18", 18));
 
        menu.addSeparator();
 
        menu.add(new StyledEditorKit.FontFamilyAction("Serif",
                                                      "Serif"));
        menu.add(new StyledEditorKit.FontFamilyAction("SansSerif",
                                                      "SansSerif"));
 
        menu.addSeparator();
 
        menu.add(new StyledEditorKit.ForegroundAction("Red",
                                                      Color.red));
        menu.add(new StyledEditorKit.ForegroundAction("Green",
                                                      Color.green));
        menu.add(new StyledEditorKit.ForegroundAction("Blue",
                                                      Color.blue));
        menu.add(new StyledEditorKit.ForegroundAction("Black",
                                                      Color.black));
 
        return menu;
    }
 
    protected void initDocument() {
        String initString[] =
                { "Use the mouse to place the caret.",
                  "Use the edit menu to cut, copy, paste, and select text.",
                  "Also to undo and redo changes.",
                  "Use the style menu to change the style of the text.",
                  "Use the arrow keys on the keyboard or these emacs key bindings to move the caret:",
                  "Ctrl-f, Ctrl-b, Ctrl-n, Ctrl-p." };
 
        SimpleAttributeSet[] attrs = initAttributes(initString.length);
 
        try {
            for (int i = 0; i < initString.length; i ++) {
                doc.insertString(doc.getLength(), initString[i] + newline,
                        attrs[i]);
            }
        } catch (BadLocationException ble) {
            System.err.println("Couldn't insert initial text.");
        }
    }
 
    protected SimpleAttributeSet[] initAttributes(int length) {
        //Hard-code some attributes.
        SimpleAttributeSet[] attrs = new SimpleAttributeSet[length];
 
        attrs[0] = new SimpleAttributeSet();
        StyleConstants.setFontFamily(attrs[0], "SansSerif");
        StyleConstants.setFontSize(attrs[0], 16);
 
        attrs[1] = new SimpleAttributeSet(attrs[0]);
        StyleConstants.setBold(attrs[1], true);
 
        attrs[2] = new SimpleAttributeSet(attrs[0]);
        StyleConstants.setItalic(attrs[2], true);
 
        attrs[3] = new SimpleAttributeSet(attrs[0]);
        StyleConstants.setFontSize(attrs[3], 20);
 
        attrs[4] = new SimpleAttributeSet(attrs[0]);
        StyleConstants.setFontSize(attrs[4], 12);
 
        attrs[5] = new SimpleAttributeSet(attrs[0]);
        StyleConstants.setForeground(attrs[5], Color.red);
 
        return attrs;
    }
 
    //The following two methods allow us to find an
    //action provided by the editor kit by its name.
    private HashMap<Object, Action> createActionTable(JTextComponent textComponent) {
        HashMap<Object, Action> actions = new HashMap<Object, Action>();
        Action[] actionsArray = textComponent.getActions();
        for (int i = 0; i < actionsArray.length; i++) {
            Action a = actionsArray[i];
            actions.put(a.getValue(Action.NAME), a);
        }
    return actions;
    }
 
    private Action getActionByName(String name) {
        return actions.get(name);
    }
 
    class UndoAction extends AbstractAction {
        public UndoAction() {
            super("Undo");
            setEnabled(false);
        }
 
        public void actionPerformed(ActionEvent e) {
            try {
                undo.undo();
            } catch (CannotUndoException ex) {
                System.out.println("Unable to undo: " + ex);
                ex.printStackTrace();
            }
            updateUndoState();
            redoAction.updateRedoState();
        }
 
        protected void updateUndoState() {
            if (undo.canUndo()) {
                setEnabled(true);
                putValue(Action.NAME, undo.getUndoPresentationName());
            } else {
                setEnabled(false);
                putValue(Action.NAME, "Undo");
            }
        }
    }
 
    class RedoAction extends AbstractAction {
        public RedoAction() {
            super("Redo");
            setEnabled(false);
        }
 
        public void actionPerformed(ActionEvent e) {
            try {
                undo.redo();
            } catch (CannotRedoException ex) {
                System.out.println("Unable to redo: " + ex);
                ex.printStackTrace();
            }
            updateRedoState();
            undoAction.updateUndoState();
        }
 
        protected void updateRedoState() {
            if (undo.canRedo()) {
                setEnabled(true);
                putValue(Action.NAME, undo.getRedoPresentationName());
            } else {
                setEnabled(false);
                putValue(Action.NAME, "Redo");
            }
        }
    }
 
    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event dispatch thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        final TextComponentDemo frame = new TextComponentDemo();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }
 
    //The standard main method.
    public static void main(String[] args) {
        //Schedule a job for the event dispatch thread:
        //creating and showing this application's GUI.
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                //Turn off metal's use of bold fonts
            UIManager.put("swing.boldMetal", Boolean.FALSE);
        createAndShowGUI();
            }
        });
    }
}


class DocumentSizeFilter extends DocumentFilter {
    int maxCharacters;
    boolean DEBUG = false;
 
    public DocumentSizeFilter(int maxChars) {
        maxCharacters = maxChars;
    }
 
    public void insertString(FilterBypass fb, int offs,
                             String str, AttributeSet a)
        throws BadLocationException {
        if (DEBUG) {
            System.out.println("in DocumentSizeFilter's insertString method");
        }
 
        //This rejects the entire insertion if it would make
        //the contents too long. Another option would be
        //to truncate the inserted string so the contents
        //would be exactly maxCharacters in length.
        if ((fb.getDocument().getLength() + str.length()) <= maxCharacters)
            super.insertString(fb, offs, str, a);
        else
            Toolkit.getDefaultToolkit().beep();
    }
     
    public void replace(FilterBypass fb, int offs,
                        int length,
                        String str, AttributeSet a)
        throws BadLocationException {
        if (DEBUG) {
            System.out.println("in DocumentSizeFilter's replace method");
        }
        //This rejects the entire replacement if it would make
        //the contents too long. Another option would be
        //to truncate the replacement string so the contents
        //would be exactly maxCharacters in length.
        if ((fb.getDocument().getLength() + str.length()
             - length) <= maxCharacters)
            super.replace(fb, offs, length, str, a);
        else
            Toolkit.getDefaultToolkit().beep();
    }
 
}

Πέμπτη 21 Απριλίου 2022

Ubuntu javajdk bug JTabbedPane JScrollPane

This bug is not a bug if i am running in windows 7...
It is a bug and application crashes in Ubuntu 20.04 LTS
ANd until i can find a way to report this
either on java or oracle either on ubuntu....
i am making this post.

The problem is that
if we add a javax.swing.JScrollPane
to a javax.swing.JTabbedPane that is NOT VISIBLE
then the application crashes....in Ubuntu 20.04 LTS(not in windows)

But if we add some other component like javax.swing.JTextArea
to a javax.swing.JTabbedPane that is NOT VISIBLE
then is ok.....


But is all ok if the JTabbedPane is Visible (via its frame)
when we add any Component either JScrollPane

So in below code

"play" with the following line to see the bug.....
//UNCOMMENT FOLLOWING  methodStyle=true to run ok

I have just added a little code with JOptionPane to be able to check it
in many OS (windows 7,ubuntu,win 10..etc)

If you dont want to check the code your self then just download this
and if in ubuntu ..properties->permissions->allow executing file as program

https://drive.google.com/file/d/1faR_76E5EjaTDE0bpqT569e2AgsDn9fc/view?usp=sharing

I thing that the method JTabbedPane.addTab(String,Component)
is not provoking the problem(in ubuntu jdk)
but the validate() method is crashing......(of the Frame)



--------------------------------------------------------------

 
package ubuntujdkbugs;

import java.awt.BorderLayout;
import java.awt.Component;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;

public class UbuntuCrashWhenAddJScrollPaneToJTabbedPaneNotBeingVisible {

    public static void main(String[] args) {
        // TODO code application logic here
        JFrame jfr=new JFrame("Ubuntu bug tester JTabbedPane-JScrollPane");
        jfr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jfr.setBounds(111,111,333,333);
        
        /**
         * If this command (jfr.setVisible(true);)
         * is BEFORE we add to JTabbedPane DIRECTLY a JScrollpane
         * then all working fine
         * So i have commented to see what is happening
         * if we call JTabbedPane.addTab("",someJScrollPane)
         * BEFORE this JTAbbepPane is visible
         *
         * But all those are running OK in windows 7
         * Just in Ubuntu i have the problem
         */
        //jfr.setVisible(true);//uncomment this and use below false->run and true->run to see its ok in both cases
        
        JTabbedPane jtp=new JTabbedPane();
        jfr.getContentPane().add(jtp);
        //jfr.validate();//no need for this ...may
        
        System.out.println("adding the JScrollPane");
        boolean methodStyle=true;
        int answer=JOptionPane.showConfirmDialog(null,"Would you like to see the bug ?"
                + "\nby crashing jdk of Ubuntu 20.04 LTS ...?"
                + "\n\nYou must see a JFrame after this..."
                + "\nIf not see then app is crashed ."
                + "\n Press NO to see the NOT CRASHED APPLICATION"
                + "\nPress YES (just enter) and do this "
                + "once in windows and once in ubuntu 20.04 LTS"
                + "\n\n\nYES will add a JScrollPane directly to JTabbedPane with jtp.addTab(\"\",somScrollPane)"
                + "\nNO will add this JScrollPane NOT DIRECTLY but via a new JPanel that has child the JScrollPane"
                ,"mes:Enter or press No",JOptionPane.YES_NO_OPTION);
        
        methodStyle = answer != JOptionPane.YES_OPTION;

        //methodStyle=false;//UN-COMMENT THIS IN UBUNTU AND YOU GET A CRASH
        addScrollableComponent(methodStyle,jtp, new JTextArea("ok"));
        //jtp.addTab("*",new JTextArea("single area"));
        System.out.println("JScrollPane added ok!");
        
        jfr.setVisible(true);
        System.out.println("JFrame is Visible ok");
        
    }
    static void addScrollableComponent(boolean createJPanelSTyle,JTabbedPane jtp,Component c){
        JScrollPane jscr=new JScrollPane(c);
        Component compToAdd=jscr;
        if(createJPanelSTyle){
            JPanel jp=new JPanel(new BorderLayout());
            jp.add(BorderLayout.CENTER,jscr);
            compToAdd=jp;
        }
        
        
        jtp.addTab("*",compToAdd);
        //jtp.validate();
    }

    
}

Τρίτη 19 Απριλίου 2022

java Queue array impl , avoid new () and System.arraycopy

 I am not sure !!!!...

Trying to avoid use some class that 

either creates too much Node Objects (calling new)  like java.util.LinkedList
either makes too much  calls to System.arraycopy like java.util.ArrayList

so......building and testing class Qar<E> and its tester....


---------------------------------------------------------

package jimakoskx.java.liba.dd;

/**

 * Purpose is to avoid

 * 

 * a)System.arraycopies

 * b)making new Node calls

 * 

 * @author jimakoskx

 */

public class Qar<E>{

    

    public static void main(String[] args) {

        Qar t=new Qar(4);

        t.add(0);

        int i=1;

        while(i<t.ar.length){

            t.add(i);

            ++i;

        }

        t.remove();

        t.remove();

        t.remove();


        //System.out.println("pops:"+t.remove());

        

        t.add(i++);

        t.add(i++);

        t.add(i++);

        //t.add(i++);

        t.remove();

        t.remove();

        t.remove();

        

        

        

        t.add(i++);

        t.add(i++);

        t.add(i++);

        //t.add(i++);

        t.remove();

        t.remove();

        t.remove();

        

        

    }

    

    

    int size;

    

    int indF[]=new int[2];

    int indL[]=new int[2];

    int indPrimary=0;

    int indSecondary=1;


    

    Object[] ar;

    boolean isLocking=false;

    private static int defInitArrayLength=10;

    

    int increasingDataMode;

    public Qar() {

        this(defInitArrayLength);

    }

    public Qar(int startingArrayLength) {

        this(startingArrayLength,true,-2);

    }

    public Qar(int startingArrayLength,boolean locking,int increasingAdderOrMultiplierOrCaller) {

        isLocking=locking;

        

        if(increasingAdderOrMultiplierOrCaller==-1){

            increasingAdderOrMultiplierOrCaller=-2;

        }

        increasingDataMode=increasingAdderOrMultiplierOrCaller;

        

        size=0;

        fi(0);

        li(0);

        fiSecondary(0);

        liSecondary(0);

        ar=new Object[startingArrayLength];

    }

    

    public void clear(){

        synchronized(locker){

            size=0;

            fi(0);

            li(0);

            fiSecondary(0);

            liSecondary(0);

            int i=0;

            while(i<ar.length){

                ar[i]=null;

                ++i;

            }

        }

    }

    

    public int getNewIncreasedLength(int oldLen){

        return oldLen*2;

    }

    public final int createNewLength(){

        int out=ar.length;

        if(increasingDataMode>0){

            out+=increasingDataMode;

        }

        else if(increasingDataMode<0){

            out*=(-increasingDataMode);

        }

        else{

            out=getNewIncreasedLength(out);

        }

        return out;

    }

    

    

    final Object locker=new Object();

    public void add(E e){

        if(isLocking){

            addLocked(e);

        }

        else{

            addUnlocked(e);

        }

    }

    public void addLocked(E e){

        synchronized(locker){

            addUnlocked(e);

        }

    }

    int debmod=0;

    public void addUnlocked(E e){

        //String deb=(debmod++)+":";

        int fi=fi();

        int li=li();

        if(li<ar.length){

            ar[li]=e;

            liss();

            ++size;

        }

        else{

            

            int lis=liSecondary();

            if(lis<fi){

                //deb+="will store on front "+lis;

                ar[lis]=e;

                liSecondaryss();

                ++size;

            }

            else{

                //deb+="will quick? increase array";

                Object newar[]=new Object[createNewLength()];

                int len=li-fi;

                int srcpos=0;

                int fis=fiSecondary();

                System.arraycopy(ar,fi, newar,0,len);

                System.arraycopy(ar,fis, newar,len,lis-fis);

                //System.arraycopy(ar, size, deb, debmod, li);

                fiSecondary(0);

                liSecondary(0);

                fi(0);

                li(size);

                

                ar=newar;

                ar[li]=e;

                liss();

                ++size;

            }

        }

        //System.out.println(deb);

        //System.out.println(toString());

        //System.out.println(getTheArrayDebugString());

        //System.out.println("");

        

    }

    public synchronized boolean hasItems(){

        return size>0;

    }

    public E remove(){

        if(isLocking){

            return removeLocked();

        }

        else{

            return removeUnlocked();

        }

    }

    public E removeLocked(){

        synchronized(locker){

            return removeUnlocked();

        }

    }

    public E removeUnlocked(){

        E out=null;

        int fi=fi();

        int li=li();

        if(fi<li){

            out=(E)ar[fi];

            ar[fi]=null;

            fiss();

            --size;

            if(size==0){

                fi(0);

                li(0);

                //System.out.println("zerowed fi-li");

            }

            else if(fi+1==li){

                //System.out.println("-------- exchanging --------");

                exchangeKeysAndMakeZeroSecondaries();

            }

        }

        else{

            int fis=fiSecondary();

            int lis=liSecondary();

            if(fis<lis){

                out=(E)ar[fis];

                ar[fis]=null;

                fiSecondaryss();

                --size;

                if(size==0){

                    fi(0);

                    li(0);

                    fiSecondary(0);

                    liSecondary(0);

                    System.out.println("zeroed all");

                }

            }

            else{

                throw new IllegalArgumentException("No item to be removed ");

            }

        }

        

        //System.out.println("pops: "+out);

        //System.out.println(toString());

        //System.out.println(getTheArrayDebugString());

        //System.out.println("");


        return out;

    }

    

    public E element(){

        return null;

    }

    

    

    

    

    

    int fi(){

        return indF[indPrimary];

    }

    void fiss(){

       ++indF[indPrimary];

    }

    void fi(int val){

       indF[indPrimary]=val;

    }

    int li(){

        return indL[indPrimary];

    }

    void liss(){

        ++indL[indPrimary];

    }

    void li(int val){

        indL[indPrimary]=val;

    }

    int fiSecondary(){

        return indF[indSecondary];

    }

    void fiSecondaryss(){

        ++indF[indSecondary];

    }

    void fiSecondary(int val){

        indF[indSecondary]=val;

    }

    int liSecondary(){

        return indL[indSecondary];

    }

    void liSecondaryss(){

        ++indL[indSecondary];

    }

    void liSecondary(int val){

        indL[indSecondary]=val;

    }

    void exchangeKeysAndMakeZeroSecondaries(){

        int temp=indPrimary;

        indPrimary=indSecondary;

        indSecondary=temp;

        indF[indSecondary]=0;

        indL[indSecondary]=0;

    } 

    

    public String getTheArrayDebugString(){

        String out="";

        int i=fiSecondary();

        int l=liSecondary();

        while(i<l){

            out+=ar[i]+",";

            ++i;

        }

        out+=",,";

        i=fi();

        l=li();

        while(i<l){

            out+=ar[i]+",";

            ++i;

        }

        

        return out;

    }

    public String toString(){

        String out="";

        synchronized(locker){

        int s=size;

        out="Q["+ar.length+"/"+s+"](";

        if(s>0){

            int i=fi();

            int l=li();

            out+=""+ar[i];//.toString();

            ++i;

            while(i<l){

                out+=",";

                out+=""+ar[i];//.toString();

                ++i;

            }

            

            i=fiSecondary();

            l=liSecondary();

            while(i<l){

                out+=",";

                out+=""+ar[i];//.toString();

                ++i;

            }

        }

        out+=")";

        }

        return out;

    }

}




/*

 * To change this license header, choose License Headers in Project Properties.

 * To change this template file, choose Tools | Templates

 * and open the template in the editor.

 */

package jimakoskx.java.liba.dd;


import java.util.ArrayList;

import java.util.LinkedList;

import java.util.Random;

import java.util.Vector;


/**

 *

 * @author jimakoskx

 */

public class QarTest {

    public static void main(String[] args) {

        new QarTest();

    }


    

    /**

     * A thread produces work adding numbers to a Queue

     * onother Thread process this queue poping the first

     * 

     * 

     * 

     * 

     */

    

    

    Thread producer=new Thread(){

        public void run(){

            runProducer();

        }

    };

    

    Thread worker=new Thread(){

        public void run(){

            runWorker();

        }

    };

    

    Thread printer=new Thread(){

        public void run(){

            runPrinter();

        }

    };

    

    

    Qar<Integer>tt=new Qar<>();

    

    QarTest(){

        //tt.isLocking=false;

        producer.setDaemon(true);

        worker.setDaemon(true);

        printer.setDaemon(false);

        

        printer.start();

        producer.start();

        worker.start();

    }

    Random r=new Random();

    

    long produced=0;

    long eachsl=10;

    boolean kpro=true;

    void runProducer(){

        while(kpro){

            

            if(produced-processed>10000){

                try{

                    producer.sleep(eachsl);

                }catch(InterruptedException inter){

                    

                }

            }

            else{

                ++produced;

                tt.add(r.nextInt(1000));

            }

        }

        System.out.println(" --- E N D     P R O D U C E R  ---");

    }

    long processed=0;

    boolean kw=true;

    void runWorker(){

        while(kw){

            if(tt.hasItems()){

                ++processed;

                tt.remove();

            }

            else{

                //try{

                    //worker.sleep(eachsl);

                //}catch(InterruptedException inter){}

            }

        }

        

        System.out.println(" --- E N D     W O R K E R  ---");

    }

    

    void runPrinter(){

        while(true){

            long prod=produced;

            long proc=processed;

            long remains=prod-proc;

            System.out.println(prod+" - "+proc+" = "+remains+"    , ["+tt.ar.length+"]");

            try{

                printer.sleep(1000);

            }catch(InterruptedException inter){


            }

        }

    }

    

}


Παρασκευή 15 Απριλίου 2022

JdoubleMouseDriverField - doubles Editor Mouse Driver

extends javax.swing.JTextField...... 
A better version and standalone instead of previus ...
~1000 code lines,,3 classes 
for easy creating ...." like mspaint" applications 

https://drive.google.com/file/d/1K-S2h-s3bbOdQS6-Zmnmx56p7Pop0eji/view?usp=sharing

The main problem to create a paint application is the complexity.
So user must have as less as i can ,,of swing Components to asjust the Image.
Thats why preparing this class.
To avoid ,as an example, having 4 JTextFields for some Rectangle that we painting.










Read LAST the main to understand


/*

 * Tsoukalas I. Dimitrios jimakoskx@hotmail.com

 */


package jdoublemousedriverfield;



import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Cursor;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.Shape;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.ComponentEvent;

import java.awt.event.ComponentListener;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

import java.awt.event.MouseMotionListener;

import java.awt.geom.Path2D;

import java.lang.reflect.Constructor;

import java.lang.reflect.Field;

import java.util.Vector;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JList;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JSplitPane;

import javax.swing.JTextField;

import javax.swing.event.ListSelectionEvent;

import javax.swing.event.ListSelectionListener;


/**

 *

 * @author jimis

 * @date 14 Απρ 2022

 */

public class JdoubleMouseDriverField extends JTextField implements Stepable{

    

    

    public static void main(String[] args) {

        Vector<Class> vClasses=new Vector();

        Vector<Shape> vShapes=new Vector();

        

        

        vShapes.add(new java.awt.geom.Arc2D.Double(100,0,100,100,45,270,2));

        vClasses.add(java.awt.geom.Arc2D.Double.class);

        

        vShapes.add(new java.awt.geom.CubicCurve2D.Double(0,0,400,400,0,400,300,0));

        vClasses.add(java.awt.geom.CubicCurve2D.Double.class);

        

        vShapes.add(new java.awt.geom.Ellipse2D.Double(100,200,200,100));

        vClasses.add(java.awt.geom.Ellipse2D.Double.class);

        

        vShapes.add(new java.awt.geom.Line2D.Double(100,100,200,200));

        vClasses.add(java.awt.geom.Line2D.Double.class);

        

        vShapes.add(new java.awt.geom.QuadCurve2D.Double(400,400,0,0,0,400));

        vClasses.add(java.awt.geom.QuadCurve2D.Double.class);

        

        vShapes.add(new java.awt.geom.Rectangle2D.Double(10,10,100,100));

        vClasses.add(java.awt.geom.Rectangle2D.Double.class);

        

        vShapes.add(new java.awt.geom.RoundRectangle2D.Double(20,20,80,80,40,20));

        vClasses.add(java.awt.geom.RoundRectangle2D.Double.class);

        

        JList<Shape> jli=new JList<>(vShapes);

        jli.putClientProperty("type",0);

        

        JPanel jpDraw=new JPanel(){

            public void paintComponent(Graphics gr){

                super.paintComponent(gr);

                Graphics2D g=(Graphics2D)gr;

                int i=0,l=vShapes.size();

                while(i<l){

                    g.draw(vShapes.get(i));

                    ++i;

                }

                

            }

        };

        

        

        Vector <Constructor> vCons=new Vector<>();

        Vector<JdoubleMouseDriverField>vDrivers=new Vector<>();

        Vector<String> vFieldsNamesStrings=new Vector<>();

        Vector<Vector<Field>> vVFields=new Vector<>();

        //JComboBox<String> jcmb=new JComboBox<>();

        Class cl;

        Constructor con;

        JdoubleMouseDriverField jtest;

        int i=0,l=vClasses.size();

        Class paramsNull[]=null;

        JTextField jtfFieldValues=new JTextField();

        try{

            while(i<l){

                cl=vClasses.get(i);

                con=cl.getConstructor(paramsNull);

                System.out.println(""+con);

                Field fs[]=cl.getDeclaredFields();

                int j=0;

                String fsnames="";

                Vector<Field> vfs=new Vector<>();

                while(j<fs.length){

                    if(fs[j].getType()==double.class){

                        fsnames+=fs[j].getName()+",";

                        vfs.add(fs[j]);

                        //System.out.println(j+" "+fs[j].getName()+" , "+fs[j].getType());

                    }

                    ++j;

                }

                vFieldsNamesStrings.add(fsnames);

                vVFields.add(vfs);

                vCons.add(con);

                

                jtest=new JdoubleMouseDriverField(fs.length-1){

                    @Override

                    public boolean setValueAtIndex(int index, double neo) {

                        boolean outfromsuper= super.setValueAtIndex(index, neo); 

                        Shape sh=jli.getSelectedValue();

                        if(sh!=null){

                            int type=(int)jli.getClientProperty("type");

                            Vector<Field> vFs=vVFields.get(type);

                            Field field=vFs.get(index);

                            //System.out.println("type->"+type+" field:"+index+" "+field.getName());

                            try{

                                field.set(sh, neo);

                                jpDraw.repaint();

                                

                            }catch(Exception e){

                                e.printStackTrace();

                            }

                        }

                        

                        jtfFieldValues.setText(this.valuesText);


                        return outfromsuper;

                    }

                    

                };

                jtest.invert(1).invert(3);//all 

                jtest.qArrowColor(new Color(cl.getName().hashCode()));

                vDrivers.add(jtest);

                //jcmb.addItem(cl.getName());

                ++i;

            }

            

        }catch(Exception e){

            e.printStackTrace();

        }

        

        //invert also some other indexes

        vDrivers.get(1).invert(5).invert(7);//CubicCurve ys

        vDrivers.get(4).invert(5);//QuadCurve ys

        

        

        JButton jbNew=new JButton("new copy selected");

        JButton jbRemove=new JButton("remove");

        JPanel jplinorth=new JPanel(new BorderLayout());

        jplinorth.add(BorderLayout.WEST,jbNew);

        jplinorth.add(BorderLayout.EAST,jbRemove);

        //jplinorth.add(BorderLayout.CENTER,jcmb);

        

        JPanel jplisouth=new JPanel(new BorderLayout());

        JTextField jtfFieldNames=new JTextField();

        jtfFieldNames.setEditable(false);

        jtfFieldValues.setEditable(false);

        

        JPanel jpli=new JPanel(new BorderLayout());

        jpli.add(BorderLayout.CENTER,new JScrollPane(jli));

        jpli.add(BorderLayout.NORTH,jplinorth);

        jpli.add(BorderLayout.SOUTH,jplisouth);


        

        

        jli.addListSelectionListener(new ListSelectionListener() {

            @Override

            public void valueChanged(ListSelectionEvent e) {

                Shape sh=jli.getSelectedValue();

                if(sh!=null){

                    Class cl=sh.getClass();

                    int clind=vClasses.indexOf(cl);

                    if(clind>-1){

                        jli.putClientProperty("type",clind);

                        jplisouth.removeAll();

                        JdoubleMouseDriverField jtestToBeSetted=vDrivers.get(clind);

                        jplisouth.add(BorderLayout.CENTER,jtestToBeSetted);

                        jtfFieldNames.setText(vFieldsNamesStrings.get(clind));

                        jplisouth.add(BorderLayout.SOUTH,jtfFieldNames);

                        jplisouth.validate();

                        jplisouth.repaint();

                        

                        ///////////////////

                        

                        Vector<Field> vFs=vVFields.get(clind);

                        int i=0;

                        double val;

                        while(i<vFs.size()){

                            try{

                                val=vFs.get(i).getDouble(sh);

                                //System.out.println(i+" : "+val);

                                jtestToBeSetted.setValueAtIndex(i, val);

                                

                            }catch(Exception ex){

                                ex.printStackTrace();

                            }

                            ++i;

                        }

                        

                    }

                }

            }

        });

        jli.setSelectedIndex(0);

        

        

        

        

        

        JFrame jfr=new JFrame("src @.jar - test/show JdoubleMouseDriverField.class -  Right (or left/middle) press on ARROWS !");

        jfr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        jfr.setBounds(0,0,888,555);

        JPanel jpEdit=new JPanel(new BorderLayout());

        JSplitPane jspl=new JSplitPane(1,jpli,jpDraw);

        

        

        

        

        jfr.getContentPane().add(BorderLayout.CENTER,jspl);

        jfr.getContentPane().add(BorderLayout.SOUTH,jtfFieldValues);

        jfr.setVisible(true);

        

        

        jbNew.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e){

                

                Shape selShape=jli.getSelectedValue();

                if(selShape!=null){

                    int type=(int)jli.getClientProperty("type");

                    Object nullParams[]=null;

                    try{

                        Shape neoShape=(Shape)vCons.get(type).newInstance(nullParams);

                        //System.out.println(selShape+" , "+neoShape);

                        Vector<Field> vFs=vVFields.get(type);

                        int i=0;

                        Field ff;

                        while(i<vFs.size()){

                            ff=vFs.get(i);

                            double val=ff.getDouble(selShape);

                            ff.set(neoShape, val+10);

                            //System.out.println(i+" setted "+val);

                            ++i;

                        }

                        vShapes.add(neoShape);

                        jli.setListData(vShapes);

                        jli.setSelectedIndex(vShapes.size()-1);

                        jli.ensureIndexIsVisible(jli.getSelectedIndex());

                    }catch(Exception ee){

                        ee.printStackTrace();

                    }

                }


            }

        });

        jbRemove.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e){

                int ind=jli.getSelectedIndex();

                if(ind>6){

                    vShapes.remove(ind);

                    jli.setListData(vShapes);

                    if(ind<vShapes.size()){

                        

                    }

                    else{

                        --ind;

                    }

                    if(ind>-1){

                        jli.setSelectedIndex(ind);

                        jli.ensureIndexIsVisible(ind);

                    }

                }

                else{

                    JOptionPane.showMessageDialog(jli, "Use this as prototype.Cant remove");

                }

            }

        });

        

    }

    

    

    protected static final Stepper stepThread=new Stepper(100);

    

    protected static final ComponentListener jtfCL=new ComponentListener() {

        @Override

        public void componentResized(ComponentEvent e) {

            ((JdoubleMouseDriverField)e.getComponent()).jtfcomponentResized(e);

        }

        @Override

        public void componentMoved(ComponentEvent e) {

            ((JdoubleMouseDriverField)e.getComponent()).jtfcomponentMoved(e);

        }

        @Override

        public void componentShown(ComponentEvent e) {

            ((JdoubleMouseDriverField)e.getComponent()).jtfcomponentShown(e);

        }

        @Override

        public void componentHidden(ComponentEvent e) {

            ((JdoubleMouseDriverField)e.getComponent()).jtfcomponentHidden(e);

        }

    };

    protected static final MouseListener jtfML=new MouseListener() {

        @Override

        public void mouseClicked(MouseEvent e) {

            ((JdoubleMouseDriverField)e.getComponent()).jtfmouseClicked(e);

        }

        @Override

        public void mousePressed(MouseEvent e) {

            ((JdoubleMouseDriverField)e.getComponent()).jtfmousePressed(e);

        }

        @Override

        public void mouseReleased(MouseEvent e) {

            ((JdoubleMouseDriverField)e.getComponent()).jtfmouseReleased(e);

        }

        @Override

        public void mouseEntered(MouseEvent e) {

            ((JdoubleMouseDriverField)e.getComponent()).jtfmouseEntered(e);

        }

        @Override

        public void mouseExited(MouseEvent e) {

            ((JdoubleMouseDriverField)e.getComponent()).jtfmouseExited(e);

        }

    };

    protected static final MouseMotionListener jtfMML=new MouseMotionListener() {

        @Override

        public void mouseDragged(MouseEvent e) {

            ((JdoubleMouseDriverField)e.getComponent()).jtfmouseDragged(e);

        }

        @Override

        public void mouseMoved(MouseEvent e) {

            ((JdoubleMouseDriverField)e.getComponent()).jtfmouseMoved(e);

        }

    };

    

    protected double[] values;

    protected double[] valuesMin;

    protected double[] valuesMax;

    protected double[][] valuesDefAndDifs;//default, dif normal, dif small,dif Big

    

    protected boolean[] inverted;

    

    

    

    protected float[] valuesDrawingWidthPercentage;

    protected int[] valuesDrawingWidthActual;

    protected boolean[] valuesDrawingVertical;

    

    public static final int decr=0;

    public static final int incr=1;

    

    protected Color[][] valuesColor;

    protected Path2D[][] valuesPath;

    

    


            

    


    

    public JdoubleMouseDriverField(){

        this(2);

    }

    public JdoubleMouseDriverField(int size){

        this(size,false);

    }

    public JdoubleMouseDriverField(int size,int orientationOfFirstArrows){

        this(size,orientationOfFirstArrows,false);

    }

    public JdoubleMouseDriverField(int size,boolean nextOrientationSame){

        this(size,JSplitPane.HORIZONTAL_SPLIT,nextOrientationSame);

    }

    public JdoubleMouseDriverField(int size,int orientationOfFirstArrows,boolean nextOrientationSame){

        constructingJNumbersField0(size, orientationOfFirstArrows, nextOrientationSame);

        resetTextFromCurrentValues();

        qCursorCrossHair();

        

        

        stepThread.checkToStart();

        

        super.addComponentListener(jtfCL);

        super.addMouseListener(jtfML);

        super.addMouseMotionListener(jtfMML);

    }

    protected void initilisingArrays(int size){

        values=new double[size];

        values=new double[size];

        valuesDefAndDifs=new double[4][size];

        valuesMin=new double[size];

        valuesMax=new double[size];

        inverted=new boolean[size];

        

        valuesColor=new Color[2][size];

        valuesPath=new Path2D[2][size];

        valuesDrawingWidthPercentage=new float[size];

        valuesDrawingWidthActual=new int[size];

        valuesDrawingVertical=new boolean[size];

    }

    protected void constructingJNumbersField0(int size,int orientationOfFirstArrows,boolean nextOrientationSame){

        size=Math.max(1, size);

        initilisingArrays(size);

        int i=0;

        boolean verticalArrows=orientationOfFirstArrows==JSplitPane.VERTICAL_SPLIT;

            

        while(i<size){

            values[i]=createDefaultValue(i);

            valuesDefAndDifs[0][i]=(createDefaultValue(i));

            valuesDefAndDifs[MouseEvent.BUTTON1][i]=(createDefaultValueDif(i));

            valuesDefAndDifs[MouseEvent.BUTTON2][i]=(createDefaultValueDifSmall(i));

            valuesDefAndDifs[MouseEvent.BUTTON3][i]=(createDefaultValueDifBig(i));

            valuesMin[i]=(createDefaultValueMin(i));

            valuesMax[i]=(createDefaultValueMax(i));

            inverted[i]=(createDefaultInverted(i));

            

            

            valuesColor[decr][i]=(createDefaultValueArrowColorDecr(i));

            valuesColor[incr][i]=(createDefaultValueArrowColorIncr(i));

            valuesPath[decr][i]=(createDefaultValueArrowPathDecr(i));

            valuesPath[incr][i]=(createDefaultValueArrowPathIncr(i));

            valuesDrawingWidthPercentage[i]=(createDefaultValuesDrawingWidthPercentage(i));

            valuesDrawingWidthActual[i]=(50);//some default actual width

            valuesDrawingVertical[i]=(verticalArrows);

            if(!nextOrientationSame){

                verticalArrows=!verticalArrows;

            }

            ++i;

        }

        


        

        

    }

    

    public double createDefaultValue(int index){

        return 0.0;//Math.random();

    }

    public double createDefaultValueDefault(int index){

        return 0.0;

    }

    public double createDefaultValueDif(int index){

        return 1.0;

    }

    public double createDefaultValueDifBig(int index){

        return 10.0;

    }

    public double createDefaultValueDifSmall(int index){

        return 0.1;

    }

    public double createDefaultValueMax(int index){

        return Integer.MAX_VALUE;

    }

    public double createDefaultValueMin(int index){

        return Integer.MIN_VALUE;

    }

    public boolean createDefaultInverted(int index){

        return false;

    }

    public double createDefaultValueDirectionIncreaseMultiplier(int index){

        return 1.0;

    }

    public static Color defArrowColor=new Color(255,0,0,90);

    public Color createDefaultValueArrowColorIncr(int index){

        return defArrowColor;

    }

    public Color createDefaultValueArrowColorDecr(int index){

        return defArrowColor;

    }

    public Path2D createDefaultValueArrowPathIncr(int index){

        return new Path2D.Double();

    }

    public Path2D createDefaultValueArrowPathDecr(int index){

        return new Path2D.Double();

    }

    public float createDefaultValuesDrawingWidthPercentage(int index){

        float out=1f;

        out/=values.length;

        return out;

    }

    

    

    

    public String createTextForCurrentValues(){

        String out="";

        int i=0;

        int l=values.length-1;

        while(i<l){

            out+=getTextForValue(i)+" , ";

            ++i;

        }

        out+=getTextForValue(i);

        return out;

    }

    /**

     * Override with some formatter etc...

     * @param index

     * @return double as it is 

     */

    public String getTextForValue(int index){

        return values[index]+"";//String.format("%.2f", val);

    }

    protected String valuesText=""; 

    /**

     * Not seting JTextField text <br>

     * because supposed to be as minimised as application wants<br>

     * to not trigger some JScrollPane<br>

     * This is the purpose of class<br>

     * Arrows always visble to user to press them<br>

     * If want values visible then override<br>

     * or override making some call to setText for other JTextFields...<br>

     * 

     * But because of this (no text in JTextField)<br>

     * may need to call setPrefferedSize(some min dimention) to ensure is visble

     */

    public void resetTextFromCurrentValues(){

        valuesText=createTextForCurrentValues();

        setToolTipText(valuesText);

        //setText(valuesText);

    }


    public JdoubleMouseDriverField q(Cursor cursor) {super.setCursor(cursor); return this;}

    public JdoubleMouseDriverField qCursorCrossHair() {super.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); return this;}

    public JdoubleMouseDriverField qCursorHand() {super.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); return this;}

    public JdoubleMouseDriverField qCursorMove() {super.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); return this;}

    public JdoubleMouseDriverField qCursorText() {super.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); return this;}

    public JdoubleMouseDriverField qCursorWait() {super.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); return this;}

    public JdoubleMouseDriverField qArrowColor(Color c){

        int i=0;

        int l=values.length;

        while(i<l){

            valuesColor[decr][i]=c;

            valuesColor[incr][i]=c;

            ++i;

        }

        return this;

    }

    public JdoubleMouseDriverField invert(int ind){

        inverted[ind]=!inverted[ind];

        return this;

    }

    

    

    

    protected int prw=0,prh=0;

    protected long prwhchanged=0,prwhtimegap=100;

    

    

    protected void jtfcomponentResized(ComponentEvent e) {

        int nw=getWidth();

        int nh=getHeight();

        long ct=System.currentTimeMillis();

        if((nw!=prw || nh!=prh)&&(ct-prwhchanged>prwhtimegap)){

            int hmiddle=nh/2;

            int hmup=hmiddle;

            int hmdown=hmiddle+1;


            int i=0,l=values.length;

            float percentwidth;

            int prevwidth=0;

            int actualwidth;

            int totalwidth=0;

            Path2D p;

            while(i<l){

                percentwidth=valuesDrawingWidthPercentage[i];

                actualwidth=(int)(percentwidth*nw);

                totalwidth+=actualwidth;

                valuesDrawingWidthActual[i]=actualwidth;


                if(valuesDrawingVertical[i]){

                    p=valuesPath[decr][i];

                    p.reset();

                    p.moveTo(prevwidth,hmdown);

                    p.lineTo(prevwidth+actualwidth, hmdown);

                    p.lineTo(prevwidth+actualwidth/2, nh);

                    p.closePath();


                    p=valuesPath[incr][i];

                    p.reset();

                    p.moveTo(prevwidth,hmup);

                    p.lineTo(prevwidth+actualwidth, hmup);

                    p.lineTo(prevwidth+actualwidth/2, 0);

                    p.closePath();

                }

                else{

                    p=valuesPath[decr][i];

                    p.reset();

                    p.moveTo(-1+prevwidth+actualwidth/2,0);

                    p.lineTo(-1+prevwidth+actualwidth/2, nh);

                    p.lineTo(prevwidth, hmiddle);

                    p.closePath();


                    p=valuesPath[incr][i];

                    p.reset();

                    p.moveTo(prevwidth+actualwidth/2,0);

                    p.lineTo(prevwidth+actualwidth/2, nh);

                    p.lineTo(prevwidth+actualwidth, hmiddle);

                    p.closePath();

                }

                prevwidth+=actualwidth;


                ++i;

            }

            

            //int remains=nw-totalwidth;

            //System.out.println(""+valuesDrawingWidthActual);

            //System.out.println("Remains "+remains+" / "+nw);

            

            prw=nw;

            prh=nh;

            prwhchanged=System.currentTimeMillis();

            repaint();

        }

        //else{

            //if(nw==prw || nh==prh){System.out.println("Skipping "+prw+","+prh+" -> "+nw+","+nh);}

            //else{System.out.println("Skipping from timegap avoiding overworking");}

        //}

        

    }


    protected void jtfcomponentMoved(ComponentEvent e) {

    }


    protected void jtfcomponentShown(ComponentEvent e) {

        System.out.println("componentShown");

    }


    protected void jtfcomponentHidden(ComponentEvent e) {

        System.out.println("componentHidden");

        

    }


    @Override

    protected void paintComponent(Graphics gr) {

        super.paintComponent(gr);

        Graphics2D g=(Graphics2D)gr;

        int i=0,l=values.length;

        while(i<l){

            g.setColor(valuesColor[decr][i]);

            g.fill(valuesPath[decr][i]);

            g.setColor(valuesColor[incr][i]);

            g.fill(valuesPath[incr][i]);

            ++i;

        }

        

    }

    

    

    

    

    public static int encode(boolean decr,int i){

        if(decr){

            i++;

            i=-i;

        }

        return i;

    }

    /**

     * 

     * @param xonjtf

     * @param yonjtf

     * @return  values.length if not found<br>

     * or the normal index if found on INCREASING array([1]) <br>

     * or -1-index if found to DECREASING arra([0])

     */

    public int getIndexOfPathContains(int xonjtf,int yonjtf){

        int i=0,l=values.length;

        while(i<l){

            int j=0;

            while(j<2){

                if(valuesPath[j][i].contains(xonjtf, yonjtf)){

                    return encode(j==0, i);

                }

                ++j;

            }

            ++i;

        }

        return l;

    }

    

    

    

    

    

    

    

    private int steppingJ,steppingI;

    private int buttonPressed;

    private boolean isNowDragging;

    private boolean isMultiplying;

    private synchronized void setStepperJIAndUnpausedIfPaused(int j,int i){

        

        steppingJ=j;

        steppingI=i;

        stepThread.setStepable(this);

        stepThread.unpauseIfPaused();

    }

    public synchronized void executeNextStep(){

        int i,j;

        i=steppingI;//sync?

        j=steppingJ;//sync?


        

        double neo=values[i];

        double dif=valuesDefAndDifs[buttonPressed][i];

        

        if(j==0){//decreasingArrow

            dif=-dif;

        }

        if(inverted[i]){

            dif=-dif;

        }

        if(isMultiplying){

            dif*=10;

        }

        neo+=dif;


        setValueAtIndex(i, neo);

        

        System.out.println(values[i]+" from stepping! ["+j+"]["+i+"]");

    }

    

    public boolean setValueAtIndex(int index,double neo){

        if(neo>=valuesMin[index] && neo<=valuesMax[index]){

            values[index]=neo;

            resetTextFromCurrentValues();

            return true;

        }

        else{

            System.out.println("not accepted");

            return false;

        }

        

    }


    protected void jtfmouseClicked(MouseEvent e) {

        //System.out.println(" clicked ");

    }

    protected void jtfmouseEntered(MouseEvent e) {

        //System.out.println("entered");

    }


    protected void jtfmouseExited(MouseEvent e) {

        //System.out.println("exited");

        stepThread.setPaused();//in case arrows path are ...strange!

    }

    protected void jtfmouseMoved(MouseEvent e) {

    }


    protected void jtfmousePressed(MouseEvent e) {

        //System.out.println("pressed "+e.getWhen());

        int but=e.getButton();

        if(but<valuesDefAndDifs.length  && but >0){

            buttonPressed=but;

            isNowDragging=true;

            int pathIndexEncodedPressed=getIndexOfPathContains(e.getX(),e.getY());

            if(pathIndexEncodedPressed<values.length){

                int pathJPressed=1;

                int pathIPressed=pathIndexEncodedPressed;

                if(pathIndexEncodedPressed<0){

                    pathJPressed=0;

                    pathIPressed=-(pathIndexEncodedPressed+1);

                }

                setStepperJIAndUnpausedIfPaused(pathJPressed, pathIPressed);

            }//else{System.out.println("pressed outside of all paths");}

        }//else{System.out.println("Not acceptable button "+but);}

    }


    protected void jtfmouseReleased(MouseEvent e) {

        //System.out.println("released "+e.getWhen());

        if(e.getButton()==buttonPressed){

            isNowDragging=false;

            stepThread.setPaused();

        }

        

    }



    protected void jtfmouseDragged(MouseEvent e) {

        if(isNowDragging){

            int pathIndexEncodedDragged=getIndexOfPathContains(e.getX(),e.getY());

            if(pathIndexEncodedDragged<values.length){

                int pathJDragged=1;

                int pathIDragged=pathIndexEncodedDragged;

                if(pathIndexEncodedDragged<0){

                    pathJDragged=0;

                    pathIDragged=-(pathIndexEncodedDragged+1);

                }

                setStepperJIAndUnpausedIfPaused(pathJDragged, pathIDragged);

            }

            else{

                stepThread.setPaused();

            }

        }

    }


    


}



interface Stepable {

    

    public void executeNextStep();


}



class Stepper extends Thread{

    

    private Stepable src;

    private long steptime;

    private long pausedtime;

    private boolean paused;

    private final Object locker=new Object();

    public Stepper(long sleepStep,long sleepPaused){

        super();

        super.setDaemon(true);

        steptime=sleepStep;

        pausedtime=sleepPaused;

        paused=true;

    }

    public Stepper(long sleepStep){

        this(sleepStep,3600000);

    }

    public Stepper(){

        this(1000);

    }

    private boolean hasStarted=false;

    public synchronized void checkToStart(){

        if(!hasStarted){

            start();

        }

    }

    @Override

    public synchronized void start() {

        hasStarted=true;

        super.start();

    }

    

    

    public void run(){

        while(true){

            if(paused){

                try{

                    sleep(pausedtime);

                }catch(InterruptedException inter){

                    //System.out.println("Stepper unpaused from big sleep "+inter);

                }

            }

            else{

                synchronized(locker){

                    if(src!=null){

                        src.executeNextStep();

                        try{

                            sleep(steptime);

                        }catch(InterruptedException inter){

                            //System.out.println("????? Stepper ???? interrupted on unpaused ?");

                            //means slept after step,made paused ,and unpaused before wake from sleep after step

                            //inter.printStackTrace();

                        }

                    }

                    else{

                        paused=true;

                    }

                }

            }

        }

    }

    public void setStepable(Stepable somesrc){

        if(src!=somesrc){

            synchronized(locker){

                src=somesrc;

            }

        }

    }

    

    public void unpauseIfPaused(){

        if(paused){

            paused=false;

            interrupt();

        }

    }

    public void setPaused(){

        paused=true;

    }


}