среда, 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, пока тот не закрыли. Попробуем теперь кое-что еще...   

вторник, 16 октября 2012 г.

Опять про Google Play....


Накапало уже на Google Play порядка 10 баксов. Правда приложения простенькие. Порядка 10 шт. Одно скоро наберет 1000 бесплатных скачиваний уже.

Открыл для себя knowledgeblackbelt.com. И уже заработал на оранжевый пояс. Скоро получу зеленый - 2 балла всего осталось. Надо Swing повторить.

суббота, 7 апреля 2012 г.

О хорошем в разработке приложений 


Приятно, что твое приложение интересно людям из стольких стран. Однако пора думать о монетизации. Продажи пока на нуле. Скачивают бесплатные версии

понедельник, 2 апреля 2012 г.

Три приложения для Android!

Опубликовал уже три приложения. Но пришлось делать версию Lite (4-е приложение) бесплатную. И сразу начались первые закачки....

суббота, 24 марта 2012 г.

четверг, 22 марта 2012 г.

Про техподдержку Google #4 (ФИНАЛ)

Урра! Техподдержка Google Play помогла! Спасибо, ребята! В выходные опубликую первые игры! 

среда, 21 марта 2012 г.

Про техподдержку Google #3


М-да. Блог постепенно превращается в историю общения со службой техподдержки Google. Написал уже два приложения, готовлю третье. А с публикацией проблемы. И ответа от техподдержки все нет и нет.

вторник, 20 марта 2012 г.

Про техподдержку Google #2

Пока жду тех поддержки от Гугл, родился текст интерпретатора для языка программирования BrainFuck Вроде тестировал - держит все команды - все 6!!! )))

package em;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class AlgBf {
  public static int rezVyv=1;
  private static String strInt="";
  public static String zapAlg(char[] s){

String rez="";
int i=0;
int[] p=new int[30000];
int lvlin=0;

for(int k=0;k<p.length;k++){
p[k]=0;
}
int n=0;

while(i<s.length){
switch (s[i]){
 case '+': p[n]++; break;
 case '-': p[n]--; break;
 case '>': n++; break;
 case '<': n--; break;
 case '.':
 if (AlgBf.rezVyv==0){
    rez=rez+(p[n])+" ";
 }
 else {
rez=rez+((char)p[n]);
 }
 break;

 case ',':

 if (true){
   InputStreamReader is = new InputStreamReader(System.in);
   BufferedReader bis = new BufferedReader(is);
   try {
    strInt = bis.readLine();
   p[n]=Integer.parseInt(strInt,10);
   } catch (IOException e) {
e.printStackTrace();
    }
 }

 case '[':

 if (p[n]==0){
 lvlin=1;
 while(lvlin>=1){
i++;
if (s[i]=='[') {lvlin++;};
if (s[i]==']') {lvlin--;};
 }
 }
    break;
 
 case ']':
lvlin=1;
while(lvlin>=1){
   i--;
   if (s[i]==']') {lvlin++;};
if (s[i]=='[') {lvlin--;};
}
i--;
    break;
 
  default:
}
i++;
}
return rez;
  }
}

понедельник, 19 марта 2012 г.

Про техподдержку Google #1


Столкнулся с неожиданной проблемой - Google Play не принимает номер эккаунта AdSense.
Как выяснилось, проблема не только у меня. Написал в техподдержку. Жду.

четверг, 15 марта 2012 г.

Об умении завязывать галстук


Вот простое, но очень полезное и бесплатное  приложение:
"Как завязать галстук" (How to Tie a Tie) - есть на Android Market. Так как не люблю носить галстук, но иногда приходится, то все время забываю как его завязывать. Иметь с собой в телефоне инструкцию не помешает - я раньше распечатанную бумажку в кармане носил вместо этого ))). 

Начало пути


Всем привет! В этом блоге планирую выкладывать ссылки и обсуждать обучающие программы для мобильных телефонов. Именно ОБУЧАЮЩИЕ программы для платформы Android.
Когда сидишь в метро или автобусе, или в другом неинтересном месте, и нечего делать - мобильные обучающие приложения позволяют не тратить время зря. Однако покопавшись в приложениях понял, что их не так уж и много. По крайней на интересующие меня темы почти нет. Поэтому начинаю делать свои. Ну и конечно буду давать ссылки на чужие разработки, которые мне понравились!