Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #373

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -8,18 +8,18 @@

public class HotKeysInterceptor {
public HotKeysInterceptor() {
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(Level.OFF);

logger.setUseParentHandlers(false);
try {
GlobalScreen.registerNativeHook();
} catch (NativeHookException e) {
e.printStackTrace();
}

GlobalScreen.addNativeKeyListener(new MercuryNativeKeyListener());
GlobalScreen.addNativeMouseListener(new MercuryNativeMouseListener());
// Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
// logger.setLevel(Level.OFF);
//
// logger.setUseParentHandlers(false);
// try {
// GlobalScreen.registerNativeHook();
// } catch (NativeHookException e) {
// e.printStackTrace();
// }
//
// GlobalScreen.addNativeKeyListener(new MercuryNativeKeyListener());
//// GlobalScreen.addNativeMouseListener(new MercuryNativeMouseListener());
}

public static void main(String[] args) {
Original file line number Diff line number Diff line change
@@ -372,6 +372,7 @@ public JLabel getTextLabel(String text, FontStyle style, Color color, float size
return getTextLabel(style, color, TextAlignment.LEFTOP, size, text);
}


/**
* Get label with icon
*
@@ -599,7 +600,7 @@ public JScrollPane getVerticalContainer(JPanel container) {
JScrollBar vBar = scrollPane.getVerticalScrollBar();
vBar.setBackground(AppThemeColor.SLIDE_BG);
vBar.setUI(new MercuryScrollBarUI());
vBar.setPreferredSize(new Dimension(15, Integer.MAX_VALUE));
vBar.setPreferredSize(new Dimension(11, Integer.MAX_VALUE));
vBar.setUnitIncrement(3);
vBar.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
return scrollPane;
@@ -665,13 +666,21 @@ public JTextArea getSimpleTextArea(String text) {
area.setEditable(false);
area.setWrapStyleWord(true);
area.setLineWrap(true);
area.setBackground(AppThemeColor.TRANSPARENT);
area.setBackground(AppThemeColor.FRAME);
area.setBorder(null);
area.setFont(REGULAR_FONT.deriveFont(scale * 16f));
area.setForeground(AppThemeColor.TEXT_DEFAULT);
return area;
}

public JTextArea getSimpleTextArea(String text, FontStyle style, float size) {
JTextArea area = this.getSimpleTextArea(text);
area.setFont(this.getFont(style, size));
area.setAlignmentX(SwingConstants.LEFT);
area.setAlignmentY(SwingConstants.CENTER);
return area;
}

public float getScale() {
return scale;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.mercury.platform.ui.components.datatable;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class MColumn {
private String caption;
private String selector;
private boolean sort;
private boolean filter;
private Class<?> rendererClass;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
package com.mercury.platform.ui.components.datatable;

import com.mercury.platform.ui.components.ComponentsFactory;
import com.mercury.platform.ui.components.datatable.data.DataRequest;
import com.mercury.platform.ui.components.datatable.data.LazyLoadParams;
import com.mercury.platform.ui.components.datatable.data.MDataService;
import com.mercury.platform.ui.components.datatable.renderer.*;
import com.mercury.platform.ui.components.datatable.ui.RowBorderListener;
import com.mercury.platform.ui.components.fields.font.FontStyle;
import com.mercury.platform.ui.components.panel.VerticalScrollContainer;
import com.mercury.platform.ui.components.panel.misc.AfterViewInit;
import com.mercury.platform.ui.components.panel.misc.ViewDestroy;
import com.mercury.platform.ui.components.panel.misc.ViewInit;
import com.mercury.platform.ui.misc.AppThemeColor;
import org.apache.commons.lang3.StringUtils;
import rx.subjects.ReplaySubject;

import javax.swing.*;
import java.awt.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

public class MDataTable<T> extends JPanel implements ViewInit, ViewDestroy, AfterViewInit {
private ComponentsFactory componentsFactory = new ComponentsFactory();
private MColumn[] columns;
private MDataService<T> dataService;

private int pageSize = 10;
private int currentPage = 1;

private Map<Class, MCellRenderer> cellRendererMap = new HashMap<>();
private ReplaySubject<?> unsubscribe$ = ReplaySubject.create();

private VerticalScrollContainer container;

public MDataTable(MColumn[] columns, MDataService<T> dataService, int pageSize) {
super(new BorderLayout());
this.columns = columns;
this.dataService = dataService;
this.pageSize = pageSize;

if (dataService == null || columns == null) {
throw new NullPointerException("DataService or columns can't be null");
}
this.fillRendererMap();
this.onViewInit();
this.initDataProviders();
this.onAfterViewInit();
}

@Override
public void onViewInit() {
this.container = new VerticalScrollContainer();
this.container.setBackground(AppThemeColor.FRAME);
this.container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
JScrollPane verticalContainer = this.componentsFactory.getVerticalContainer(this.container);

this.add(this.getHeaderPanel(), BorderLayout.PAGE_START);
this.add(this.componentsFactory.wrapToSlide(verticalContainer, 2, 0, 0, 0), BorderLayout.CENTER);
this.add(this.getPeginator(), BorderLayout.PAGE_END);
}

@Override
public void onAfterViewInit() {
this.reload();
}

public void reload() {
this.container.removeAll();
DataRequest dataRequest = new DataRequest();
dataRequest.setLazyLoadParams(new LazyLoadParams((this.currentPage - 1) * this.pageSize, this.pageSize));
this.dataService.update(dataRequest);
this.repaint();
}

private JPanel getHeaderPanel() {
JPanel root = this.componentsFactory.getJPanel(new GridLayout());
Arrays.stream(this.columns).forEach(it -> {
JPanel headerColumn = this.componentsFactory.getJPanel(new BorderLayout(), AppThemeColor.TABLE_HEADER_BG);
headerColumn.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 1, AppThemeColor.TABLE_BORDER));
headerColumn.add(this.componentsFactory.getTextLabel(it.getCaption()), BorderLayout.LINE_START);

if (it.isFilter()) {
JButton filter_menu = componentsFactory.getIconButton("app/sandwich.png", 13, AppThemeColor.TABLE_HEADER_BG, "Filter menu");
headerColumn.add(filter_menu, BorderLayout.LINE_END);
}
root.add(headerColumn);
});
((JPanel) root.getComponent(0)).setBorder(BorderFactory.createLineBorder(AppThemeColor.TABLE_BORDER));
return root;
}

@SuppressWarnings("all")
private void initDataProviders() {
this.dataService.getValues()
.takeUntil(this.unsubscribe$)
.subscribe(data -> {
Arrays.stream(data).forEach(it -> {
JPanel root = this.componentsFactory.getJPanel(new GridLayout(), AppThemeColor.TABLE_CELL_BG);
Arrays.stream(this.columns).forEach(column -> {
try {
String[] selectors = this.parseSelector(column.getSelector(), it);
StringBuilder result = new StringBuilder();
for (String selector : selectors) {
Method method = it.getClass().getMethod("get" + selector);
result.append(method.invoke(it));
if (selectors.length > 1) {
result.append(":");
}
}
if (!result.toString().trim().equals("")) {
JComponent component =
this.componentsFactory.wrapToSlide(this.cellRendererMap
.get(column.getRendererClass())
.getComponent(result.toString()), AppThemeColor.TABLE_CELL_BG);
component.setBorder(BorderFactory.createMatteBorder(0, 1, 0, 0, AppThemeColor.TABLE_BORDER));
root.add(component);
} else {
root.add(this.getDefaultComponent());
}
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
root.add(this.getDefaultComponent());
}
});
root.setBorder(BorderFactory.createLineBorder(AppThemeColor.TABLE_BORDER));
root.addMouseListener(new RowBorderListener(root));
((JComponent) root.getComponent(0)).setBorder(BorderFactory.createEmptyBorder(0, 1, 0, 0));
this.container.add(this.componentsFactory.wrapToSlide(root, 2, 0, 0, 0));
});
JFrame parent = (JFrame) SwingUtilities.getWindowAncestor(this);
if (parent != null) {
parent.pack();
}
});
this.dataService.getTotalValues()
.takeUntil(this.unsubscribe$)
.subscribe(count -> {

});
}

private JComponent getDefaultComponent() {
JPanel root = this.componentsFactory.getJPanel(new FlowLayout(FlowLayout.CENTER, 0, 0), AppThemeColor.TABLE_CELL_BG);
root.add(this.componentsFactory.getTextLabel("-", FontStyle.REGULAR));
JComponent component =
this.componentsFactory.wrapToSlide(root, AppThemeColor.TABLE_CELL_BG);
component.setBorder(BorderFactory.createMatteBorder(0, 1, 0, 0, AppThemeColor.TABLE_BORDER));
return component;
}

private String[] parseSelector(String query, T data) {
String[] parsedQuery = query.split("\\|");
List<String> methodsName = Arrays.stream(data.getClass().getMethods())
.map(Method::getName)
.collect(Collectors.toList());
if (parsedQuery.length == 1 && !parsedQuery[0].contains("+")) {
return parsedQuery;
} else {
List<String> selectors = new ArrayList<>();
Arrays.stream(parsedQuery).forEach(it -> {
if (it.contains("(") && it.contains(")")) {
it = StringUtils.substringBetween(it, "(", ")");
}
String[] split = it.split("\\+");
for (String item : split) {
if (methodsName.contains("get" + item)) {
selectors.add(item);
}
}
});
return selectors.toArray(new String[0]);
}
}

private JPanel getPeginator() {
JPanel paginator = this.componentsFactory.getJPanel(new BorderLayout(), AppThemeColor.TABLE_HEADER_BG);
paginator.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 1, AppThemeColor.TABLE_BORDER));
paginator.add(this.componentsFactory.getTextLabel("1 2 3"));
return this.componentsFactory.wrapToSlide(paginator, 2, 0, 0, 0);
}

private void fillRendererMap() {
this.cellRendererMap.put(PlainTextRenderer.class, new PlainTextRenderer());
this.cellRendererMap.put(PlainIconRenderer.class, new PlainIconRenderer());
this.cellRendererMap.put(NotificationTypeRenderer.class, new NotificationTypeRenderer());
this.cellRendererMap.put(PlainDoubleRenderer.class, new PlainDoubleRenderer());
}

public void addCellRenderer(Class classType, MCellRenderer renderer) {
this.cellRendererMap.putIfAbsent(classType, renderer);
}

@Override
public void onViewDestroy() {
this.unsubscribe$.onNext(null);
this.unsubscribe$.onCompleted();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.mercury.platform.ui.components.datatable.data;

import lombok.Data;

@Data
public class DataRequest {
private LazyLoadParams lazyLoadParams;
private SortParams sortParams;
private String filters;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.mercury.platform.ui.components.datatable.data;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class LazyLoadParams {
private int skip;
private int top;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.mercury.platform.ui.components.datatable.data;

import com.mercury.platform.ui.components.panel.misc.ViewDestroy;
import lombok.Getter;
import rx.subjects.ReplaySubject;

public abstract class MDataService<T> implements ViewDestroy {
@Getter
private ReplaySubject<Integer> totalValues = ReplaySubject.create();
@Getter
private ReplaySubject<T[]> values = ReplaySubject.create();

private ReplaySubject<DataRequest> updateStream = ReplaySubject.create();
private ReplaySubject<T> removeStream = ReplaySubject.create();

private ReplaySubject<?> unsubscribe$ = ReplaySubject.create();

public MDataService() {
this.updateStream
.takeUntil(this.unsubscribe$)
.subscribe(dataRequest -> {
T[] data = this.getData(dataRequest);
this.values.onNext(data);
this.totalValues.onNext(data.length);
});
this.removeStream
.takeUntil(this.unsubscribe$)
.subscribe(this::removeData);
}

public void update(DataRequest dataRequest) {
this.updateStream.onNext(dataRequest);
}

public void remove(T data) {
this.removeStream.onNext(data);
}

public abstract T[] getData(DataRequest request);

public abstract void removeData(T data);

@Override
public void onViewDestroy() {
this.unsubscribe$.onNext(null);
this.unsubscribe$.onCompleted();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.mercury.platform.ui.components.datatable.data;

import lombok.Data;

@Data
public class SortParams {
private String columnName;
private boolean reverse;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.mercury.platform.ui.components.datatable.renderer;

import javax.swing.*;

public interface MCellRenderer<T> {
JComponent getComponent(T data);
}
Loading