среда, 25 декабря 2013 г.

Случайно стал модератором сайта по VBA
http://www.quizful.net/test/vba-excel

Вот так вот. 

среда, 16 октября 2013 г.

Немного статистики по одной игре

 (по остальным примерно та же картина)

По странам:

По устройствам:



Приложения не рекламирую. Кто скачает - тот скачает. 

Поле с автозаполнением на основе JTextArea


Люблю Java за то, что на ней приятно логику писать. Просто нереально приятно!

Но когда дело доходит то графики - все немного усложняется. Многих Java из-за этого отпугивает. Пока "врубишься" во все тонкости принципа "написал раз - работает везде" применительно к интерфейсу, особенно применительно к Swing, вспотеешь...

Делаю приложение, соединяющееся с БД через SQL (толстого клиента, без Web). Пользователь должен заполнять поля формы, список значений в которых ограничен списком из БД. И нет в стандартной библиотеке готового компонента (JComboBox, JList, JTextField или JTextArea), который бы автоматически заполнялся (или фильтровал список выбора) при вводе данных с клавиатуры (список очень большой - без этого никак). Вроде есть на сайтах информация как это сделать - но не сразу въедешь.

Поэтому кидаю для всех желающих готовый компонент. Он расширяет  JTextArea.

Сразу напишу - что за основу брал уже написанный кем-то в сети код - но он не совсем корректно работал в некоторых ситуациях. Пришлось допиливать (оригинал тут ).

А теперь собственно код:


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.BorderFactory;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;

public class JTextAreaAutocompleted extends JTextArea{
private List<String> dataList;
private SuggestionPanel suggestion;
private JTextArea textarea;

public JTextAreaAutocompleted(List<String> dataList,String startValue) {
super(24, 80);
this.setText(startValue);
this.dataList=dataList;
textarea=this;

    textarea.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
    textarea.addKeyListener(new KeyListener() {

            @Override
            public void keyTyped(KeyEvent e) {
                if (e.getKeyChar() == KeyEvent.VK_ENTER) {
                 if (textarea.getText().length()==1){
                 textarea.setText("");
                 e.consume();
                 showSuggestionLater();
                 }
                    if (suggestion != null) {
                        if (suggestion.insertSelection()) {
                            e.consume();
                        }
                    }
                
                }
            }

            @Override
            public void keyReleased(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_DOWN && suggestion != null) {
                    suggestion.moveDown();
                } else if (e.getKeyCode() == KeyEvent.VK_UP && suggestion != null) {
                    suggestion.moveUp();
                } else if (Character.isLetterOrDigit(e.getKeyChar())) {
                    showSuggestionLater();
                }else if (e.getKeyCode() == KeyEvent.VK_ENTER){
                 hideSuggestion();
                }
            }

            @Override
            public void keyPressed(KeyEvent e) {

            }
        });  
    
}

class SuggestionPanel {
        private JList list;
        private JPopupMenu popupMenu;


        public SuggestionPanel(JTextArea textarea, int position, String subWord, Point location) {        
                 
            list = createSuggestionList(position, subWord);        
            popupMenu = new JPopupMenu();
            popupMenu.removeAll();                    
            popupMenu.setOpaque(false);
            popupMenu.setBorder(null);
            JScrollPane jpPM=new JScrollPane(list);
            jpPM.setPreferredSize(new Dimension(600,500));
            popupMenu.add(jpPM, BorderLayout.CENTER);
        
            if (list.getModel().getSize()==0){
        
         } else{
         popupMenu.show(textarea, location.x+30, textarea.getBaseline(0, 0) + location.y);    
         }        

        }

        public void hide() {
            popupMenu.setVisible(false);      
            suggestion = null;
     
        }
        private List<String> getFiltredList(final String subWord){
         List<String> listFiltered=new ArrayList<String>();        
         for (String s: dataList){
         String subWordCorrect=subWord;         
         Pattern p=Pattern.compile("^"+subWordCorrect+".*", Pattern.CASE_INSENSITIVE+Pattern.UNICODE_CASE);
         Matcher m = p.matcher(s);        
         if (m.matches()){        
         listFiltered.add(s);
         }        
            }
        
return listFiltered;        
        }
     
        private JList createSuggestionList(final int position, final String subWord) {
         List<String> listFiltered=getFiltredList(subWord);

            Object[] data = listFiltered.toArray();//new Object[10];
         
            JList list = new JList(data);
            list.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
            list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            list.setSelectedIndex(0);
            list.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {                
                    if (e.getClickCount() == 2) {
                        insertSelection();
                        suggestion.hide();
                    }
                }
            });              
       
            return list;
        }

        public boolean insertSelection() {
            if (list.getSelectedValue() != null) {
                final String selectedSuggestion = ((String) list.getSelectedValue());
    textarea.setText(selectedSuggestion);
    return true;
            }
            return false;
        }

        public void moveUp() {
            int index = Math.min(list.getSelectedIndex() - 1, 0);
            selectIndex(index);
        }

        public void moveDown() {
            int index = Math.min(list.getSelectedIndex() + 1, list.getModel().getSize() - 1);
            selectIndex(index);
        }

        private void selectIndex(int index) {
            final int position = textarea.getCaretPosition();
            list.setSelectedIndex(index);
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    textarea.setCaretPosition(position);
                };
            });
        }
    }
 
    protected void showSuggestionLater() {   
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                showSuggestion();
            }
        });
    }

    protected void showSuggestion() {
        hideSuggestion();
        final int position = textarea.getCaretPosition();
        Point location;
        try {
            location = textarea.modelToView(position).getLocation();
        } catch (BadLocationException e2) {
            e2.printStackTrace();
            return;
        }
        String text = textarea.getText();
        int start = Math.max(0, position - 1);
        while (start > 0) {
         start--;
        }
        if (start > position) {
            return;
        }
        String subWord = text.substring(start, position);
        if (subWord.length() < 1) {
         //Test.w();
         suggestion = new SuggestionPanel(textarea, position, subWord, location);
            return;
        }
        suggestion = new SuggestionPanel(textarea, position, subWord, location);
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                textarea.requestFocusInWindow();
            }
        });
    }

    private void hideSuggestion() {
        if (suggestion != null) {
            suggestion.hide();        
        }
    }
}


Вам осталось только заменить  функцию getFiltredList на возвращение своего списка значений.
Если пригодилось - сообщайте. Комментируйте, если найдете ошибки! 

четверг, 21 марта 2013 г.

О результатах размещения приложений на Google Play...


Короче говоря, результат по нулям. Платных скачивается дай бог  4 шт/мес (все по 1 баксу), бесплатных скачивается значительно больше (на некоторых моих приложениях на Google Play - уже более 1500 скачиваний). Мало скачиваний потому, что это так называемые quiz.

Но зато круто стал программировать в java. Получил синий пояс на knowledgeblackbelt.com, пока тот не закрыли. Попробуем теперь кое-что еще...