powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Покритикуйте код. Заход 2
60 сообщений из 60, показаны все 3 страниц
Покритикуйте код. Заход 2
    #38525317
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Собственно ребята. Написал прогу для загрузки картинок в группу в vk.com. Это вторая написанная мной прога в процесе изучения java. Хотелось бы услышать критику от более опытных людей, если конечно вам не очень влом ковыряться в чужом коде.
Програмулину выложил на гитхаб https://github.com/GaraZ/VKLoader
еще есть архив если влом заливать

Заранее благодарен за участие )

ЗЫ: в предыдущей теме прогнал со ссылкой ((
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525423
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
App.
- Java logger никто не юзает. Даже тут видно что его не удобно конфигурировать.
- "Архитекура на Helper-ах" показывает несостоятельность в следовании Single Responsibility Principle. Если класс называется Helper, это значит что его создатель понятия не имеет для чего этот класс ему будет нужен. Так же и для читателя слово Helper никакой полезной информации не несёт. Просто мусор в коде.
- mainForm.setVisible(true) вызывается до инициализации. Это значит юзер увидит не валидную форму. Если в методе initSettings предполагается progress indicator, то я бы назвал его runInitialization. Если не предполагается, то инициализацию стоит выполнить до вывода на UI.

Common
- класс с говорящим именем. Сразу понятно о чем речь. Ещё и с volatile полями.
- забавно логгер конфигурируются через точку, а здесь текущая директория через System.getProperty("user.dir") (а это одно и то же). Причем очевидный copy paste. Стоило сделать parent/root dir отдельным полем.
Я бы не рекомендовал user.dir. Он может быть разным у одного и того же приложения. В зависимости от того как запущено приложение.
- Нет такого слова uncorrect. Возможно такое словообразование, но оно обозначало бы совсем другое.
- getIsArhContent - JavaBeans спецификация разрешает boolean getter-ы с префиксом is. isArhContent() - Нет такого слова Arh.
- getArhContentDir и getArhPagesDir бессмысленные методы. Созданые через copy paste. Если конфигурация не валидна, то приложение должно говорить об этом на этапе инициализации, а не на этапе использования настроек.
- Вместо mkdir() стоит использовать mkdirs(), чтобы обезопасить код от будущих изменений в настройках.
- для простого XML я бы использовал JAXB, а не DOM. Тем более что вам в обе стороны сериализовать нужно. DOM подходит хорошо для изменения данных в существующем XML.

Crypt
- getKey() - создаём массив значений, но зачем-то их все потом заменяем. Честно говоря не понял задумки. Имя метода плохое - не сообщает что именно делает метод. Так же в этом методе стоило написать коментарий. Мне сходу не понятно что там происходит.
- Все методы статические. Зачем?
- Нельзя так писать.
Код: java
1.
2.
if(source == null || source.trim().isEmpty()) 
return null;


Либо фигурные скобки. Либо в одну строку. Ну, и вообще, вернуть null при null аргументе это спорное решение. Только усложняет поиски источника null значения. Подумайте действительно ли вам нужны null значения. Или стоит просто запретить их на более верхнем уровне и не тыкать проверки где попало.

CustomList
- ещё одно имя не о чем. Можно было называть хотя бы XmlList. Правда не ясно почему обязательно эти методы к List привязывать, а не к любой сущности.
- Зачем там E extends Object тоже не ясно.

ExceptionLoggerForm
- Хорошая попытка дать внятное имя классу. Но тем неменее не удачная. Почему Exception, если туда можно всё логировать? Почему Form? Если оно не для ввода, а для вывода.

to be continued...
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525484
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

спасибо огромное за коментарии!

BlazkowiczApp.
- Java logger никто не юзает. Даже тут видно что его не удобно конфигурировать.

а что юзают? Log4J?

Blazkowicz"Архитекура на Helper-ах" показывает несостоятельность в следовании Single Responsibility Principle. Если класс называется Helper, это значит что его создатель понятия не имеет для чего этот класс ему будет нужен. Так же и для читателя слово Helper никакой полезной информации не несёт. Просто мусор в коде.

Вы правы. "Архитекура на Helper-ах" - я понятия не имею что это какая то специфическая архитектура. "Helper" назвал без какойто задней мысли

BlazkowiczmainForm.setVisible(true) вызывается до инициализации. Это значит юзер увидит не валидную форму. Если в методе initSettings предполагается progress indicator, то я бы назвал его runInitialization. Если не предполагается, то инициализацию стоит выполнить до вывода на UI.

Не доглядел. В принципе согласен.

BlazkowiczCommon
- класс с говорящим именем. Сразу понятно о чем речь. Ещё и с volatile полями

Ну да )) Название наверное не очень. Там хранятся общие настройки. а volatile потому что эти настройки могут дергать несколько потоков
Хотя да скорре всего volatile в данном случае бесмысленно.

BlazkowiczЯ бы не рекомендовал user.dir. Он может быть разным у одного и того же приложения. В зависимости от того как запущено приложение.

Можете этот момент разъяснить более подробно?

BlazkowiczНет такого слова uncorrect. Возможно такое словообразование, но оно обозначало бы совсем другое.

Там должно быть incorrect. Провтыкал


BlazkowiczgetArhContentDir и getArhPagesDir бессмысленные методы. Созданые через copy paste. Если конфигурация не валидна, то приложение должно говорить об этом на этапе инициализации, а не на этапе использования настроек.

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

BlazkowiczВместо mkdir() стоит использовать mkdirs(), чтобы обезопасить код от будущих изменений в настройках.

Да что то я этот метод провтыкал. Так конечно лучше.

Blazkowiczдля простого XML я бы использовал JAXB, а не DOM. Тем более что вам в обе стороны сериализовать нужно. DOM подходит хорошо для изменения данных в существующем XML.

Я про JAXB не слышал. Поковыряюсь что за зверь.

BlazkowiczgetKey() - создаём массив значений, но зачем-то их все потом заменяем. Честно говоря не понял задумки. Имя метода плохое - не сообщает что именно делает метод. Так же в этом методе стоило написать коментарий. Мне сходу не понятно что там происходит.


Ну задумка в том чтобы ключ зависел от мак адреса. Но поскольку длинна массива батов должна быть 16 байт, а длинна мак адреса меньше, то я заменяю только первые несколько байт в первоначальной последовательности
Ну здесь конечно есть недоработка если мак адресов несколько)
статические они потому что для каждой шифровки/дешифровки не вижу смысла создавать экземпляр класса.

Blazkowicz- Нельзя так писать.
if(source == null || source.trim().isEmpty())
return null;


Либо фигурные скобки. Либо в одну строку. Ну, и вообще, вернуть null при null аргументе это спорное решение. Только усложняет поиски источника null значения. Подумайте действительно ли вам нужны null значения. Или стоит просто запретить их на более верхнем уровне и не тыкать проверки где попало.


Насчет скобок согласен. Провтыкал просто. Ну а насчет нула - возможно вы правы. Подумаю.

BlazkowiczCustomList
- ещё одно имя не о чем. Можно было называть хотя бы XmlList. Правда не ясно почему обязательно эти методы к List привязывать, а не к любой сущности.
- Зачем там E extends Object тоже не ясно.

С фантазией что то туго было на тот момент. Ваше название получше. )) E extends Object не нужно действительно. Чесно говоря не помню о чем я тогда думал


BlazkowiczExceptionLoggerForm
- Хорошая попытка дать внятное имя классу. Но тем неменее не удачная. Почему Exception, если туда можно всё логировать? Почему Form? Если оно не для ввода, а для вывода.

Ну хоть гдето хорошая попытка )))

Blazkowiczto be continued...

Буду ждать )
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525553
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZВы правы. "Архитекура на Helper-ах" - я понятия не имею что это какая то специфическая архитектура.

Ну, это как паттерн "золотой молоток" и аналогичные. Стиль программирования "не знаю как надо, сделаю как-нибудь".

GaraZ"Helper" назвал без какойто задней мысли

Можно вместо слова Helper использовать Manager. :) Зоркому взгляду понятно, что про SRP автор не знает. Но зато хоть выглядит солиднее - FileManager, например, чем FileHelper.

GaraZBlazkowiczЯ бы не рекомендовал user.dir. Он может быть разным у одного и того же приложения. В зависимости от того как запущено приложение.

Можете этот момент разъяснить более подробно?

java -jar {полный путь к jar приложния} - эту команду можно запустить из любой директории системы. Из какой запустите, та и будет user.dir.
Есть ещё такая тема что в Windows приложения принято ставить в Program Files. А в корпоративном\государственном секторе админы могут запретить запись в Program Files. Если ваше приложение захочет там хранить файлы, то он не будет работать под пользовательским аккаунтом. Только под админом.

GaraZBlazkowiczgetArhContentDir и getArhPagesDir бессмысленные методы. Созданые через copy paste. Если конфигурация не валидна, то приложение должно говорить об этом на этапе инициализации, а не на этапе использования настроек.

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

Параметры нужно валидировать в момент установки. А не в момент чтения. В момент установки, падает валидация в stacktrace видно какая падла установила кривое значение. В момент чтения в stacktrace видно кто хочет получить валидное значение.
Но оно уже не валидное. И для того чтобы узнать кто его установил, надо дебагать. Что намного дольше, чем просмотр stacktrace.
А если это случится у клиента, то дебагать может быть и принципиально не возможно.


Смысл вообще держать объект в невалидном состоянии и всем кричать - "я не валидный, я не валидный"


GaraZНу задумка в том чтобы ключ зависел от мак адреса. Но поскольку длинна массива батов должна быть 16 байт, а длинна мак адреса меньше, то я заменяю только первые несколько байт в первоначальной последовательности
Ну здесь конечно есть недоработка если мак адресов несколько)
статические они потому что для каждой шифровки/дешифровки не вижу смысла создавать экземпляр класса.

Стоило либо метод назвать так чтобы было понятно, что ключ вычисляется из MAC каким-то известным способом. Либо описать это в коментарии.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525561
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZ, в сборке у тебя есть java_cup. А через какую dependency ты ее подключаешь?
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525610
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

перерыл весь код
где я его использую java_cup так и не нашел )
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525618
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

Blazkowiczjava -jar {полный путь к jar приложния} - эту команду можно запустить из любой директории системы. Из какой запустите, та и будет user.dir.
Есть ещё такая тема что в Windows приложения принято ставить в Program Files. А в корпоративном\государственном секторе админы могут запретить запись в Program Files. Если ваше приложение захочет там хранить файлы, то он не будет работать под пользовательским аккаунтом. Только под админом.

Именно изз того что доступ к папке может быть залочен я решил по умолчанию складывать все туда где запущено приложение
про то что приложение можна запустить с любого места я както не подумал
так какое наиболее приемлимое решение?
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525648
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZmayton,

перерыл весь код
где я его использую java_cup так и не нашел )
А ладно. Забудь. Я думаю это в зависимостях от gson или html cleaner или еще чего-то что должно парсить текст.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525649
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZBlazkowiczCustomList
- ещё одно имя не о чем. Можно было называть хотя бы XmlList. Правда не ясно почему обязательно эти методы к List привязывать, а не к любой сущности.
- Зачем там E extends Object тоже не ясно.

С фантазией что то туго было на тот момент. Ваше название получше. )) E extends Object не нужно действительно. Чесно говоря не помню о чем я тогда думал


Я вспомнил ))
без объявления
Код: java
1.
 E extends Object

в интерфейсе я не могу сделать
вот так в реализации
Код: java
1.
ProfilesArrayList <E extends ProfileObj>


а без этого я не могу сделать вот так
Код: java
1.
this.get(i).writeToXML(element);
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525656
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В конфигах мне кажется лучше прописывать пути к home-каталогу пользователя.
Код: xml
1.
    <ContentDir>%USER_HOME%\VKLoader\VKLoader\target\Cont</ContentDir>


Или через точку ".". Или через "user.home". Так надёжнее что будет доступ на запись всегда и приватнее.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525659
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ExceptionLoggerForm
- setLocationRelativeTo(null); - по центру экрана. Лучше ориентироваться по родителю.
- Родительское окно не указано для JDialog, это приводит к багам в Swing при пеперключении через Alt-TAB между окнами. Особенно на модальном может вылезти. Лучше указывать родительское окно всегда.
- Я вообще не понимаю, почему вы учитесь на Swing. Стоило взять JavaFX.
- В данном тривиальном примере, конечно, не критично. Но переменным всегда стоит давать внятные и красивые имена, даже UI контролам. А не те что предлагает IDE по-умолчанию.
textArea, mainPanel, scrollPane читаются и выглядят намного лучше чем jTextArea, jPanelMain и jScrollPane.
- Поле объявлено внизу класса. Это Coding Convention такой?

FileHelper
- MASKS_LIST - почему константа и вдруг Mutable список?
- if (MASKS_LIST.isEmpty()) return true; Зачем проверка что он пустой? Другие классы меняют состояние этого поля? Инкапсуляция ни к черту.
- Coding Convention обычно требует определенный порядок членов класса. А тут бац - в середине static метод.
- Это не одно ли и то же? Зачем так раздувать код? Для диплома?
Код: java
1.
2.
3.
4.
5.
new File(dir.getAbsolutePath()
                        .concat(File.separator)
                        .concat(string));
new File(dir, string);
 


Вам же уже писали что JavaDoc стоит читать, а не копипастить код отовсюду.
- getHarmonizeSelFiles - генерики куда-то просрались.
- if (fl == true) - Идия Style?
- fl это вообще что за переменная? Flag? Flag чего? Совпадения? Так и надо было назвать тогда equal, matches, etc.
- file.delete() - результат этого метода стоит обрабатывать. А так же изучть Java NIO2 API для работы с файлами. И использовать его.
- selFilesList = selectedFiles не сокращайте без надобности. Код должен быть как можно ближе к английскому языку.
- используйте Buffered UI Stream-ы. Это проще чем самому через byte[] гонять данные.
- GregorianCalendar calendar = new GregorianCalendar(); лучше Calendar calendar = Calendar.newInstance();
- FileHelper работает с файлами. А у вас какие-то images везде в именах проскакиваю. Хотя методам всё равно image там ли что-то другое.
- Локальный StringBuilder не нужен, если нет цикла, который в него добавляет строки. Лучше строить пути через File/Path API, а не через String.
- changeSelListPos - не хватает пробелов вокруг +,-,> - форматируйте свой код в IDE и настройте форматирование согласно выбраному соглашению о кодировании.
- строки вида if (arg == null) return false/null; лучше отделять от тела методов дополнительным переносом строки. Тогда видно, тут у нас валидация аргумента, а тут у нас реализация логики.


-
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525661
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonВ конфигах мне кажется лучше прописывать пути к home-каталогу пользователя.
Код: xml
1.
    <ContentDir>%USER_HOME%\VKLoader\VKLoader\target\Cont</ContentDir>


Или через точку ".". Или через "user.home". Так надёжнее что будет доступ на запись всегда и приватнее.
Точка это то же самое что user.dir.
user.home - правильное решение.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525692
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

а оно работает ? Использовать можно по назначению?
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525730
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JCanvas
- в drawImage вместо null стоило передать this. Это должно уберечь от частичной отрисовки изображения до его окончательной загрузки.

MainForm - реальная колбаса.
- Ох, как не хватает Dependency Injection:
Код: java
1.
2.
app = vkl;
settingsForm = new SettingsForm(MainForm.this);


если мне влом подключать Spring или другой IoC контейнер, я просто завожу отдельный класс, который у меня собирает всю структуру. Такие циклические зависимости как App создаёт MainForm, а MainForm использует App, только всё усложнают. Аналогично и с SettingsForm.

- FilesTreeCellRenderer вызывает showImage, который больше нигде не используется, но метод зачем-то во внешнем классе. Renderer, ведь, можно было спокойно отдельным классом оформить?
- Нарушения принципа "наименьшего удивления":
Код: java
1.
2.
3.
catch (IOException e) {
...
   initTreeFiles();


- Строки вида app.getSettingsHelper().getCommon().getIsArhPages() - это грубейшее нарушение инкапсуляции. А так же "угадай какой из методов верунул null" и привел к NPE.
- Вместо if (evt.getSource() == someControl), вместо KeyAdapter и т.п. лучше использовать Action. Его можно пере-использовать. Из них проще строить иерархию. Они не будут раздувать методы, когда у вас появиться десяток-другой пунктов в меню. Плюсов море.
- MigLayout рулит.
- getFocusDown() это для чего вообще? Есть устойчивое чуство что можно было проще.
- Никаким MVP, смотрю, не пахнет. Все удаления\добавления происходят сразу на дереве, а не на бизнес-модели.
- В целом, тот самый "золотой молоток", о котором я писал выше. И GUI показывает. И кучу бизнес-логики реализует.
- line.separator разве работает в JOptionPane? По-моему нужно JTextArea использовать вместо строки.

ProfileObj
- Object login; - как так?
- А вот это оригинально.
Код: java
1.
2.
3.
4.
public boolean equals(Object obj) {
  ...
  return this.hashCode() == obj.hashCode();
}


Чем гарантируется уникльность hashCode?
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525752
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZЯ вспомнил ))
без объявления
Код: java
1.
 E extends Object

в интерфейсе я не могу сделать
вот так в реализации
Код: java
1.
ProfilesArrayList <E extends ProfileObj>


а без этого я не могу сделать вот так
Код: java
1.
this.get(i).writeToXML(element);


Просто где-то недоразобрались с генериками. В идеале типа Object в коде не должно быть вообще. Либо генерик тип, либо конкретный.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525754
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivBlazkowicz,

а оно работает ? Использовать можно по назначению?
Это к какому моему коментарию вопрос?
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525763
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ProfilesArrayList показывает нам основной косяк подхода Active Record в Java. Почему для загрузки нового экземпляра ProfilesArrayList требуется какой-то другой экземпляр, чтобы вызывать instance метод readFromXML? В каком отношении старый экземпляр состоит с новым?
JAXB позволит выкинуть вам кучу лишнего кода.

Наследование от ArrayList тоже спорное решение.
Обратите внимание сколько общего кода между SitesArrayList и ProfilesArrayList. Возникает резонный вопрос. Почему бы общий код не вынести в общий предок?
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525769
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SettingsForm - в рот мне ноги!

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
void initCommon() throws IOException {
        try {
            jTextFieldGroupId.setText(mainForm.getApp().getSettingsHelper().getCommon().getGroupId());
            jTextAreaComments.setText(mainForm.getApp().getSettingsHelper().getCommon().getComments());
            jTextFieldCont.setText(mainForm.getApp().getSettingsHelper().getCommon().getContentDir().getAbsolutePath());
            jTextFieldArhCont.setText(mainForm.getApp().getSettingsHelper().getCommon().getArhContentDir().getAbsolutePath());
            jTextFieldArhSite.setText(mainForm.getApp().getSettingsHelper().getCommon().getArhPagesDir().getAbsolutePath());
            jCheckBoxArhCont.setSelected(mainForm.getApp().getSettingsHelper().getCommon().getIsArhContent());
            jCheckBoxArhSite.setSelected(mainForm.getApp().getSettingsHelper().getCommon().getIsArhPages());
        } catch(IOException e) {
            jTextFieldCont.setText(mainForm.getApp().getSettingsHelper().getCommon().DEF_CONTENT_DIR.getAbsolutePath());
            jTextFieldArhCont.setText(mainForm.getApp().getSettingsHelper().getCommon().DEF_ARH_CONTENT_DIR.getAbsolutePath());
            jTextFieldArhSite.setText(mainForm.getApp().getSettingsHelper().getCommon().DEF_ARH_PAGES_DIR.getAbsolutePath());
            jCheckBoxArhCont.setSelected(false);
            jCheckBoxArhSite.setSelected(false);
            throw e;
        }
    }
    
    void saveCommon() {
        mainForm.getApp().getSettingsHelper().getCommon().setGroupId(jTextFieldGroupId.getText());
        mainForm.getApp().getSettingsHelper().getCommon().setComments(jTextAreaComments.getText());
        mainForm.getApp().getSettingsHelper().getCommon().setContentDir(jTextFieldCont.getText());
        mainForm.getApp().getSettingsHelper().getCommon().setArhContentDir(jTextFieldArhCont.getText());
        mainForm.getApp().getSettingsHelper().getCommon().setArhPagesDir(jTextFieldArhSite.getText());
        mainForm.getApp().getSettingsHelper().getCommon().setArhContent(jCheckBoxArhCont.isSelected());
        mainForm.getApp().getSettingsHelper().getCommon().setArhPages(jCheckBoxArhSite.isSelected());
    }
    
    void initTimer() throws IOException {
        try {
            jSliderPeriod.setValue(mainForm.getApp().getSettingsHelper().getTimer().getPeriod()/60);
            jSliderTimeError.setValue(mainForm.getApp().getSettingsHelper().getTimer().getTimeError()/60);
        } catch(NumberFormatException e) {
            jSliderPeriod.setValue(mainForm.getApp().getSettingsHelper().getTimer().DEF_PERIOD_SECONDS);
            jSliderTimeError.setValue(mainForm.getApp().getSettingsHelper().getTimer().DEF_TIME_ERROR_SECONDS);
            throw new IOException("Timer is uncorrect.");
        }
    }
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525802
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

Blazkowicz- Родительское окно не указано для JDialog, это приводит к багам в Swing при пеперключении через Alt-TAB между окнами. Особенно на модальном может вылезти. Лучше указывать родительское окно всегда.
- Я вообще не понимаю, почему вы учитесь на Swing. Стоило взять JavaFX.

Багов не замечал. Компоненты Swing описывались в тех учебниках которые я читал. Про JavaFX ничего не встречал, а специально не смотрел. Посмотрю по свободе что за зверь

Blazkowicz- В данном тривиальном примере, конечно, не критично. Но переменным всегда стоит давать внятные и красивые имена, даже UI контролам. А не те что предлагает IDE по-умолчанию.
textArea, mainPanel, scrollPane читаются и выглядят намного лучше чем jTextArea, jPanelMain и jScrollPane.

Интерфейсы я создавал вручную.Эти названия мне показались достаточно красивыми ))

Blazkowicz- MASKS_LIST - почему константа и вдруг Mutable список?
- if (MASKS_LIST.isEmpty()) return true; Зачем проверка что он пустой? Другие классы меняют состояние этого поля? Инкапсуляция ни к черту.

Да в данном варианте согласен - полная ерунда. Я собирался MASKS_LIST вынести в интерфейс, но потом чето передумал, а переписать забыл.
Гон конечно. Каюсь (

BlazkowiczВам же уже писали что JavaDoc стоит читать, а не копипастить код отовсюду.
- getHarmonizeSelFiles - генерики куда-то просрались.
- if (fl == true) - Идия Style?
- fl это вообще что за переменная? Flag? Flag чего? Совпадения? Так и надо было назвать тогда equal, matches, etc.

Доку читаю по необходимости, но копипастить проще )))
Про fl наверное следовало назвать более осмысленно, но функция маленькая в ней сложно запутаться

Blazkowiczfile.delete() - результат этого метода стоит обрабатывать. А так же изучть Java NIO2 API для работы с файлами. И использовать его.

Спасиб посмотрю.

Blazkowicz- используйте Buffered UI Stream-ы. Это проще чем самому через byte[] гонять данные.

Так проще или лучше?

BlazkowiczGregorianCalendar calendar = new GregorianCalendar(); лучше Calendar calendar = Calendar.newInstance();

Чем лучше?
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525812
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SettingsHelper
- сериализация может подтормаживать, если нет буферизации input\output stream. Будем надеятся что Dom4j сам обернет.
- в XML сериализуется, а интерфейс не реализует.
- readFile не закрывает стримы. Почему try-with-resource не используется?

SiteHelper
- длинный список аргументов я предпочитаю форматировать в столбик.
- GetThread - ни о чем. Что за поток? Чем занимается?
- GetThread - цикла в run не вижу. Зачем надо было наследоваться от Thread? Используйте Executors/SwingWorker.
- Есть потоки, но обращение к GUI не выполнено из EDT. Срочно читать статьи о потоках в Swing.
- parse методы - каша, вникать лень.

class Timer implements Runnable
Really? То есть java.util.Timer, javax.swing.Timer и ScheduledExecutorService на столько кривые, что пришлось написать свой?


TokenForm
- Hyperlink label стоило оформить отдельным классом-Swing-контролом.
- А что за мода на StringBuilder-ы пошла? У меня молодой коллега так же пишет где попало.

VkHelper
- много сомнительных констат. В целом, такое надо было на каком-то динамическом скриптовом языке писать, чтобы при изменении адресов и URL VK вдруг не потребовалось пересобирать проект, а можно было бы просто обновить скрипт.

В целом, очень сильно не хватает разбиения на абстрактные слои. Тонны бизнес-логики в GUI классах.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525815
Лагман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowiczмода на StringBuilder
это из-за того что копипастят из декомпилорованного кода.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525837
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZБагов не замечал.

Возможно это только в модальных.

GaraZКомпоненты Swing описывались в тех учебниках которые я читал.

Какого года учебники?

GaraZПро fl наверное следовало назвать более осмысленно, но функция маленькая в ней сложно запутаться

Если flag имеет значение, то его можно прочитать из названия. В противном случае нужно разбираться из кода, что же этот флаг обозначает. А функции имеют свойство расти во временем.

GaraZBlazkowicz- используйте Buffered UI Stream-ы. Это проще чем самому через byte[] гонять данные.

Так проще или лучше?

Если потоки не буферизировать вообще, будет поддтормаживать. Потоки чтения\записи лучше буферизировать.
Buffered Reader-ы и Stream-ы проще использовать, чем самому создавать массив и цикл копирования через него.

GaraZBlazkowiczGregorianCalendar calendar = new GregorianCalendar(); лучше Calendar calendar = Calendar.newInstance();

Чем лучше?
Не знаю. Как-то привычнее и вопросов не вызывает. Почему именно GregorianCalendar... Абстракцию, ведь, для чего-то создали.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525839
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЛагманBlazkowiczмода на StringBuilder
это из-за того что копипастят из декомпилорованного кода.
Не думаю. Просто прочитали что конкатенация тормозит, но не разобрались где и почему.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525846
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczЛагманпропущено...

это из-за того что копипастят из декомпилорованного кода.
Не думаю. Просто прочитали что конкатенация тормозит, но не разобрались где и почему.

именно ))
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525858
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

BlazkowiczJCanvas
- в drawImage вместо null стоило передать this. Это должно уберечь от частичной отрисовки изображения до его окончательной загрузки.

Спасибо не знал

Blazkowiczесли мне влом подключать Spring или другой IoC контейнер, я просто завожу отдельный класс, который у меня собирает всю структуру. Такие циклические зависимости как App создаёт MainForm, а MainForm использует App, только всё усложнают. Аналогично и с SettingsForm.

Да согласен что както запутано. Но как будет лучше я както смутно представляю

BlazkowiczFilesTreeCellRenderer вызывает showImage, который больше нигде не используется, но метод зачем-то во внешнем классе. Renderer, ведь, можно было спокойно отдельным классом оформить?

Можно было конечно

BlazkowiczСтроки вида app.getSettingsHelper().getCommon().getIsArhPages() - это грубейшее нарушение инкапсуляции. А так же "угадай какой из методов верунул null" и привел к NPE.

а как лучше сделать? не испотльзовать один класс дя доступа к другим а передавать их все в конструктор (Допустим MainForm)

BlazkowiczВместо if (evt.getSource() == someControl), вместо KeyAdapter и т.п. лучше использовать Action. Его можно пере-использовать. Из них проще строить иерархию. Они не будут раздувать методы, когда у вас появиться десяток-другой пунктов в меню. Плюсов море.
MigLayout рулит.

Погляжу. Пока я не в теме

BlazkowiczgetFocusDown() это для чего вообще? Есть устойчивое чуство что можно было проще.

Когда из Дерева удаляем ноду - фокус должен переместится на следущую или на первую - если удаленная нода последняя

Blazkowiczline.separator разве работает в JOptionPane? По-моему нужно JTextArea использовать вместо строки

а почему нет


BlazkowiczProfileObj
- Object login; - как так?
- А вот это оригинально.
public boolean equals(Object obj) {
...
return this.hashCode() == obj.hashCode();
}

В общем в текущей реализации переопределять equals вообще нет никакого смыла. Это осталось от более ранней версии но я и сам понял что херня какаято
вообще забыл что что-то там переопределял ((
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525872
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZа как лучше сделать? не испотльзовать один класс дя доступа к другим а передавать их все в конструктор (Допустим MainForm)

Inversion of Control -> Dependency Injection


GaraZКогда из Дерева удаляем ноду - фокус должен переместится на следущую или на первую - если удаленная нода последняя

В JTree есть методы работы со строками (rows). Реально какой-то сложный метод, который, ИМХО, можно было бы заменить методами из JTree.

GaraZBlazkowiczline.separator разве работает в JOptionPane? По-моему нужно JTextArea использовать вместо строки

а почему нет

По-тому что jlabel не умеет показывать многострочный текст, без <html>.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525891
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

BlazkowiczreadFile не закрывает стримы. Почему try-with-resource не используется?

провтыкал (

BlazkowiczSiteHelper
- длинный список аргументов я предпочитаю форматировать в столбик.
- GetThread - ни о чем. Что за поток? Чем занимается?
- GetThread - цикла в run не вижу. Зачем надо было наследоваться от Thread? Используйте Executors/SwingWorker.
- Есть потоки, но обращение к GUI не выполнено из EDT. Срочно читать статьи о потоках в Swing.
- parse методы - каша, вникать лень.

Поток парсит страницу выдирая с нее картинки
Для каждой страницы в runSitesDownload(CustomList<SiteObj> sitesList)
создается свой поток GetThread
Цикл в run и не нужен


Blazkowiczclass Timer implements Runnable
Really? То есть java.util.Timer, javax.swing.Timer и ScheduledExecutorService на столько кривые, что пришлось написать свой?

Ничем мой класс не лучше. Просто мне нужно было и jLabelTime (Циферблат) менять каждую секунду и еще и задание выполнить через n секунд
После беглого просмотра по существующим классам понял что для этого придется применить два таймера
Ну может это и не так. Чесно говоря сильно не вникал.

BlazkowiczПо-тому что jlabel не умеет показывать многострочный текст, без <html>.

Ну незнаю )0 у меня все переносит
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525892
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivBlazkowicz,

а оно работает ? Использовать можно по назначению?

Если вас интересует работает ли приложение - то да вполне
я каждый день его юзаю для своей группы
Мне интересно было бы если бы ктото еще попытался его заюзать )))
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525895
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZПоток парсит страницу выдирая с нее картинки
Для каждой страницы в runSitesDownload(CustomList<SiteObj> sitesList)
создается свой поток GetThread
Цикл в run и не нужен

Если не нужен цикл в run, то и Thread не нужен.
Нужны Executors и Callable/Runnable.
Если нужна интеграция с UI, то SwingWorker.
Зачем тут Thread не понятно.

GaraZНу незнаю )0 у меня все переносит
Значит я гоню. Переносы работают. Это word wrap не работает.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525980
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczMasterZivBlazkowicz,

а оно работает ? Использовать можно по назначению?
Это к какому моему коментарию вопрос?
Не спорьте по пустякам. Это я опечатался. Задачу получения HOME каталога можно решать
на разных уровнях. Можно проверить версию ОС и использовать тильду или %USER_PROFILE%
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525984
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonBlazkowiczMasterZivBlazkowicz,
а оно работает ? Использовать можно по назначению?
Это к какому моему коментарию вопрос?
Не спорьте по пустякам. Это я опечатался.
Кто здесь?
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525993
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonМожно проверить версию ОС и использовать тильду или %USER_PROFILE%Зачем, если есть стандартное свойство?
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38525997
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovmaytonМожно проверить версию ОС и использовать тильду или %USER_PROFILE%Зачем, если есть стандартное свойство?
какое стандартное средство?
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38526000
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZBasil A. Sidorovпропущено...
Зачем, если есть стандартное свойство?
какое стандартное средство?
свойство тоесть
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38526005
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczGregorianCalendar calendar = new GregorianCalendar(); лучше Calendar calendar = Calendar.newInstance();
Не знаю. Как-то привычнее и вопросов не вызывает. Почему именно GregorianCalendar... Абстракцию, ведь, для чего-то создали.
Можно поспорить насчет полезности данного совета (например, по одному из календарей сегодня новый год!!!)
на самом деле он там вообще не нужен, так как используется не по назначению (для получения текущего времени):
Код: java
1.
String dirNow = df.format(calendar.getInstance().getTime());
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38526013
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZGaraZкакое стандартное средство?свойство тоестьСмотрите вывод:
Код: sql
1.
jinfo PID|find "user"|more

если уж из топика непонятно.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38526023
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovGaraZпропущено...
свойство тоестьСмотрите вывод:
Код: sql
1.
jinfo PID|find "user"|more

если уж из топика непонятно.
ааа
я подумал еще чето есть )
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38526028
0FD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZ,

SiteHelper :
private static Map<URI, byte[]> pageMap;
private static Map<URI, byte[]> imgMap;
private static List<Exception> exList;

Используются несколькими потоками GetThread
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38526041
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
0FDGaraZ,

SiteHelper :
private static Map<URI, byte[]> pageMap;
private static Map<URI, byte[]> imgMap;
private static List<Exception> exList;

Используются несколькими потоками GetThread
ну да
что не так?
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38526047
Лагман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZ,

не являются thread safe
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38526065
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
0FD, Лагман,
нежданчик
я даже и не подумал посмотреть являются ли они потоко-безопасными
явный прогон с моей стороны
спасибо )
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38526129
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZBasil A. Sidorovпропущено...
Зачем, если есть стандартное свойство?
какое стандартное средство?
Я не возражаю. Но ему это стандартное свойство надо описать в терминах конфигурационного
файла. Предложите вариант как в строку вставить ссылку на USER_HOME
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38526169
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonПредложите вариант как в строку вставить ссылку на USER_HOMEНичего не понял, честно говоря.
Общепринятая практика использует ${user.home}, а так же любое другое свойство установленное "самим запускатором" или заданное в его командной строке.
Код, который разбирает такие вставки, конечно, должен быть написан, но тот же log4j умеет это из коробки.
Можно, например, написать "обобщённый" server.xml и запускать какой-нибудь tomcat как:
Код: sql
1.
java -Dsite.port=XXXX -site.jvm=YYY -Dcatalina.base=ZZZ -jar bin/bootstrap.jar

Работает как из пушки.

P.S. Хотите извратиться - можно использовать "обрамление процентами", как в виндовом шелле или REXX-овый вариант - имена вне кавычек рассматриваются как переменная, а при наличии "правильно прижатых скобок" - как вызов функции.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38526171
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov
Код: sql
1.
java -Dsite.port=XXXX -Dsite.jvm=YYY -Dcatalina.base=ZZZ -jar bin/bootstrap.jar
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38526187
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет. Нет. У чела есть конфиг. В нём прописано.

Код: xml
1.
2.
3.
4.
5.
6.
7.
<?xml version="1.0" encoding="UTF-8"?>

<Root>
  <Common>
    <GroupId></GroupId>
    <Comments></Comments>
    <ContentDir>/home/GaraZ/VKLoader/target/Cont</ContentDir>



Или

Код: xml
1.
  <ContentDir>c:\Documents And Settings\GaraZ\VKLoader\target\Cont</ContentDir>



Но суть - та-же самая. Каталог пользователя и локальный путь GaraZ\VKLoader\target\Cont
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38526199
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonНет. Нет. У чела есть конфиг. В нём прописаноПоскипано.
Должно быть:
Код: xml
1.
<ContentDir>${user.home}/VKLoader/target/Cont</ContentDir>

Код разбора или берётся готовый или пишется самостоятельно.

P.S. Для винды разворот слешей - вопрос личных предпочтений (файловому API - до лампочки).
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38539370
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Постарался учесть изложенные выше замечания
Обновил репозиторий :)
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38539486
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZПостарался учесть изложенные выше замечания
Обновил репозиторий :)
App
http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
initDependence() - почему не initDependencies(), почему не просто init()???
initialization это обычно этам подготовки к чему-то.
А здесь не только подготовка, но и сам запуск.
Ну, это такое...

ExceptionLoggerForm
Уже писал выше. Очень рекомендую всегда указывать родительский контейнер для JDialog и JFrame.

FileManager
initContent() - явно собирает какой-то список файлов по маске. Ну, почему было не дать методу внятное и понятное имя.
Иначе в таком стиле можно весь код написать
Код: java
1.
2.
3.
4.
public class GenericPurposeClass{
  private void init();
  private Result doThePurpose();
}


for (int i = 0; i < length; i++) - заменяется на for each.

Грубая ошибка:
Код: java
1.
2.
3.
4.
catch(NoSuchFileException e) {
            filesList.remove(file);
            throw new NoSuchFileException(file.getName().concat(" not found. "));
}


Вы теряете оригинальный stacktrace. Почему не просто throw e?
filesList.remove(file); копипастом вставлен в два места. Почему было не использовать try...finally без catch вообще?

synchronized стоит на методе класса FileManager, хотя по логике он относится к File.

saveImages/savePages - очень сильно смущает фривольное обращение с URI, который, вероятно, должен быть всегда валидным для этой задачи.


MainForm
Почему было import-ы не свернуть через * ?
getTreeCellRendererComponent - должен очень быстро по состоянию модели создать отображение. А тут запускается какая-то сложная логика с IO, ловятся исключения. А потом пишут мол Swing тормозной.

Download implements Runnable - запускается в фоновом потоке и из него обновляет GUI. Это приведёт к рандоммным исключениям с UI уровня Swing. Используйте SwingWorker или SecondaryLoop.

А это что за финт ушами?
Код: java
1.
2.
class Download implements Runnable {
        private Runnable runnable;



Как уже писал выше.
Лесенка if (evt.getSource() == jButtonFileDel) и смешивание UI с бизнес-логики в одном классе.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38539505
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: java
1.
2.
3.
4.
 @Override
    public String toString() {
        return login.trim();
    }


Лучше полностью выводить состояние объекта. Удобно для отладки. Не используйте toString() для логики.

SettingsForm модальный и не имеет родительского окна. Модальность сломана.
this перед полями не везде пишется. Github не достаточно умный, чтобы находить поля и подсвечивать.

Всё что касается сложной логики
SiteManager.parse() и методы VkManager - реальная каша. Читать трудно.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38539515
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZ,

Вам нужно научиться отделять модель от представления. Весь ваш код должен уметь работать без UI вообще.
UI нужен лишь для того чтобы отображать состояние вашей модели.
Хорошим упражнением может быть создание альтернативного UI для вашей логики. Например web или JavaFX.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38539588
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

BlazkowiczГрубая ошибка:
Код: java
1.
2.
3.
4.
catch(NoSuchFileException e) {
            filesList.remove(file);
            throw new NoSuchFileException(file.getName().concat(" not found. "));
}




исправил

Blazkowicz saveImages/savePages - очень сильно смущает фривольное обращение с URI, который, вероятно, должен быть всегда валидным для этой задачи.

это ссылки на картинки, страницы которые я выкачал. на этом этапе они всегда валидные

BlazkowiczgetTreeCellRendererComponent - должен очень быстро по состоянию модели создать отображение. А тут запускается какая-то сложная логика с IO, ловятся исключения. А потом пишут мол Swing тормозной.

я понимаю что та должно быть как можно меньше проверок. Но убрать я их не могу. Если при отображении файла возникла ошибка нужно перепроверить список файлов в директории
BlazkowiczDownload implements Runnable - запускается в фоновом потоке и из него обновляет GUI. Это приведёт к рандоммным исключениям с UI уровня Swing. Используйте SwingWorker или SecondaryLoop.

я думал SwingUtilities.invokeLater решит эту проблему

BlazkowiczА это что за финт ушами?
Код: java
1.
2.
class Download implements Runnable {
        private Runnable runnable;



))))))
да я согласен шняга )) сча придумаю чето другое

Blazkowicz @Override
public String toString() {
return login.trim();
}


Лучше полностью выводить состояние объекта. Удобно для отладки. Не используйте toString() для логики.

Эту штуку я переопределил что бы JComboBox jComboBoxLogin отображался только логин. а не весь объект

BlazkowiczВам нужно научиться отделять модель от представления. Весь ваш код должен уметь работать без UI вообще.
UI нужен лишь для того чтобы отображать состояние вашей модели.
Хорошим упражнением может быть создание альтернативного UI для вашей логики. Например web или JavaFX.


та это я и сам понимаю. Теоретически, а вот когда пишешь то чето так не получается. Как это сделать реально я сейчас не сосем понимаю
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38539594
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZBlazkowiczГрубая ошибка:

исправил

Оно не в одном месте, если что.

GaraZэто ссылки на картинки, страницы которые я выкачал. на этом этапе они всегда валидные

Ссылки без "расширений" в имени файлов тоже работают?

GaraZя понимаю что та должно быть как можно меньше проверок. Но убрать я их не могу. Если при отображении файла возникла ошибка нужно перепроверить список файлов в директории
Поэтому должна быть заведомо валиднай модель, которая всегда отображается. "Перепроверки" должны быть на этапе изменения модели.

GaraZя думал SwingUtilities.invokeLater решит эту проблему

Решит. Но там куча мест где он не используется. JOptionPane, .setText() и пр. Если каждый отдельно оборачивать в invokeLater, то код станет достаточно уродливым. SwingWorker отчасти решает эту проблему. Тут код выполняющийся в фоне, тут обрабатываем результат, а тут ошибки.


Лучше полностью выводить состояние объекта. Удобно для отладки. Не используйте toString() для логики.
[/quot]
Эту штуку я переопределил что бы JComboBox jComboBoxLogin отображался только логин. а не весь объект

BlazkowiczВам нужно научиться отделять модель от представления. Весь ваш код должен уметь работать без UI вообще.
UI нужен лишь для того чтобы отображать состояние вашей модели.
Хорошим упражнением может быть создание альтернативного UI для вашей логики. Например web или JavaFX.


GaraZта это я и сам понимаю. Теоретически, а вот когда пишешь то чето так не получается. Как это сделать реально я сейчас не сосем понимаю
Выходит что класс, которы отвечает за работу с XML, теперь зависит от того как устроен UI. Связь не явная. Ломается очень легко, в случае каких рефакторингов.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38540679
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczGaraZпропущено...

исправил

Оно не в одном месте, если что.

GaraZэто ссылки на картинки, страницы которые я выкачал. на этом этапе они всегда валидные

Ссылки без "расширений" в имени файлов тоже работают?

Ссылки без расширений не выкачиваются

BlazkowiczGaraZя понимаю что та должно быть как можно меньше проверок. Но убрать я их не могу. Если при отображении файла возникла ошибка нужно перепроверить список файлов в директории
Поэтому должна быть заведомо валиднай модель, которая всегда отображается. "Перепроверки" должны быть на этапе изменения модели.

Я не очень понимаю как здесь обеспечить заведомо валидную модель. Загружать все файлы в память или блокировать все файлы в папке?
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38540696
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZСсылки без расширений не выкачиваются

Да. Но выходит что один класс, предполагает что другой класс предоставит ему всегда валидную информацию. Если вы вдруг захотите эту логику поменять. Ни HTTP, ни даже файловая система не запрещает картинки без расширений, то сделав изменение в одном месте, вы можете упустить надобность изменения в другом. То есть между кодом одного класса и кодом другого класса существует неявная зависимость. О которой надо знать.

BlazkowiczЯ не очень понимаю как здесь обеспечить заведомо валидную модель. Загружать все файлы в память или блокировать все файлы в папке?
Я не разбирался что эта хрень делает. Поэтому не вникал особо. Я просто говорю о недостатках в коде. Отображение не должно быть на столько сложным чтобы выкидывать исключение.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38540712
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZЯ не очень понимаю как здесь обеспечить заведомо валидную модель. Загружать все файлы в память или блокировать все файлы в папке?
Скорее всего именно стоит загружать в память. Но тут много тонких моментов связаных с количеством этих файлов, с их размером и т.п. Но реально, cellRenderer будет вызываться на каждый пук. При этом картинка снова и снова будет загружаться из файловой системы и декодироваться. Откройте десяток-другой нод с разными файлами и сделайте resize окна и дерева.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38540718
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczСкорее всего именно стоит загружать в память. Но тут много тонких моментов связаных с количеством этих файлов, с их размером и т.п. Но реально, cellRenderer будет вызываться на каждый пук. При этом картинка снова и снова будет загружаться из файловой системы и декодироваться. Откройте десяток-другой нод с разными файлами и сделайте resize окна и дерева.
А ещё, картинки ведь ресайзятся под размер ячейки каждый раз. Это тоже отнимает дополнительные ресурсы.
С другой стороны держать в памяти все изображения, если они крупные, будет накладно по памяти. Поэтому имеет смысл добавить какой-то memory sensitive кэш, для того чтобы хранить в нем thumbnail нужного размера.
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38541252
Alex Kuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZBlazkowiczGregorianCalendar calendar = new GregorianCalendar(); лучше Calendar calendar = Calendar.newInstance();

Чем лучше?
Лучше тем, что Calendar.getInstance() вернёт нужный, правильно инициализированный объект календаря в зависимости от текущих региональных настроек...
Но вместе с тем никто не запрещает сделать и вот так Calendar calendar = GregorianCalendar.getInstance() или вот так GregorianCalendar calendar = GregorianCalendar.getInstance(), в случае если Вы не собираетесь локализовать приложение для работы в разных временнЫх исчислениях и будете работать только с григорианским календарём...
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38541493
Alex Kuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex Kuznetsovпропущено...
...или вот так GregorianCalendar calendar = GregorianCalendar.getInstance()...Сорри, здесь я налажевал, потому как если что то придётся делать явное приведение типа, т.е. GregorianCalendar calendar = (GregorianCalendar)GregorianCalendar.getInstance(); Что на самом деле странно, могли бы уж и переопределить возвращаемый результат...
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38541770
GaraZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex KuznetsovGaraZпропущено...

Чем лучше?
Лучше тем, что Calendar.getInstance() вернёт нужный, правильно инициализированный объект календаря в зависимости от текущих региональных настроек...
Но вместе с тем никто не запрещает сделать и вот так Calendar calendar = GregorianCalendar.getInstance() или вот так GregorianCalendar calendar = GregorianCalendar.getInstance(), в случае если Вы не собираетесь локализовать приложение для работы в разных временнЫх исчислениях и будете работать только с григорианским календарём...

уже отказался от данной реализации в пользу

Код: java
1.
2.
        DateFormat df = new SimpleDateFormat("yyyyMMdd");
        String dirNow = df.format(System.currentTimeMillis());
...
Рейтинг: 0 / 0
Покритикуйте код. Заход 2
    #38542121
Alex Kuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GaraZ,

Это в принципе правильно, но можно было бы и проще сделать с одним лишь String.format
...
Рейтинг: 0 / 0
60 сообщений из 60, показаны все 3 страниц
Форумы / Java [игнор отключен] [закрыт для гостей] / Покритикуйте код. Заход 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]