Разработка системы учета рабочего времени сотрудника
Понятие и преимущества корпоративного тайм-менеджмента, его основные методики. Причины дефицита времени. TimeTracker как решение проблемы тайм-менеджмента. Разработка графического интерфейса приложения, его архитектура. Принципы тестирования программы.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 07.08.2018 |
Размер файла | 7,2 M |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
4.2 Тестирование графического интерфейса приложения
Как и любое программное обеспечение, TimeTrackerдолжен пройти фазу тестирования. В современном мире веб разработок создано огромное количество технологий, которые помогают в тестирование графического интерфейса. Одной из таких технологий является продукт Selenium, который имитирует нажатие кликов мыши по экрану в браузере. К сожалению Seleniumне подходит для тестирования приложений для Windows, по этому, тестирование будет проводиться путем нажатие кнопок вручную.В этом разделе представлены тесты графического интерфейса приложения на правильность реагирования, заявленного в техническом задании.Тестирование графического интерфейса производится путем нажатия кликом мыши по компонентам системы и проверки правильности реагирования системы на нажатие. Также тестирование проводится на проверку отсутствия ошибок при работе с графическим интерфейсом.
Тестирование создание задачи. В этом тесте проверяется, как будет реагировать программа на нажатие кнопки “Создать задачу” (рис. 4.1).
Входные данные: Перейти на экран “Tasks”, нажать на кнопку добавления задачи.
Ожидание: Переход на экран создания задачи.
Результат: Переход на экран создания задачи (рис. 4.2).
Рис. 4.1 - Тестирование создание задачи
Рис. 4.2 - Тестирование создание задачи
Тестирование сохранения задачи. Открыть редактирование задачи, изменить Tasktitleна 123, сохранить задачу, проверить правильность сохранения.
Входные данные: Нажать на кнопку SAVE (рис. 4.3).
Ожидание: Сохранение задачи без ошибок и добавление её в общий список.
Результат: Сохранение задачи без ошибоки добавление её в общий список (рис. 4.4).
Рис. 4.3 -Тестирование сохранения задачи
Рис. 4.4 -Результат тестированиясохранения задачи
Тестирование фильтрации. В этом тесте проверяется, как программа реагирует на изменение фильтрации списка задач.
Входные данные: В выпадающем списке фильтрации выбрать ASSIGNEDTOME(рис.4.5).
Ожидание: Список задач отобразит задачи, присвоенные текущему пользователю.
Результат: Список задач отобразит задачи, присвоенные текущему пользователю (рис.4.6).
Рис. 4.5 - Тестирование фильтрации списка задач
Рис. 4.6 -Результат тестирования фильтрации списка задач
Тестирование запуска таймера задачи. В этом тесте проверяется, как реагирует система на изменение статуса задачи.
Входные данные: Открыть задачу в статусе OPEN, нажать на кнопку STARTPROGRESS (рис.4.7).
Ожидание: Задача перейдет в статус INPROGRESS. Область TimeTrackingначнет учет активности пользователя. В области учета времени окно приложения выйдет на первую позицию.
Результат: Задача перейдет в статус INPROGRESS. Область TimeTrackingначнет учет активности пользователя. В области учета времени окно приложения выйдет на первую позицию (рис. 4.8).
Рис. 4.7 - Тестирование запуска таймера задачи
Рис. 4.8 -Результат тестирования запуска таймера задачи
Тестирование авторизации пользователя. В этом тесте проверяется, как реагирует система на авторизацию пользователя.
Входные данные: Запустить приложение, ввести в поле ввода имени пользователя UserNameи нажать кнопку Login (рис.4.9).
Ожидание: Приложение без ошибок загрузит экран Dashboard. Имя пользователя будет отображено в шапке приложения.
Результат: Приложение без ошибок загрузит экран Dashboard. Имя пользователя будет отображено в шапке приложения (рис.4.10).
Рис. 4.9 - Тестирование авторизации пользователя
Рис. 4.10 - Результат тестирования авторизации пользователя
Тестирование раскрытия и закрытия меню приложения. В этом тесте проверяется, как реагирует система на нажатие кнопки «Меню».
Входные данные: Запустить приложение, нажать на кнопку «Меню» в шапке приложения (рис. 4.11).
Ожидание: Приложение откроет меню в левой части экрана.
Результат: Приложение открыло меню в левой части экрана (рис. 4.12).
Рис. 4.11 - Тестирование кнопки «Меню» приложения
Рис. 4.12 - Результат тестирования кнопки «Меню» приложения
Тестирование множественного редактирования данных задачи.
Входные данные: Открыть экран редактирования задачи, изменить поле Tasktitle, Taskpriority, Taskstatus, Tasktype, сохранить задачу (рис.4.13).
Ожидание: Задача будет изменена без ошибок и это отразится на экране информации.
Результат: Задача изменена без ошибок, и измененные данные отображены на экране информации о задаче (рис.4.14).
Рис. 4.13 - Тестирование множественного редактирования
Тестирование смены экранов приложения. В этом тесте проверяется, как система реагирует на переходы через кнопку меню приложения.
Рис. 4.14 - Результат тестирования множественного редактирования
Входные данные: Перейти на экран Dashboard, открыть меню, нажать на кнопку Tasks (рис. 4.15).
Ожидание: Содержимое приложения изменится на экран списка задач.
Результат: Приложение открыло список задач (рис.4.16).
Рис. 4.15 - Тестирование смены экранов приложения
Рис. 4.16 - Результат тестирования смены экранов приложения
Заключение
На данный момент профессия разработчика высоко ценится на рынке и количество вакансий намного больше, чем специалистов подходящих под них.
Каждый день появляются новые технологии, требующие особых навыков специалиста этой отрасли. С каждым годом растет сложность разработки программного обеспечения требуя от специалиста огромного терпения, желания и что самое главное времени. Зачастую многие разработчики брезгуют своим рабочим временем нарушая свою дисциплину и неся убытки компаниям.
В ходе выполнения бакалаврской работы, на тему «Разработка приложения учета рабочего времени сотрудника», было проделано следующее:
Продумана архитектура приложения и подобраны технологии, которые помогут в решении поставленной задачи.
Основной платформой для разработки системы была выбрана Java.
Разработан примерный шаблон графического интерфейса приложения в современном стиле с использованием навыков UX.
Разработан основной функционал приложения.
Описаны основные возможности приложения.
Приложение было протестировано на отказоустойчивость и на наличие функционала указанного в техническом задании.
Список использованных источников
1. StackOverFlow [Электронный ресурс] / 2017. - Режим доступа: https://stackoverflow.com/, свободный. - Загл. с экрана.
2. Тейлор, Ф.У. Принципы научного менеджмента [Текст]/В.А.Бесекерский,Е.П.Попов.-4-еизд.,перераб.идоп.-СПб.:Профессия,2017.-747с.
3. Java 8 Reference Guide [Электронный ресурс] / 2017. - Режим доступа: https://docs.oracle.com/javase/8/docs/api/java/lang/ref/Reference.html, свободный. - Загл. с экрана.
4. Maven referenece [Электронный ресурс] / 2017. - Режим доступа: https://maven.apache.org/, свободный. - Загл. с экрана.
5. RxJava Tutorials [Электронный ресурс] / 2017. - Режим доступа: https://github.com/ReactiveX/RxJava, свободный. - Загл. с экрана.
6. Project Lombok [Электронный ресурс] / 2017. - Режим доступа: https://projectlombok.org/. - Загл. с экрана.
7. Junit 4 Guide [Электронный ресурс] / 2017. - Режим доступа: http://junit.org/junit4/. - Загл. с экрана.
8. IntelliJIDEAKotlinGuide [Электронныйресурс] / 2017. -Режим доступа: https://kotlinlang.org/. - Загл. с экрана.
9. JavaNativeAccess [Электронныйресурс] / 2017. -Режим доступа:https://github.com/java-native-access/jna/. - Загл. с экрана.
Приложение
Исходный код приложения
package com.home.timetracker.core.entity.task;
public enum TaskPriority {
LOW, NORMAL, HIGH, CRITICAL
}
package com.home.timetracker.core.entity.task;
public enum TaskStatus {
OPEN, IN_PROGRESS, ON_HOLD,CLOSED
}
package com.home.timetracker.core.entity.task;
public enum TaskType {
BUG, FEATURE
}
package com.home.timetracker.core.entity.task;
import com.home.timetracker.core.entity.PlotData;
import com.home.timetracker.core.entity.User;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TrackerTask {
private String taskTitle;
private String description;
private TaskPriority priority = TaskPriority.NORMAL;
private TaskType type = TaskType.BUG;
private TaskStatus status = TaskStatus.OPEN;
private User reporter;
private User assignee;
private LocalDate created = LocalDate.now();
private LocalDate due = LocalDate.now();
private int estimatedTime;
private int dueTime;
private List<PlotData> plotData = new ArrayList<>();
}
package com.home.timetracker.core.entity;
import com.home.timetracker.core.MenuAction;
import lombok.AllArgsConstructor;
import lombok.Data;
import javax.swing.*;
@Data
@AllArgsConstructor
public class MenuEntry {
private String text;
private MenuAction action;
private ImageIcon imageIcon;
}
package com.home.timetracker.core.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Data
@EqualsAndHashCode
@ToString
@AllArgsConstructor
public class PlotData implements Comparable<PlotData>{
private String title;
private int value;
public void increment(){
this.value++;
}
@Override
public int compareTo(PlotData o) {
if(value > o.value){
return -1;
}else if(value < o.value){
return 1;
}
return 0;
}
}
package com.home.timetracker.core.entity;
import com.home.timetracker.core.entity.task.TrackerTask;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class User {
private String userName;
private List<TrackerTask> tasks = new ArrayList<>();
}
package com.home.timetracker.core.routing;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class ApplicationReducer<T> {
private ApplicationState state;
private T payload;
}
package com.home.timetracker.core.routing;
public enum ApplicationState {
DASHBOARD,
AUTH,
TASKS_LIST,
STATISTIC,
TASK_OPERATIONS,
TASK_INFO
}
package com.home.timetracker.core.routing;
import com.home.timetracker.core.AsSubscriber;
import com.home.timetracker.core.SubjectsStore;
import com.home.timetracker.core.entity.User;
import com.home.timetracker.core.entity.task.TrackerTask;
import com.home.timetracker.ui.MainFrame;
import com.home.timetracker.ui.panel.*;
import java.awt.*;
public class RouteManager implements AsSubscriber{
private MainFrame mainFrame;
private ApplicationState prevState = ApplicationState.DASHBOARD;
private Object prevPayload = null;
private ApplicationState currentState = ApplicationState.DASHBOARD;
private PageJPanel<User> dashboardPanel;
private PageJPanel<User> authenticationPanel;
private PageJPanel<TrackerTask> taskInfoPanel;
private PageJPanel<User> taskListPanel;
private PageJPanel<TrackerTask> taskOperationsPanel;
private User currentUser;
private Object currentPayload;
public void start(){
EventQueue.invokeLater(()-> {
mainFrame = new MainFrame();
mainFrame.setVisible(true);
this.dashboardPanel = new DashboardPanel();
this.authenticationPanel = new AuthenticationPanel();
this.taskInfoPanel = new TaskInfoPanel();
this.taskListPanel = new TaskListPanel();
this.taskOperationsPanel = new TaskOperationsPanel();
this.authenticationPanel.init();
mainFrame.setContentPanel(authenticationPanel);
subscribe();
});
}
@Override
public void subscribe() {
SubjectsStore.stateSubject.subscribe(this::changeState);
SubjectsStore.logoutSubject.subscribe(state -> {
this.currentUser = null;
changeState(new ApplicationReducer<>(ApplicationState.AUTH,null));
});
SubjectsStore.backStateSubject.subscribe(state -> {
this.changeState(new ApplicationReducer<>(this.prevState,this.prevPayload));
});
}
private void changeState(ApplicationReducer state){
this.prevState = this.currentState;
this.prevPayload = this.currentPayload;
this.currentState = state.getState();
this.currentPayload = state.getPayload();
switch (state.getState()){
case DASHBOARD: {
this.currentUser = (User) state.getPayload();
this.dashboardPanel.setPayload(this.currentUser);
this.mainFrame.setContentPanel(this.dashboardPanel);
break;
}
case AUTH: {
this.currentUser = null;
this.authenticationPanel.setPayload(null);
this.mainFrame.setContentPanel(this.authenticationPanel);
break;
}
case TASKS_LIST:{
this.taskListPanel.setPayload(this.currentUser);
this.mainFrame.setContentPanel(this.taskListPanel);
break;
}
case TASK_INFO: {
this.taskInfoPanel.setPayload((TrackerTask) state.getPayload());
this.mainFrame.setContentPanel(this.taskInfoPanel);
break;
}
case TASK_OPERATIONS: {
this.taskOperationsPanel.setPayload((TrackerTask) state.getPayload());
this.mainFrame.setContentPanel(this.taskOperationsPanel);
break;
}
}
}
}
package com.home.timetracker.core.service;
import com.home.timetracker.core.entity.User;
import com.home.timetracker.core.entity.task.TaskPriority;
import com.home.timetracker.core.entity.task.TaskStatus;
import com.home.timetracker.core.entity.task.TaskType;
import com.home.timetracker.core.entity.task.TrackerTask;
import java.util.List;
public interface TimeTrackerDataService {
User getUserByName(String name);
List<TrackerTask> getTasks();
void addTask(TrackerTask task);
List<TrackerTask> getUserTasks(User user);
List<TrackerTask> getUnassignedTasks();
List<TrackerTask> getTasksByPriority(TaskPriority priority);
List<TrackerTask> getTasksByType(TaskType type);
List<TrackerTask> getTasksByStatus(TaskStatus status);
}
package com.home.timetracker.core.service;
import com.home.timetracker.core.entity.PlotData;
import com.home.timetracker.core.entity.User;
import com.home.timetracker.core.entity.task.TaskPriority;
import com.home.timetracker.core.entity.task.TaskStatus;
import com.home.timetracker.core.entity.task.TaskType;
import com.home.timetracker.core.entity.task.TrackerTask;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class TimeTrackerDataServiceStub implements TimeTrackerDataService {
private static class TimeTrackerDataServiceStubHolder {
static final TimeTrackerDataServiceStub HOLDER_INSTANCE = new TimeTrackerDataServiceStub();
}
public static final TimeTrackerDataServiceStub INSTANCE = TimeTrackerDataServiceStubHolder.HOLDER_INSTANCE;
private User currentUser; //stub data
private List<TrackerTask> tasks;
@Override
public User getUserByName(String name) {
User user = new User();
this.currentUser = user;
user.setUserName(name);
this.tasks = getTasks();
user.setTasks(this.getUserTasks(user));
return user;
}
@Override
public List<TrackerTask> getTasks() {
return Arrays.stream(new TrackerTask[] {
new TrackerTask(
"TaskTitle",
"Task description",
TaskPriority.LOW,
TaskType.BUG,
TaskStatus.OPEN,
currentUser,
currentUser,
LocalDate.now(),
LocalDate.now(),
8,0,
Arrays.stream(new PlotData[]{
new PlotData("Test1",5),
new PlotData("Test2",2),
new PlotData("Test3",6),
}).collect(Collectors.toList())
),
new TrackerTask(
"TaskTitle",
"Task description",
TaskPriority.CRITICAL,
TaskType.FEATURE,
TaskStatus.OPEN,
currentUser,
null,
LocalDate.now(),
LocalDate.now(),
8,3,
Arrays.stream(new PlotData[]{
new PlotData("Test1",5),
new PlotData("Test2",2),
new PlotData("Test3",6),
}).collect(Collectors.toList())
),
new TrackerTask(
"TaskTitle",
"Task description",
TaskPriority.HIGH,
TaskType.BUG,
TaskStatus.CLOSED,
currentUser,
currentUser,
LocalDate.now(),
LocalDate.now(),
8,6,
Arrays.stream(new PlotData[]{
new PlotData("Test1",5),
new PlotData("Test2",2),
new PlotData("Test3",6),
}).collect(Collectors.toList())
),
new TrackerTask(
"TaskTitle",
"Task description",
TaskPriority.NORMAL,
TaskType.FEATURE,
TaskStatus.IN_PROGRESS,
currentUser,
null,
LocalDate.now(),
LocalDate.now(),
8,5,
Arrays.stream(new PlotData[]{
new PlotData("Test1",5),
new PlotData("Test2",2),
new PlotData("Test3",6),
}).collect(Collectors.toList())
),
new TrackerTask(
"TaskTitle",
"Task description",
TaskPriority.NORMAL,
TaskType.FEATURE,
TaskStatus.IN_PROGRESS,
currentUser,
currentUser,
LocalDate.now(),
LocalDate.now(),
8,5,
Arrays.stream(new PlotData[]{
new PlotData("Test1",5),
new PlotData("Test2",2),
new PlotData("Test3",6),
}).collect(Collectors.toList())
),
new TrackerTask(
"TaskTitle",
"Task description",
TaskPriority.NORMAL,
TaskType.FEATURE,
TaskStatus.IN_PROGRESS,
currentUser,
currentUser,
LocalDate.now(),
LocalDate.now(),
8,5,
Arrays.stream(new PlotData[]{
new PlotData("Test1",5),
new PlotData("Test2",2),
new PlotData("Test3",6),
}).collect(Collectors.toList())
),
new TrackerTask(
"TaskTitle",
"Task description",
TaskPriority.NORMAL,
TaskType.FEATURE,
TaskStatus.IN_PROGRESS,
currentUser,
null,
LocalDate.now(),
LocalDate.now(),
8,5,
Arrays.stream(new PlotData[]{
new PlotData("Test1",5),
new PlotData("Test2",2),
new PlotData("Test3",6),
}).collect(Collectors.toList())
),
new TrackerTask(
"TaskTitle",
"Task description",
TaskPriority.LOW,
TaskType.BUG,
TaskStatus.OPEN,
currentUser,
null,
LocalDate.now(),
LocalDate.now(),
8,5,
Arrays.stream(new PlotData[]{
new PlotData("Test1",5),
new PlotData("Test2",2),
new PlotData("Test3",6),
}).collect(Collectors.toList())
)
}).collect(Collectors.toList());
}
@Override
public void addTask(TrackerTask task) {
this.tasks.add(task);
}
@Override
public List<TrackerTask> getUserTasks(User user) {
return this.tasks
.stream()
.filter(trackerTask -> (trackerTask.getAssignee() != null && trackerTask.getAssignee().equals(user)))
.collect(Collectors.toList());
}
@Override
public List<TrackerTask> getUnassignedTasks() {
return this.tasks
.stream()
.filter(trackerTask -> trackerTask.getAssignee() == null)
.collect(Collectors.toList());
}
@Override
public List<TrackerTask> getTasksByPriority(TaskPriority priority) {
return this.tasks
.stream()
.filter(trackerTask -> trackerTask.getPriority().equals(priority))
.collect(Collectors.toList());
}
@Override
public List<TrackerTask> getTasksByType(TaskType type) {
return this.tasks
.stream()
.filter(trackerTask -> trackerTask.getType().equals(type))
.collect(Collectors.toList());
}
@Override
public List<TrackerTask> getTasksByStatus(TaskStatus status) {
return this.tasks
.stream()
.filter(trackerTask -> trackerTask.getStatus().equals(status))
.collect(Collectors.toList());
}
}
package com.home.timetracker.core;
public interface AsSubscriber {
void subscribe();
}
package com.home.timetracker.core;
public interface MenuAction {
void onClick();
}
package com.home.timetracker.core;
import com.home.timetracker.core.entity.User;
import com.home.timetracker.core.routing.ApplicationReducer;
import rx.subjects.PublishSubject;
public class SubjectsStore {
public static final PublishSubject<ApplicationReducer> stateSubject = PublishSubject.create();
public static final PublishSubject<Boolean> backStateSubject = PublishSubject.create();
public static final PublishSubject<Boolean> packSubject = PublishSubject.create();
public static final PublishSubject<Boolean> openMenuSubject = PublishSubject.create();
public static final PublishSubject<User> loginSubject = PublishSubject.create();
public static final PublishSubject<Boolean> logoutSubject = PublishSubject.create();
}
package com.home.timetracker.ui.panel.additional;
import com.home.timetracker.ui.AppThemeColor;
import com.home.timetracker.ui.ComponentsFactory;
import com.home.timetracker.ui.panel.HasView;
import javax.swing.*;
import java.awt.*;
public abstract class BaseJPanel extends JPanel implements HasView{
protected ComponentsFactory componentsFactory = new ComponentsFactory();
public BaseJPanel(){
super(new BorderLayout());
this.setBackground(AppThemeColor.BACKGROUND);
}
}
package com.home.timetracker.ui.panel.additional;
import com.home.timetracker.core.SubjectsStore;
import com.home.timetracker.core.entity.MenuEntry;
import com.home.timetracker.core.routing.ApplicationReducer;
import com.home.timetracker.core.routing.ApplicationState;
import com.home.timetracker.ui.AppThemeColor;
import com.home.timetracker.ui.TextStyle;
import com.home.timetracker.ui.util.MenuListRenderer;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class MenuPanel extends BaseJPanel {
public MenuPanel() {
super();
this.setBackground(AppThemeColor.MENU_BG_COLOR);
this.setPreferredSize(new Dimension(220,20));
this.setBorder(BorderFactory.createMatteBorder(0,0,0,1,AppThemeColor.HEADER_BORDER_COLOR));
this.createView();
}
@Override
public void createView() {
JList<MenuEntry> list = new JList<>(getEntries());
list.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
list.setCursor(new Cursor(Cursor.HAND_CURSOR));
}
@Override
public void mouseExited(MouseEvent e) {
list.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
});
list.setCellRenderer(new MenuListRenderer());
list.setBackground(AppThemeColor.MENU_BG_COLOR);
list.setSelectedIndex(0);
list.addListSelectionListener(e ->
list.getSelectedValue().getAction().onClick());
JLabel appIcon = this.componentsFactory.getLabel("TimeTracker",20,AppThemeColor.MENU_FONT_COLOR, TextStyle.BOLD);
appIcon.setIcon(new ImageIcon(this.componentsFactory.getIcon("app/app_icon.png", 36)));
appIcon.setBorder(BorderFactory.createEmptyBorder(15,15,15,15));
appIcon.setBackground(AppThemeColor.MENU_BG_COLOR);
this.add(list,BorderLayout.CENTER);
this.add(appIcon,BorderLayout.PAGE_START);
}
@SuppressWarnings("all")
private MenuEntry[] getEntries(){
return new MenuEntry[] {
new MenuEntry("Dashboard",()->{
SubjectsStore.stateSubject.onNext(new ApplicationReducer(ApplicationState.DASHBOARD,null));
},new ImageIcon(this.componentsFactory.getIcon("app/dashboard_icon.png",26))),
new MenuEntry("Tasks",()->{
SubjectsStore.stateSubject.onNext(new ApplicationReducer(ApplicationState.TASKS_LIST,null));
},new ImageIcon(this.componentsFactory.getIcon("app/thickets_icon.png",26))),
new MenuEntry("Statistic",()->{
SubjectsStore.stateSubject.onNext(new ApplicationReducer(ApplicationState.STATISTIC,null));
},new ImageIcon(this.componentsFactory.getIcon("app/statistic_icon.png",26))),
new MenuEntry("Account",()->{
SubjectsStore.stateSubject.onNext(new ApplicationReducer(ApplicationState.DASHBOARD,null));
},new ImageIcon(this.componentsFactory.getIcon("app/account_icon.png",26)))
};
}
}
packagecom.home.timetracker.ui.panel;
public interface HasView {
void createView();
}
package com.home.timetracker.ui.panel;
import com.home.timetracker.core.SubjectsStore;
import com.home.timetracker.ui.AppThemeColor;
import com.home.timetracker.ui.ComponentsFactory;
import javax.swing.*;
import java.awt.*;
public abstract class PageJPanel<T> extends JPanel {
protected T payload;
protected ComponentsFactory componentsFactory = new ComponentsFactory();
protected PageJPanel(){
super(new BorderLayout());
this.setBackground(AppThemeColor.BACKGROUND_DARK);
}
public abstract void init();
public void setPayload(T payload) {
this.payload = payload;
if(this.payload != null) {
this.removeAll();
this.init();
}
SubjectsStore.packSubject.onNext(true);
}
}
package com.home.timetracker.ui.panel;
import com.home.timetracker.core.SubjectsStore;
import com.home.timetracker.core.entity.User;
import com.home.timetracker.core.entity.task.TrackerTask;
import com.home.timetracker.core.routing.ApplicationReducer;
import com.home.timetracker.core.routing.ApplicationState;
import com.home.timetracker.core.service.TimeTrackerDataServiceStub;
import com.home.timetracker.ui.AppThemeColor;
import com.home.timetracker.ui.TextStyle;
import com.home.timetracker.ui.panel.additional.TaskEntryPanel;
import com.home.timetracker.ui.util.VerticalScrollContainer;
import javax.swing.*;
import java.awt.*;
public class TaskListPanel extends PageJPanel<User> {
private JPanel taskGrid;
private TaskFilter filter = TaskFilter.ALL;
@Override
public void init() {
taskGrid = this.componentsFactory.getGridJPanel(3,0,5,5);
taskGrid.setBackground(AppThemeColor.BACKGROUND_DARK);
VerticalScrollContainer taskContainer = new VerticalScrollContainer();
taskContainer.setLayout(new BorderLayout());
taskContainer.setBackground(AppThemeColor.BACKGROUND_DARK);
taskContainer.add(taskGrid,BorderLayout.CENTER);
JScrollPane scrollPane = this.componentsFactory.getScrollPane(taskContainer,AppThemeColor.BACKGROUND_DARK);
this.fillContainer();
this.add(getHeaderPanel(), BorderLayout.PAGE_START);
this.add(scrollPane, BorderLayout.CENTER);
}
private void fillContainer(){
this.taskGrid.removeAll();
switch (this.filter){
case ALL:{
TimeTrackerDataServiceStub.INSTANCE.getTasks().forEach(task -> {
taskGrid.add(new TaskEntryPanel(task));
});
break;
}
case ASSIGNED_TO_ME: {
this.payload.getTasks().forEach(task -> {
taskGrid.add(new TaskEntryPanel(task));
});
}
}
}
public JPanel getHeaderPanel(){
JPanel root = this.componentsFactory.getJPanel(new BorderLayout());
root.setBorder(BorderFactory.createEmptyBorder(2,2,5,2));
root.setBackground(AppThemeColor.BACKGROUND_DARK);
JButton addTaskButton = this.componentsFactory.getIconButton("app/add_task.png", 30, AppThemeColor.BACKGROUND_DARK);
addTaskButton.addActionListener(action -> SubjectsStore.stateSubject.onNext(
new ApplicationReducer<>(ApplicationState.TASK_OPERATIONS, null)));
JComboBox<String> filterComboBox = this.componentsFactory.getComboBox(TaskFilter.class, filter.toString());
filterComboBox.addActionListener(action -> {
this.filter = TaskFilter.valueOf(filterComboBox.getSelectedItem().toString());
this.fillContainer();
SubjectsStore.packSubject.onNext(true);
});
root.add(filterComboBox,BorderLayout.LINE_START);
root.add(addTaskButton,BorderLayout.LINE_END);
return root;
}
private enum TaskFilter {
ALL, ASSIGNED_TO_ME
}
}
package com.home.timetracker.ui.plot;
import com.home.timetracker.ui.AppThemeColor;
import de.erichseifert.gral.data.DataSource;
import de.erichseifert.gral.data.DataTable;
import de.erichseifert.gral.graphics.Insets2D;
import de.erichseifert.gral.plots.PiePlot;
import de.erichseifert.gral.plots.colors.LinearGradient;
import de.erichseifert.gral.ui.InteractivePanel;
import javax.swing.*;
import java.awt.*;
import java.util.Random;
public class ForegroundPiePlot extends JPanel{
private final DataTable dataTable;
private final PiePlot piePlot;
public ForegroundPiePlot() {
this.dataTable = new DataTable(Integer.class);
this.piePlot = new PiePlot(dataTable);
this.piePlot.setRadius(0.9);
this.piePlot.setStart(90.0);
this.piePlot.setInsets(new Insets2D.Double(20.0));
PiePlot.PieSliceRenderer pieSliceRenderer = (PiePlot.PieSliceRenderer) piePlot.getPointRenderer(dataTable);
pieSliceRenderer.setGap(0.2);
pieSliceRenderer.setValueVisible(true);
LinearGradient color = new LinearGradient(AppThemeColor.DARK_PRIMARY_COLOR,AppThemeColor.BACKGROUND);
pieSliceRenderer.setColor(color);
InteractivePanel panel = new InteractivePanel(piePlot);
panel.setPannable(false);
panel.setZoomable(false);
this.setLayout(new BorderLayout());
this.add(panel,BorderLayout.CENTER);
for (int i = 0; i < 15; i++) {
this.dataTable.add(new Random().nextInt(3));
}
}
}
package com.home.timetracker.ui.util;
import com.home.timetracker.core.entity.MenuEntry;
import com.home.timetracker.ui.AppThemeColor;
import com.home.timetracker.ui.ComponentsFactory;
import com.home.timetracker.ui.TextStyle;
import javax.swing.*;
import java.awt.*;
public class MenuListRenderer extends JButton implements ListCellRenderer<MenuEntry> {
private ComponentsFactory componentsFactory = new ComponentsFactory();
@Override
public Component getListCellRendererComponent(JList<? extends MenuEntry> list, MenuEntry value, int index, boolean isSelected, boolean cellHasFocus) {
JButton button = this.componentsFactory.getButton(value.getText(), TextStyle.REGULAR,18f);
button.setForeground(AppThemeColor.MENU_FONT_COLOR);
button.setHorizontalAlignment(SwingConstants.LEFT);
button.setBackground(AppThemeColor.MENU_BG_COLOR);
button.setPreferredSize(new Dimension(220,50));
button.setIcon(value.getImageIcon());
if(isSelected){
button.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(0,14,0,0),
BorderFactory.createMatteBorder(0,0,0,4,AppThemeColor.DARK_PRIMARY_COLOR)));
button.setBackground(AppThemeColor.MENU_SELECTED_COLOR);
}else {
button.setBorder(BorderFactory.createEmptyBorder(0,10,0,4));
}
button.addActionListener(action -> {
value.getAction().onClick();
});
return button;
}
}
package com.home.timetracker.ui.util;
import com.home.timetracker.ui.AppThemeColor;
import javax.swing.*;
import javax.swing.plaf.basic.BasicScrollBarUI;
import java.awt.*;
public class ScrollUI extends BasicScrollBarUI {
private final Dimension d = new Dimension();
private Color scrollColor;
public ScrollUI(Color color) {
this.scrollColor = color;
}
public ScrollUI() {
this.scrollColor = AppThemeColor.HEADER_BUTTONS_COLOR;
}
@Override
protected JButton createDecreaseButton(int orientation) {
return new JButton() {
@Override
public Dimension getPreferredSize() {
return d;
}
};
}
@Override
protected JButton createIncreaseButton(int orientation) {
return new JButton() {
@Override
public Dimension getPreferredSize() {
return d;
}
};
}
@Override
protected void paintTrack(Graphics g, JComponent c, Rectangle r) {
}
@Override
protected void paintThumb(Graphics g, JComponent c, Rectangle r) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Color color = null;
JScrollBar sb = (JScrollBar) c;
if (!sb.isEnabled()) {
return;
} else {
color = scrollColor;
}
g2.setPaint(color);
g2.fillRect(r.x, r.y, r.width, r.height);
g2.setPaint(AppThemeColor.HEADER_BORDER_COLOR);
g2.drawRect(r.x, r.y, r.width, r.height);
g2.dispose();
}
@Override
protected void setThumbBounds(int x, int y, int width, int height) {
super.setThumbBounds(x, y, width, height);
scrollbar.repaint();
}
}
package com.home.timetracker.ui.util;
import com.home.timetracker.ui.AppThemeColor;
import com.home.timetracker.ui.ComponentsFactory;
import javax.swing.*;
import java.awt.*;
public class UIUtils {
private static ComponentsFactory componentsFactory = new ComponentsFactory();
public static JPanel wrapToSlide(JComponent panel){
JPanel wrapper = componentsFactory.getJPanel(new BorderLayout());
wrapper.setBackground(AppThemeColor.BACKGROUND_DARK);
wrapper.setBorder(BorderFactory.createEmptyBorder(4,4,4,4));
wrapper.add(panel,BorderLayout.CENTER);
return wrapper;
}
public static JPanel wrapToVerticalSlide(JComponent panel){
JPanel wrapper = wrapToSlide(panel);
wrapper.setBorder(BorderFactory.createEmptyBorder(4,0,4,0));
return wrapper;
}
}
package com.home.timetracker.ui.util;
import javax.swing.*;
import java.awt.*;
public class VerticalScrollContainer extends JPanel implements Scrollable {
@Override
public Dimension getPreferredScrollableViewportSize() {
return super.getPreferredSize();
}
@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 16;
}
@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 16;
}
@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
@Override
public boolean getScrollableTracksViewportHeight() {
return false;
}
}
package com.home.timetracker.ui;
import com.home.timetracker.core.AsSubscriber;
import com.home.timetracker.core.SubjectsStore;
import com.home.timetracker.ui.panel.AuthenticationPanel;
import com.home.timetracker.ui.panel.HasView;
import com.home.timetracker.ui.panel.additional.MenuPanel;
import com.home.timetracker.ui.panel.additional.navigation.NavigationHeaderPanel;
import javax.swing.*;
import java.awt.*;
public class MainFrame extends JFrame implements AsSubscriber,HasView {
private JPanel currentPanel;
private MenuPanel menuPanel;
private NavigationHeaderPanel headerPanel;
private JPanel root;
public MainFrame() throws HeadlessException {
super("Time tracker");
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setVisible(true);
this.setLayout(new BorderLayout());
this.setBackground(AppThemeColor.BACKGROUND_DARK);
this.setPreferredSize(new Dimension(1000,700));
this.setMinimumSize(new Dimension(1000,700));
this.createView();
this.subscribe();
this.pack();
this.setLocationRelativeTo(null);
}
public void setContentPanel(JPanel panel){
if(currentPanel != null){
this.root.remove(currentPanel);
}
if(panel instanceof AuthenticationPanel){
this.menuPanel.setVisible(false);
this.headerPanel.setVisible(false);
}else {
this.headerPanel.setVisible(true);
}
this.root.add(panel,BorderLayout.CENTER);
this.currentPanel = panel;
this.pack();
this.repaint();
}
@Override
public void subscribe() {
SubjectsStore.packSubject.subscribe(state -> {
this.pack();
this.repaint();
});
SubjectsStore.openMenuSubject.subscribe(state -> {
if(this.menuPanel.isVisible()){
this.menuPanel.setVisible(false);
}else {
this.menuPanel.setVisible(true);
}
this.pack();
this.repaint();
});
}
@Override
public void createView() {
this.root = new JPanel(new BorderLayout());
headerPanel = new NavigationHeaderPanel();
this.root.add(headerPanel,BorderLayout.PAGE_START);
this.menuPanel = new MenuPanel();
this.menuPanel.setVisible(false);
this.add(menuPanel,BorderLayout.LINE_START);
this.add(root,BorderLayout.CENTER);
}
}
package com.home.timetracker.ui;
public enum TextStyle {
BOLD, LIGHT, ITALIC, MEDIUM, REGULAR
}
package com.home.timetracker;
import com.home.timetracker.core.routing.RouteManager;
public class AppMain {
public static void main(String[] args) {
new RouteManager().start();
}
}
Презентационный материал
Размещено на Allbest.ru
...Подобные документы
Назначение и архитектура экспертных систем, их применение в сфере образования. Экспертные системы тестирования, принципы их функционирования. Инструментальные средства создания приложения и разработка программы тестирования. Описание программы, листинг.
дипломная работа [706,4 K], добавлен 07.05.2012Разработка приложения, которое будет выполнять функции показа точного времени и точной даты. Определение дополнительных функций разработанного приложения. Рассмотрение основных этапов создания программного продукта. Результаты тестирования приложения.
курсовая работа [2,2 M], добавлен 14.04.2019Разработка пользовательского интерфейса. Цели и задачи базы данных. Создание информационно-структурной модели для предприятия и обеспечение в этой сети необходимого уровня защиты информации от некомпетентных действий некоторых сотрудников предприятия.
курсовая работа [1,1 M], добавлен 27.12.2009Проектирование структуры программы, принцип ее работы, сферы практического использования и оценка возможностей. Выбор и обоснование среды программирования. Разработка пользовательского интерфейса и модулей приложения. Проведение тестирования программы.
курсовая работа [637,7 K], добавлен 14.01.2015Характеристика форматов файлов wav и mp3. Построение диаграмм прецедентов, разработка графического интерфейса и архитектуры приложения. Разработка алгоритмов работы программы: метод TrimWavFile, TrimMp3, ChangeVolume, speedUpX1_2, speedDownX1_2.
курсовая работа [2,7 M], добавлен 20.12.2013Понятие, законодательное регулирование и виды электронных подписей. Разработка структурной схемы приложения и базы данных. Создание диаграммы прецедентов и классов. Проектирование интерфейса программы. Анализ руководства пользователя web-приложения.
дипломная работа [869,8 K], добавлен 12.08.2017Обзор подходов к разработке музейных приложений с элементами дополненной реальности, формирование требований к ним. Выбор методов разработки приложения, разработка пользовательского интерфейса. Принципы тестирования. Реализация раздела "Распознавание".
дипломная работа [2,8 M], добавлен 03.07.2017Разработка графического интерфейса проекта (панель инструментов имеет 6 кнопок). Процедуры разделов программы: документа ThisDocument, программного модуля Module1 и пользовательских форм UserForm1, UserForm2 и Деление_амёбы. Тестирование программы.
курсовая работа [29,5 K], добавлен 14.12.2010Интерфейс системы онлайн-мониторинга стационарного аппарата. Интерфейс автоматизированного рабочего места мониторинга АПБ Московского метрополитена. Архитектура системы ProView, основные сферы применения. Структура графического интерфейса пользователя.
курсовая работа [1,8 M], добавлен 21.03.2016Клиент-серверная архитектура проектируемой программы по проверке знаний студентов, структура базы данных. Разработка ее программно-интерфейсной реализации в среде Delphi. Установка и запуск приложения, информация для пользователя, листинг программы.
дипломная работа [2,1 M], добавлен 20.06.2011Характеристика информационных систем учета медицинских услуг, представленных на современном рынке. Разработка приложения "Учет услуг в спортивном клубе "Т-Фитнес": средства управления графического интерфейса пользователя, создание меню и основные формы.
дипломная работа [1,8 M], добавлен 14.10.2010Обобщенная структура и принципы функционирования экспертных систем. Выбор модели представления знаний. Разработка логического блока программы и графического пользовательского интерфейса. Текст программы и экспериментальная оценка результатов работы.
дипломная работа [2,4 M], добавлен 06.03.2013Программа смены обоев рабочего стола, принцип ее работы. Основные виды обоев для рабочего стола. Существующие программы и их преимущества. Разработка приложения для смены обоев рабочего стола с использованием функций программы Delphi 7, листинг программы.
контрольная работа [3,8 M], добавлен 17.11.2012Теоретические основы разработки приложения, реализующего подсвечивание ключевых слов. Описание используемых процедур и функций, структуры программы, интерфейса пользователя. Системные требования для работы приложения, анализ результаты его тестирования.
курсовая работа [1,2 M], добавлен 07.07.2012Анализ использования рабочего времени. Создание базы данных для хранения и обработки информации. Управление пользователями. Интерфейс программы. Работа со списком мероприятий, с модулями "задачи", "заявки", "регламенты", "события" и "отчётность".
дипломная работа [3,3 M], добавлен 19.01.2017Проектирование модульной структуры программы сетевого мессенджера, назначение модуля "frmMsg". Разработка главной формы и интерфейса пользователя программы. Проектирование модуля формы "About". Разработка методики тестирования и отладка программы.
курсовая работа [606,7 K], добавлен 19.01.2012Изучение особенностей растровых и векторных графических редакторов. Создание графического редактора: выбор языка программирования, разработка структуры программы и алгоритма работы. Описание интерфейса программы. Руководство программиста и пользователя.
курсовая работа [1,3 M], добавлен 28.07.2013Анализ аналогов-ресурсов системы "Бюро регистрации несчастных случаев", критерии выбор задач, подлежащих автоматизации. Проектирование автоматизированного рабочего места сотрудника оперативного учета. Разработка модели базы с использованием CASE-средств.
дипломная работа [7,8 M], добавлен 21.01.2012Техника создания графики при помощи API функций, экспортируемых библиотекой GDI32.DLL. Разработка на языке программирования С++ в среде программирования Microsoft Visual C++ программы для отображения часов реального времени в цифровом и аналоговом виде.
курсовая работа [2,8 M], добавлен 27.01.2010Создание системы компьютерного тестирования для контроля знаний. Проблемы, возникающие при создании тестовой оболочки в среде Ren`Py. Разработка проектных решений по системе и её частям. Структура тестирования, вопросы и ответы тестирующей системы.
дипломная работа [501,6 K], добавлен 12.09.2016