вторник, 11 декабря 2012 г.

Использование Look And Feel в приложениях на java

Поддержка Look And Feel - очень важная и достаточно необычная особенность языка программирования java. С использованием Look And Feel можно одной командой изменить стиль всех окон и диалогов в приложении. Существует около десятка стандартных Look And Feel встроенных в java, а помимо этого возможна установка сторонних Look And Feel и самостоятельное создание их. LookAndFeel крайне удобны тем, что с их помощью можно стандартизировать оформление всего приложения, и затем, при необходимости, легко изменять стили оформления одновременно для всех элементов приложения.

пятница, 14 сентября 2012 г.

Перенаправление сообщений со стандартного потока вывода system.out в логгер log4j на java

В коде своих приложений для логирования я везде стараюсь использовать библиотеку log4j, однако во многих сторонних библиотеках часто используются другие средства логирования, в частности стандартные потоки вывода System.out и System.err (методы System.out.println() и т.д.). При работе приложения такие сообщения и информация которую они несут, могут попросту потеряться, если их не перехватывать. Для перехвата таких сообщений и был написан класс, приведенный ниже.

пятница, 3 августа 2012 г.

Удобная генерация serialVersionUID в NetBeans

Очень важно, чтобы для классов, реализующих интерфейс Serializable был определен serialVersionUID, почему, можно прочитать здесь.
Как известно большинству разработчиков, работающих в NetBeans - по умолчанию в NetBeans отсутствует возможность сгенерировать щелчком мыши serialVersionUID для класса реализующего интерфейс Serializable. Поэтому чтобы избежать повторения uid-ов приходится либо каким-то образом запоминать создаваемые uid-ы, либо писать случайные цифры и надеяться на удачу. Можно конечно использовать утилиту serialver, однако это очень неудобно.

суббота, 30 июня 2012 г.

Работа с системном треем (system tray) на java

Для размещения иконки в трее можно воспользоваться стандартным классом java.awt.SystemTray, который стал доступен начиная с 6-й версии java. Данный класс воплощает собой системный трей среды в которой запущена виртуальная машина java. Перед началом работы с треем необходимо обязательно проверить его доступность с помощью метода SystemTray.isSupported(), далее следует получить текущий экземпляр SystemTray методом SystemTray.getSystemTray(). Вполне логично, что класс SystemTray является синглтоном, т.е. любое java приложение может иметь только один экземпляр SystemTray.
Системный трей может содержать некоторое количество иконок. Добавление иконок в системый трей производится с использованием команды add(java.awt.TrayIcon), а удаление командой remove(java.awt.TrayIcon).
Ниже привожу пример с официального сайта Oracle, в котором демонстрируется использование системного трея

final TrayIcon trayIcon;

if (SystemTray.isSupported()) {

    SystemTray tray = SystemTray.getSystemTray();
    Image image = Toolkit.getDefaultToolkit().getImage("tray.gif");

    MouseListener mouseListener = new MouseListener() {
                
        public void mouseClicked(MouseEvent e) {
            System.out.println("Tray Icon - Mouse clicked!");                 
        }

        public void mouseEntered(MouseEvent e) {
            System.out.println("Tray Icon - Mouse entered!");                 
        }

        public void mouseExited(MouseEvent e) {
            System.out.println("Tray Icon - Mouse exited!");                 
        }

        public void mousePressed(MouseEvent e) {
            System.out.println("Tray Icon - Mouse pressed!");                 
        }

        public void mouseReleased(MouseEvent e) {
            System.out.println("Tray Icon - Mouse released!");                 
        }
    };

    ActionListener exitListener = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            System.out.println("Exiting...");
            System.exit(0);
        }
    };
            
    PopupMenu popup = new PopupMenu();
    MenuItem defaultItem = new MenuItem("Exit");
    defaultItem.addActionListener(exitListener);
    popup.add(defaultItem);

    trayIcon = new TrayIcon(image, "Tray Demo", popup);

    ActionListener actionListener = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            trayIcon.displayMessage("Action Event", 
                "An Action Event Has Been Performed!",
                TrayIcon.MessageType.INFO);
        }
    };
            
    trayIcon.setImageAutoSize(true);
    trayIcon.addActionListener(actionListener);
    trayIcon.addMouseListener(mouseListener);

    try {
        tray.add(trayIcon);
    } catch (AWTException e) {
        System.err.println("TrayIcon could not be added.");
    }

} else {

    //  System Tray is not supported

}

В вышеприведенном примере есть один существенный недочет - для всплывающего меню там используется тяжеловесный устарелый компонент java.awt.PopupMenu, одним из недостатков которого является невозможность установки иконок для его MenuItem'ов. Несмотря на то, что TrayIcon по умолчанию принимает в своем конструкторе только java.awt.PopupMenu, возможность использовать более продвинутый javax.swing.JPopupMenu все же существует. Необходимо добавить к TrayIcon MouseListener, который будет создавать JPopupMenu при своем срабатывании. Ниже приведен пример такой реализации.

final TrayIcon trayIcon;

        if (SystemTray.isSupported()) {

            SystemTray tray = SystemTray.getSystemTray();
            Image image = Toolkit.getDefaultToolkit().getImage("tray.gif");



            ActionListener exitListener = new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    System.out.println("Exiting...");
                    System.exit(0);
                }
            };

            final JPopupMenu popup = new JPopupMenu();
            JMenuItem defaultItem = new JMenuItem("Exit");
            defaultItem.addActionListener(exitListener);
            popup.add(defaultItem);

            trayIcon = new TrayIcon(image, "Tray Demo");

            ActionListener actionListener = new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    trayIcon.displayMessage("Action Event",
                            "An Action Event Has Been Performed!",
                            TrayIcon.MessageType.INFO);
                }
            };

            trayIcon.setImageAutoSize(true);
            trayIcon.addActionListener(actionListener);
            trayIcon.addMouseListener(new MouseAdapter() {

                @Override
                public void mouseReleased(MouseEvent e) {
                    if (e.isPopupTrigger()) {
                        popup.setLocation(e.getX(), e.getY());
                        popup.setInvoker(popup);
                        popup.setVisible(true);
                    }
                }
            });

            try {
                tray.add(trayIcon);
            } catch (AWTException e) {
                System.err.println("TrayIcon could not be added.");
            }

        } else {
            //  System Tray is not supported
        }

среда, 30 мая 2012 г.

Как остановить веб приложение java на Apache Tomcat непосредственно из програмного кода

Остановку веб приложения java на Tomcat из программного кода можно выполнить путем посылки команды выключения на специальный порт, который может быть настроен в корневом элементе файла server.xml Томката.

Итак, алгоритм действий по шагам:

1. Добавить в корневой элемент файла CATALINA_HOME/conf/server.xml код, приведенный ниже:

<server port="8005" shutdown="myShutDownCommand">

Аттрибут port не обязателен. Если он пропущен - то будет использован порт по умолчанию - 8005. Значением аттрибута shutdown может быть все что угодно. Это значение не должно быть известно никому кроме вас.

Может возникнуть сложность в нахождении файла server.xml. Он может оказаться в различных местах. У меня при использовании Netbeans 7.1.2 он оказался в директории вида C:\Documents and Settings\<UserName>\.netbeans\7.1.2\apache-tomcat-7.0.22.0_base\conf. Файл server.xml есть также по пути вида C:\Program Files\Apache Software Foundation\Apache Tomcat 7.0.22\conf - путь к нужному файлу будет зависеть от того, с какими параметрами был запущен томкат.

2. Создать код в java программе, который будет посылать команду остановки используя java.net.Socket на порт остановки tomcat.

try { 
    Socket socket = new Socket("localhost", 8005); 
    if (socket.isConnected()) { 
        PrintWriter pw = new PrintWriter(socket.getOutputStream(), true); 
        pw.println("myShutDownCommand");//send shut down command 
        pw.close(); 
        socket.close(); 
    } 
} catch (Exception e) { 
    e.printStackTrace(); 
}

пятница, 18 мая 2012 г.

Как единоразово выполнить некоторый код в java при запуске web приложения на Apache Tomcat

Чтобы выполнить некоторый код единоразово при запуске веб приложения на Apache Tomcat (например создать иконку в трее и т.д.) следует сконфигурировать listener в файле web.xml

Итак, по шагам:

1. Добавляем в раздел <web-app> код листенера со ссылкой на наш класс.

<listener>
    <listener-class>mypackage.StartListener</listener-class>
</listener>


2. Создаем класс своего листенера наследуясь от javax.servlet.ServletContextListener.

package mypackage;

import javax.servlet.ServletContextEvent;

/**
 *
 * @author Cloud
 */
public class StartListener implements javax.servlet.ServletContextListener {

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
         // код выполняющийся при уничтожении контейнера
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        // код выполняющийся при инициализации контейнера
    }
}

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

Как в java определить свой внешний IP адрес

Программно определить внешний IP не так уж и просто как может показаться на первый взгляд. В java нет да и не может быть стандартной функции для получения IP адреса своего компьютера в интернете. При этом ip адрес компьютера в локальной сети получить достаточно просто, для этого можно воспользоваться классом InetAddress.
InetAddress addr = InetAddress.getLocalHost();         
String myLANIP = addr.getHostAddress();
Для получения внешнего IP необходимо подключиться к какому-нибудь серверу в интернете, который вернет IP под которым он видит данный компьютер. В общем случае необходимо подключится к серверу (сайту) предоставляющему услугу определения IP, получить ответ в виде html кода и выделить из этого кода IP адрес. Ниже приведен пример с использованием сервиса http://myip.by/ - он удобен тем, что возвращает минимум лишней информации.

private static String getCurrentIP() {
        String result = null;
        try {
            BufferedReader reader = null;
            try {
                URL url = new URL("http://myip.by/");
                InputStream inputStream = null;
                inputStream = url.openStream();
                reader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuilder allText = new StringBuilder();
                char[] buff = new char[1024];

                int count = 0;
                while ((count = reader.read(buff)) != -1) {
                    allText.append(buff, 0, count);
                }
// Строка содержащая IP имеет следующий вид 
// <a href="whois.php?127.0.0.1">whois 127.0.0.1</a> 
                Integer indStart = allText.indexOf("\">whois ");
                Integer indEnd = allText.indexOf("</a>", indStart);

                String ipAddress = new String(allText.substring(indStart + 8, indEnd));
                if (ipAddress.split("\\.").length == 4) { // минимальная (неполная) 
                //проверка что выбранный текст является ip адресом.
                    result = ipAddress;
                }
            } catch (MalformedURLException ex) {
                 ex.printStackTrace();
            } catch (IOException ex) {
                 ex.printStackTrace();
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
       
        return result;
    }

воскресенье, 13 мая 2012 г.

Как в java поместить фрейм (JFrame) в центре экрана

Основной сложностью при помещении фрейма в центр экрана является получение значения текущего разрешения экрана. Получить разрешение экрана в java можно используя класс java.awt.Toolkit вызвав метод java.awt.Toolkit.getDefaultToolkit().getScreenSize().
Он возвратит значение разрешения экрана в виде объекта класса Dimension.
Дальше необходимо просто вычислить координаты, куда следует поместить фрейм.
Пример:

    /**
    * Puts any Window or Frame to the centre of the screen.
    * 
    * @author Cloud
    */
    public static void centerFrame(Window frame) {
        Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        int x = (int) ((screenSize.getWidth() - frame.getWidth()) / 2);
        if (x < 0) {
            x = 0;
        }
        int y = (int) ((screenSize.getHeight() - frame.getHeight()) / 2);
        if (y < 0) {
            y = 0;
        }
        frame.setBounds(x, y, frame.getWidth(), frame.getHeight());
    }

UPD (из комментария Tom-Trix): Есть более простой способ помещения фрейма в центр экрана - использование метода frame.setLocationRelativeTo(null). Однако следует учитывать, что данный метод будет работать только при использовании java версии выше 1.4 (первый способ работает и на более ранних версиях java). Пример :
    /**
    * Puts any Window or Frame to the centre of the screen.
    * 
    */
    public static void centerFrame(Window frame) {
        frame.setLocationRelativeTo(null);
    }

Важно: вышеописанные методы следует вызывать после установки размера фрейма (вызова методов setSize(), setPrefferedSize() и т.д.), а также желательно после добавления всех необходимых компонентов на фрейм, иначе эти методы просто не сработают или сработают не так, как ожидалось. Также скорее всего они могут не совсем корректно работать для среды с несколькими мониторами (не проверял).

суббота, 12 мая 2012 г.

Часто используемые регулярные выражения в java

Регулярные выражения могут являться крайне удобным средством для решения самых различных задач. Обычно, главная сложность состоит в составлении выражения для конкретной задачи. В данной статье приведены примеры регулярных выражений в java для решения наиболее часто встречающихся случаев.

1. Выделение IP-адреса из произвольной строки.
Например, для строки "Ваш IP: 178.124.248.231" регулярное выражение имеет вид
Pattern ipPattern =
            Pattern.compile("Ваш IP: ([[\\d]+[\\.]+]+[\\d])[\\.]+", 
 Pattern.DOTALL | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); 

2. Выделение времени в минутах и секундах.
Для строки "Время : 02:00"
Pattern remainedTimePattern =
            Pattern.compile("Время : ([[\\d]+[:]]+[\\d])",
 Pattern.DOTALL | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);

3. Проверка строки времени в 12-ти часовом формате.

Pattern timeAMPMPattern =
            Pattern.compile("(1[012]|[1-9]):[0-5][0-9](\\s)?(?i)(am|pm)", 
Pattern.DOTALL | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);

4. Проверка строки времени в 24-x часовом формате.

Pattern time24Pattern =
            Pattern.compile("([01]?[0-9]|2[0-3]):[0-5][0-9]", 
Pattern.DOTALL | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);

5. Проверка даты в формате dd/mm/yyyy.

Pattern datePattern =
            Pattern.compile(
"(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\\d\\d)", 
Pattern.DOTALL | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);

6. Проверка правильности email адреса

Pattern emailPattern =
            Pattern.compile(
"^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$", 
Pattern.DOTALL | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);


7. Проверка IP

Pattern checkIPattern = Pattern.compile(
        "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
        "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
        "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
        "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");

8. Проверка имени пользователя

Pattern userNamePattern = Pattern.compile("^[a-z0-9_-]{3,15}$");

9. Паттерн HTML тэга

Pattern htmlTagPattern = Pattern.compile("<("[^"]*"|'[^']*'|[^'">])*>");

пятница, 30 марта 2012 г.

Что делать если не открывается сетевое окружение ни на одном из компьютеров рабочей группы сети?

Сегодня столкнулся со следующей проблемой - не открывалось сетевое окружение ни на одном из компьютеров рабочей группы. При этом сеть работала - то есть все компьютеры нормально пинговались, доступ к каждому компьютеру через ip тоже работал.
При выполнении команды net view из командной строки выдавало ошибку "Системная ошибка 6118. Недоступен список серверов для этой рабочей группы."

Для понимания почему такие ошибки иногда происходят необходимо понимать теорию работы общего сетевого доступа. Вкратце - для работы сетевого окружения необходимо наличие компьютера мастер-браузера (master browser). Этот компьютер назначается автоматически при включении компьютеров в сеть из имеющихся подключенных компьютеров путем выборов (elections). Правильная работа данного компьютера необходима для корректного разрешения имен в netbios-сети, т.е. такие ошибки обычно происходят именно из-за проблем в работе мастер-браузера.

Если сеть небольшая, из 3-5 компьютеров, то, наверное, наиболее простым решением будет просто выключить сразу все компьютеры, а потом их включить. Скорее всего автоматически будет назначен новый мастер браузер.

Для сети больших размеров для решения (и предотвращения появления в будущем) такой проблемы необходимо узнать имя текущего мастер браузера. Сделать это можно с помощью утилиты командной строки browstat.exe выполнив команду browstat sta. Зная имя компьютера идем (физически) к этому компьютеру. Если оказывается что компьютер просто завис - перезагружаем его. Если нет - проверяем чтобы службы обозpеватель компьютеров и сервер корректно работали. Далее в свойствах сетевого подключения смотрим чтобы компонент "клиент для сетей майкрософт" был включен.

Также проблема может возникнуть из-за того, что компьютер назначенный мастером имеет 2 сетевые карты. Для всех таких компьютеров - очень желательно запретить их использование в качестве мастер браузеров. Сделать это можно установив в реестре HKLM\System\CurrentControlSet\Services\Browser\Paramters ключ MaintainServerList в значение No.

После перезагрузки компьютера теоретически мастер браузер для сети должен переназначиться, но чтобы это произошло наверняка следует выполнить команду browstat elect - для запуска перевыборов мастер браузера.

В моем случае оказалось что компьютер назначенный мастер-браузером просто завис, после его перезагрузки сетевое окружение сразу стало нормально открываться.

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

Глюк в Netbeans 7.1

При обновлении netbeans до новой версии 7.1.1 при попытке скомпилировать один из старых проектов стало выдавать ошибку "copylibs doesn't support the "rebase" attribute when trying to perform an ant build of the project.". Об этой ошибке можно прочитать на официальном сайте netbeans перейдя по следующей ссылке. Для избавления от этой проблемы следует заменить файл lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar в папке проекта аналогичной библиотекой из любого созданного в netbeans 7.1.1 проекта (кому лень создавать пустой проект библиотеку можно скачать здесь).

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

Открытие в Windows файла или папки на java

Часто при проектировании приложений возникает необходимость просто открыть папку в проводнике или файл в связанном с расширением файла приложении, чтобы пользователь мог просмотреть его.
Решение этой задачи мной было найдено, однако оно является платформо-зависимым и точно подходит для систем ОС Windows версии ниже Windows XP (возможно и для других версий ОС Windows - не проверял, кто проверит, пожалуйста, отпишитесь). Платформо-независимого решения не нашел (кроме как анализировать версию ос и самому выбирать нужный способ запуска), если кто знает - поделитесь в комментариях.
Открытие файла происходит с помощью командной строки Windows, имя файла передается как параметр командной строки.
Открытие папки происходит с использованием проводника Windows explorer, имя папки передается как параметр запуска файла explorer.exe.

    /**
     * Opens Windows file in associated application
     * @param file File to open
     * @author Cloud
     */
    public static void openFile(File file) {
        try {
            String osName = System.getProperty("os.name");
            String[] cmd = new String[3];

            if (osName.equals("Windows 95")) {
                cmd[0] = "command.com";
            } else {
                cmd[0] = "cmd.exe";
            }
            cmd[1] = "/C";
            cmd[2] = file.getAbsolutePath();
            Runtime rt = Runtime.getRuntime();
            rt.exec(cmd);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Opens windows directory in explorer
     * @param dir Directory to open
     * @author Cloud
     */
    public static void openDir(File dir) {
        try {
            String[] cmd = new String[2];
            cmd[0] = "explorer.exe";
            cmd[1] = dir.getAbsolutePath();
            Runtime rt = Runtime.getRuntime();
            rt.exec(cmd);

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

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

Удаление элементов из списка List в цикле на Java

Как известно, в java в упрошенном цикле for для обхода списка (любого, наследуемого от List) удалять элементы нельзя, так как при этом могут возникать различные ошибки. Если же все таки необходимость удалить элементы из такого списка существует, то следует воспользоваться классом ListIterator для перебора элементов. Пример кода, использующего ListIterator, приведен ниже.

List< Integer> list = new ArrayList< Integer>();
for (ListIterator< Integer> i = list.listIterator(); i.hasNext(); ) {
   Integer el = i.next();
   if(el == 1) {
      i.remove();
   }
}   

пятница, 6 января 2012 г.

DropBox - программа для синхронизации файлов между компьютерами

В этой статье я хочу рассказать об одном замечательном сервисе - DropBox.com.

DropBox - сервис, позволяющий синхронизировать данные между компьютерами, просто путем копирования файлов в определенную папку. Сразу после попадания в эту папку файлы автоматически закачиваются на сервер, и затем уже с сервера - на синхронизированные ПК.
Даже если у вас один компьютер - вы можете использовать dropbox просто для автоматического создания резервных копий важной информации, фотографий, музыки.
С помощью dropbox можно легко делиться фотографиями с вашими друзьями и родственниками, простым копированием этих файлов в специальную папку. Для этого нужно лишь создать какую-нибудь подпапку в dropbox, напримен photos, открыть доступ к ней вашим друзьям и родственникам (в настройках), после чего она появится у них на компьютере.
Чтобы начать пользоваться сервисом - следует зарегистрироваться на сайте dropbox.com и скачать специальную программку, которая будет висеть в трее и синхронизировать файлы.
Для бесплатного аккаунта дается возможность хранить в dropbox до 2 Гб файлов. Лично мне, например, этого места хватает с лихвой.

Ярлыки

java (31) оптимизация (7) CPanel (5) svn (5) windows xp (5) ошибка (5) свой сервер (5) файлы и папки (5) gui (4) регулярные выражения (4) jacoco (3) redmine (3) windows (3) автоматизация (3) защита данных (3) резервное копирование (3) сервер (3) JavaScript (2) Oracle SQL (2) adsl модем (2) apache maven (2) apache tomcat (2) coverage (2) dropbox (2) excel (2) firewall (2) netbeans (2) office 2007 (2) samsung (2) system tray (системный трей) (2) xerox (2) вирусы (2) принтер (2) сериализация (2) удаленный рабочий стол (2) HTML (1) JFileChooser (1) MySQL (1) Nokia (1) Ovi (1) P660R-T1 (1) WakeOnLan (1) blogger.com (1) ctfmon.exe (1) email (1) flash память (1) ftp (1) integration testing (1) ip (1) jQuery (1) jvisualWm (1) log4j (1) look and feel (1) myBatis (1) php (1) serialVersionUID (1) skype (1) smtp (1) ssh (1) swing (1) torrents (1) unit-testing (1) unix (1) vpn (1) windows 7 (1) xStarter (1) zip (1) безопасность (1) вход в систему (1) дизайн (1) документация (1) заправка (1) интернет (1) логирование (1) мышь (1) патч (1) перенос (1) печать (1) плагины (1) почтовые сообщения (1) программирование (1) процессы (1) прошивка (1) сеть (1) сеть. ошибка (1) скрытые файлы (1) списки (1) фильтрация (1) фокус (1) часовые пояса (1) шифрование (1) экран (1)