weisj / darklaf Goto Github PK
View Code? Open in Web Editor NEWDarklaf - A themeable swing Look and Feel based on Darcula-Laf
License: MIT License
Darklaf - A themeable swing Look and Feel based on Darcula-Laf
License: MIT License
We're using 3rd party swing based framework that manipulates UI controls through reflection.
Unfortunately, last release (1.4.0.0) leads to NPE with the following call stack:
java.lang.NullPointerException
at com.github.weisj.darklaf.platform.macos.ui.MacOSTitlePane$PropertyChangeHandler.propertyChange(MacOSTitlePane.java:246)
at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335)
at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:327)
at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:263)
at java.awt.Component.firePropertyChange(Component.java:8434)
at java.awt.Frame.setTitle(Frame.java:523)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
... 3rd party framework call stack
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
... 3rd party framework call stack
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Based on MacOSTitlePane I suppose that pce.getNewValue() is null at line 246 at correct code could be
protected class PropertyChangeHandler implements PropertyChangeListener {
public void propertyChange(final PropertyChangeEvent pce) {
String name = pce.getPropertyName();
if ("title".equals(name)) {
titleLabel.setText(pce.getNewValue() == null ? null : pce.getNewValue().toString());
repaint();
}
}
}
P.S. I don't understand why the title value is null, I pass not null value to the framework
I just noticed darklaf-windows from a RC-2 is 350KiB, and each DLL takes 500KiB.
It does not hurt much, however, it is a bit strange considering that JNIDecorations.cpp
is just 8KiB.
Does that mean debugging information costs that much?
Would the binary be smaller if optimized
one is shipped instead?
0 02-01-1980 00:00 com/github/weisj/darklaf/platform/darklaf-windows/
0 02-01-1980 00:00 com/github/weisj/darklaf/platform/darklaf-windows/windows-x86/
456704 02-01-1980 00:00 com/github/weisj/darklaf/platform/darklaf-windows/windows-x86/darklaf-windows.dll
0 02-01-1980 00:00 com/github/weisj/darklaf/platform/darklaf-windows/windows-x86-64/
571392 02-01-1980 00:00 com/github/weisj/darklaf/platform/darklaf-windows/windows-x86-64/darklaf-windows.dll
The following code leads to incorrect Jdialog initial size (and position). Actually it's on decoration under OSX and shows JDialog.
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import com.github.weisj.darklaf.LafManager;
public class Foo2 {
private void initGUI() {
JFrame frame = new JFrame("XXX");
JButton button = new JButton("XXX");
button.addActionListener(x -> {
// create a dialog Box
JDialog d = new JDialog(frame);
// create a label
JLabel l = new JLabel("this is a dialog box");
d.add(l);
// setsize of dialog
d.setSize(300, 300);
d.setLocationRelativeTo(null);
// set visibility of dialog
d.setVisible(true);
});
JPanel content = new JPanel(new FlowLayout());
content.add(button);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setContentPane(content);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
// LafManager.setDecorationsEnabled(false);
LafManager.install();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Foo2().initGUI();
}
});
}
}
Currently the default style for the split pane divider is grip
(through the SplitPane.defaultDividerStyle
property). Personally I would almost always prefer the look of the Line
style.
I'd like to change the default value of SplitPane.defaultDividerStyle
to be line
.
This comes with a few drawbacks though as this style by design doesn't honour JSplitPane#isOneTouchExpandable
.
I'd like to get feedback on whether the change should happen.
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at com.github.weisj.darklaf.ui.toolbar.DarkToolBarUI.dragTo(DarkToolBarUI.java:201)
at com.github.weisj.darklaf.ui.toolbar.DarkToolBarUI.lambda$new$0(DarkToolBarUI.java:46)
at java.desktop/javax.swing.Timer.fireActionPerformed(Timer.java:317)
at java.desktop/javax.swing.Timer$DoPostEvent.run(Timer.java:249)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Occurs on Windows when dragging a floating JToolbar between monitors of different resolutions.
This relates to #2 .
Provide a custom title bar on macOS. After doing some research, this could be done by setting
the properties
fullsizecontentview
and ]titlebarappearstransparent
of the underlying NSWindow. (see https://stackoverflow.com/questions/54353576/colorizing-the-titlebar-in-macos-with-multiple-colors).
Communication with java would happen as in the windows version through JNI passing the request to a C++ function which in turn calls the objective-c code, that is able to set those properties.
If working the LaF should add a custom title bar (without window buttons, as those should still be present).
As I don't have access to macOS platform I can't do this myself, so help would be highly appreciated.
The insets for components such as JButton, JComboBox etc. should be able to be changed by setting the appropriate properties in themes.
See 8246bb4 as an example (JButton).
Any occurrence of new InsetsUIResource(...)
where there are hard coded values.
When i am use JComboBox it shows error message java.lang.NoClassDefFoundError
The pre-built (maven) binaries seem to be built with a newer version of Java. Therefore this L&F can't be used in applications that are still running Java 8. I've seen that you've set sourceCompatibility
to 11
, but is this actually necessary? If not, i think it'd be cool to allow usage of older Java versions as well.
Currently the popup of a JComboBox any PopupMenu doesn't show up when clicked.
Use ComboDemo.java to reproduce.
Hi, darklaf looks nice, and MIT is a great license choice (well, Apache-2.0 might be slightly less better), however, would you please add the relevant license to the resulting jar file?
For instance, https://repo1.maven.org/maven2/com/github/weisj/darklaf/1.3.3.4/ does not have license, so it would be a bit complicated for third-parties to comply with darklaf license.
I suggest that darklaf.jar should include at least LICENSE for darklaf itself
It looks like you include bits from IntelliJ platform (judging by NOTICE.txt). I guess that NOTICE.txt must be re-distributed with binary artifacts as well.
The suggested location is META-INF/LICENSE
and or META-INF/NOTICE
.
PS. Having a license in META-INF/LICENSE
would simplify license compliance for the projects that bundle darklaf
.
WARNING: Illegal reflective access by com.github.weisj.darklaf.DarkLaf (file:/Users/vladimirsitnikov/Documents/code/darklaf/core/build/classes/java/main/) to constructor com.apple.laf.AquaLookAndFeel()
at com.github.weisj.darklaf.DarkLaf.<init>(DarkLaf.java:69)
at java.base/java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:166)
at java.base/jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:404)
at java.base/java.lang.Class.newInstance(Class.java:591)
at java.desktop/javax.swing.UIManager.setLookAndFeel(UIManager.java:633)
at com.github.weisj.darklaf.LafManager.install(LafManager.java:172)
at ui.ComponentDemo.lambda$showDemo$0(ComponentDemo.java:41)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
:(
Ran DialogDemo with --illegal-access=deny
Got the following:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalAccessError: class com.github.weisj.darklaf.ui.text.DarkTextUI (in unnamed module @0x68ceda24) cannot access class sun.swing.DefaultLookup (in module java.desktop) because module java.desktop does not export sun.swing to unnamed module @0x68ceda24
at com.github.weisj.darklaf.ui.text.DarkTextUI.getInputMap(DarkTextUI.java:215)
at com.github.weisj.darklaf.ui.text.DarkTextUI.installKeyboardActions(DarkTextUI.java:175)
at java.desktop/javax.swing.plaf.basic.BasicTextUI.installUI(BasicTextUI.java:841)
at com.github.weisj.darklaf.ui.text.DarkTextUI.installUI(DarkTextUI.java:194)
at com.github.weisj.darklaf.ui.text.DarkFormattedTextFieldUI.installUI(DarkFormattedTextFieldUI.java:55)
at java.desktop/javax.swing.JComponent.setUI(JComponent.java:685)
at java.desktop/javax.swing.text.JTextComponent.setUI(JTextComponent.java:342)
at java.desktop/javax.swing.text.JTextComponent.updateUI(JTextComponent.java:352)
at java.desktop/javax.swing.text.JTextComponent.<init>(JTextComponent.java:326)
at java.desktop/javax.swing.JTextField.<init>(JTextField.java:230)
at java.desktop/javax.swing.JTextField.<init>(JTextField.java:171)
at java.desktop/javax.swing.JFormattedTextField.<init>(JFormattedTextField.java:293)
at java.desktop/javax.swing.JFormattedTextField.<init>(JFormattedTextField.java:306)
at ui.dialog.CustomDialog.<init>(CustomDialog.java:62)
at ui.dialog.DialogDemo.<init>(DialogDemo.java:57)
at ui.dialog.DialogDemo.createAndShowGUI(DialogDemo.java:402)
When a JComboBox is focused one should be able to scroll through the entries of the selection model using the arrow keys on the keyboard.
Button.defaultButtonFollowFocus = false
should be replaced with
Button.defaultButtonFollowsFocus = false
It seems to be a regression since 6e26765
if (comboBox.getComponentOrientation().isLeftToRight()) {
return new InsetsUIResource(boxPadding.top, boxPadding.left, boxPadding.bottom, borderSize); // <-- HERE
java.lang.NullPointerException: null
at com.github.weisj.darklaf.ui.combobox.DarkComboBoxUI.getBorderInsets(DarkComboBoxUI.java:398) ~[darklaf-core.jar:1.4.0.3-SNAPSHOT]
at javax.swing.JComponent.setBorder(JComponent.java:1799) ~[?:1.8.0_222]
at com.github.weisj.darklaf.ui.combobox.DarkComboBoxUI.installUI(DarkComboBoxUI.java:77) ~[darklaf-core.jar:1.4.0.3-SNAPSHOT]
at javax.swing.JComponent.setUI(JComponent.java:666) ~[?:1.8.0_222]
at javax.swing.JComboBox.setUI(JComboBox.java:257) ~[?:1.8.0_222]
at javax.swing.JComboBox.updateUI(JComboBox.java:266) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1238) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1229) ~[?:1.8.0_222]
at com.github.weisj.darklaf.LafManager.updateLafRecursively(LafManager.java:194) ~[darklaf-core.jar:1.4.0.3-SNAPSHOT]
at com.github.weisj.darklaf.LafManager.updateLafRecursively(LafManager.java:192) ~[darklaf-core.jar:1.4.0.3-SNAPSHOT]
at com.github.weisj.darklaf.LafManager.updateLaf(LafManager.java:186) ~[darklaf-core.jar:1.4.0.3-SNAPSHOT]
at com.github.weisj.darklaf.LafManager.install(LafManager.java:172) ~[darklaf-core.jar:1.4.0.3-SNAPSHOT]
at com.github.weisj.darklaf.LafManager.installTheme(LafManager.java:140) ~[darklaf-core.jar:1.4.0.3-SNAPSHOT]
at org.apache.jmeter.gui.action.LookAndFeelCommand.activateLookAndFeel(LookAndFeelCommand.java:204) ~[ApacheJMeter_core.jar:5.3-SNAPSHOT]
at org.apache.jmeter.gui.action.LookAndFeelCommand.doAction(LookAndFeelCommand.java:225) ~[ApacheJMeter_core.jar:5.3-SNAPSHOT]
at org.apache.jmeter.gui.action.ActionRouter.performAction(ActionRouter.java:87) ~[ApacheJMeter_core.jar:5.3-SNAPSHOT]
at org.apache.jmeter.gui.action.ActionRouter.lambda$actionPerformed$0(ActionRouter.java:69) ~[ApacheJMeter_core.jar:5.3-SNAPSHOT]
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311) [?:1.8.0_222]
The width of the selection highlight isn't correctly calculated.
The width should span the width of the whole container and not just the width of the text in one line.
See TextDemo.java or
TabFrameDemo.java to reproduce.
I just git-pulled and ran gradlew tasks
and instantly ran into errors. While quickly stripping the build file of the problematic parts wasn't a problem, this should be solvable in a less dumb way than I did :D
I don't know too much about gradle though, therefore I can't provide any insight.
[2020-02-18 11:38:21] [SEVERE] java.lang.NullPointerException: inStream parameter is null [at com.github.weisj.darklaf.DarkLaf]
[Details] java.base/java.util.Objects.requireNonNull(Objects.java:246),
java.base/java.util.Properties.load(Properties.java:403),
com.github.weisj.darklaf.util.PropertyLoader.loadProperties(PropertyLoader.java:78),
com.github.weisj.darklaf.theme.Theme.loadDecorationProperties(Theme.java:149),
com.github.weisj.darklaf.DarkLaf.loadThemeDefaults(DarkLaf.java:170),
com.github.weisj.darklaf.DarkLaf.getDefaults(DarkLaf.java:88),
java.desktop/javax.swing.UIManager.setLookAndFeel(UIManager.java:587),
java.desktop/javax.swing.UIManager.setLookAndFeel(UIManager.java:633),
com.github.weisj.darklaf.LafManager.install(LafManager.java:166),
DarklafDemo.lambda$main$0(DarklafDemo.java:9),
java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313),
java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770),
java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721),
java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715),
java.base/java.security.AccessController.doPrivileged(AccessController.java:389),
java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85),
java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740),
java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203),
java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124),
java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113),
java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109),
java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101),
java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at com.github.weisj.darklaf.ui.button.DarkButtonBorder.getBorderInsets(DarkButtonBorder.java:178)
at java.desktop/javax.swing.JComponent.getInsets(JComponent.java:1840)
at java.desktop/javax.swing.plaf.basic.BasicGraphicsUtils.getPreferredButtonSize(BasicGraphicsUtils.java:370)
at java.desktop/com.apple.laf.AquaButtonUI.getPreferredSize(AquaButtonUI.java:443)
at java.desktop/javax.swing.JComponent.getPreferredSize(JComponent.java:1680)
at java.desktop/java.awt.FlowLayout.layoutContainer(FlowLayout.java:609)
at java.desktop/java.awt.Container.layout(Container.java:1537)
at java.desktop/java.awt.Container.doLayout(Container.java:1526)
at java.desktop/java.awt.Container.validateTree(Container.java:1722)
at java.desktop/java.awt.Container.validateTree(Container.java:1731)
at java.desktop/java.awt.Container.validateTree(Container.java:1731)
at java.desktop/java.awt.Container.validateTree(Container.java:1731)
at java.desktop/java.awt.Container.validate(Container.java:1657)
at java.desktop/java.awt.Container.validateUnconditionally(Container.java:1694)
at java.desktop/java.awt.Window.show(Window.java:1040)
at java.desktop/java.awt.Component.show(Component.java:1716)
at java.desktop/java.awt.Component.setVisible(Component.java:1663)
at java.desktop/java.awt.Window.setVisible(Window.java:1021)
at DarklafDemo.lambda$main$0(DarklafDemo.java:22)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:389)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at com.github.weisj.darklaf.ui.button.DarkButtonBorder.getBorderInsets(DarkButtonBorder.java:178)
at java.desktop/javax.swing.JComponent.getInsets(JComponent.java:1840)
at java.desktop/javax.swing.plaf.basic.BasicGraphicsUtils.getPreferredButtonSize(BasicGraphicsUtils.java:370)
at java.desktop/com.apple.laf.AquaButtonUI.getPreferredSize(AquaButtonUI.java:443)
at java.desktop/javax.swing.JComponent.getPreferredSize(JComponent.java:1680)
at java.desktop/java.awt.FlowLayout.layoutContainer(FlowLayout.java:609)
at java.desktop/java.awt.Container.layout(Container.java:1537)
at java.desktop/java.awt.Container.doLayout(Container.java:1526)
at java.desktop/java.awt.Container.validateTree(Container.java:1722)
at java.desktop/java.awt.Container.validateTree(Container.java:1731)
at java.desktop/java.awt.Container.validateTree(Container.java:1731)
at java.desktop/java.awt.Container.validateTree(Container.java:1731)
at java.desktop/java.awt.Container.validate(Container.java:1657)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2760)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4840)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:389)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:389)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
To allow theming of all icons could be replaced with their "patched"(see here) counterpart i.e. an icon which the colours are being applied to at runtime.
Advantages:
Possible negatives:
Feedback would be greatly appreciated.
It looks like each release adds +3 megabytes to the repository (e.g. bin/
folder), so it might be hard to clone very soon :-(
JTextPane uses the wrong selection text color.
When the window is maximized it is too big when custom decorations are enabled. This is due to windows including the removed border insets.
Sent from PPHub
darklaf-core-1.4.0.3.jar, Java 1.8
if (val instanceof DefaultMutableTreeNode) {
val = ((DefaultMutableTreeNode) val).getUserObject();
}
if (!(val instanceof Boolean)) {
String str = val.toString(); <-- NPE here
Caused by: java.lang.NullPointerException
at com.github.weisj.darklaf.ui.tree.DarkTreeCellRenderer.unwrapBooleanIfPossible(DarkTreeCellRenderer.java:74) ~[darklaf-core-1.4.0.3.jar:1.4.0.3]
at com.github.weisj.darklaf.ui.tree.DarkTreeCellRenderer.getTreeCellRendererComponent(DarkTreeCellRenderer.java:49) ~[darklaf-core-1.4.0.3.jar:1.4.0.3]
at javax.swing.plaf.basic.BasicTreeUI$NodeDimensionsHandler.getNodeDimensions(BasicTreeUI.java:2807) ~[?:1.8.0_222]
at javax.swing.tree.AbstractLayoutCache.getNodeDimensions(AbstractLayoutCache.java:492) ~[?:1.8.0_222]
at javax.swing.tree.VariableHeightLayoutCache$TreeStateNode.updatePreferredSize(VariableHeightLayoutCache.java:1360) ~[?:1.8.0_222]
at javax.swing.tree.VariableHeightLayoutCache.rebuild(VariableHeightLayoutCache.java:738) ~[?:1.8.0_222]
at javax.swing.tree.VariableHeightLayoutCache.setModel(VariableHeightLayoutCache.java:109) ~[?:1.8.0_222]
at javax.swing.plaf.basic.BasicTreeUI.setModel(BasicTreeUI.java:412) ~[?:1.8.0_222]
at javax.swing.plaf.basic.BasicTreeUI$Handler.propertyChange(BasicTreeUI.java:3414) ~[?:1.8.0_222]
at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335) ~[?:1.8.0_222]
at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:327) ~[?:1.8.0_222]
at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:263) ~[?:1.8.0_222]
at java.awt.Component.firePropertyChange(Component.java:8434) ~[?:1.8.0_222]
at javax.swing.JTree.setModel(JTree.java:885) ~[?:1.8.0_222]
at javax.swing.JTree.<init>(JTree.java:673) ~[?:1.8.0_222]
Gradle can generate the full pom, so there's probably not much help from the file stored in the repository.
The current pom.xml
duplicates the list of dependencies, so it might go off rails :-/
Hello!
As I see the L&F defines pair disabledBackground/inactiveBackground color for most UI controls.
Unfortunately, in my examples background color never changes for readonly (editable=false) or disabled elements. Is it a bug or expected behavior?
E.g. see draft code below
LafManager.install();
System.out.println("TextField.inactiveBackground="+UIManager.getColor("TextField.inactiveBackground"));
System.out.println("TextField.disabledBackground="+UIManager.getColor("TextField.disabledBackground"));
String text = "";
int columns = 20;
JTextField textField = new JTextField(text, columns);
JTextField textField1 = new JTextField(text, columns);
textField1.setEditable(false);
// textField1.setBackground(UIManager.getColor("TextField.inactiveBackground"));
JTextField textField2 = new JTextField(text, columns);
textField2.setEnabled(false);
// textField2.setBackground(UIManager.getColor("TextField.disabledBackground"));
I just saw that you changed the maven coordinates in the README in commit 95b1f93 to include version ranges. This is bad practice as the build isn't reproducible anymore. I therefore advise to revert this change and specify an explicit version.
I have tried to apply darklaf to Apache JMeter, and below are some samples.
The issue I have is checkboxes and radioboxes can not be flipped by clicking on the relevant labels.
For instance, here's the code that creates radio buttons:
https://github.com/apache/jmeter/blob/b6d11d79d905d0c099732bb928d2372fd1388981/src/components/src/main/java/org/apache/jmeter/sampler/gui/TestActionGui.java#L210
With other LaFs (e.g. Darcula) I can click on labels like Infinite
, Continue
, Stop Test
, and they alter the checkboxes.
PS. I can't build darklaf as it fails with windows.h
not found (I use macOS)
Apache JMeter with bulenkov/darcula:
Apache JMeter with weisJ/darflaf/darcula (it is strange the menu is not moved to Apple's menu):
Sample: https://recordit.co/2JXoSkG7zg
According to the stracktrace, its due to calling toString
in DarkTreeCellRenderer.unwrapBooleanIfPossible
so I think its a case of an unhandled state. This is an assumption due to DefaultMutableTreeNode
's userObject
being null by default.
Tested with 1.3.3.6 on Java 8.
public class Main {
public static void main(String[] args) {
LafManager.install();
JFrame frame = new JFrame("Testing");
frame.setLayout(new BorderLayout());
JTree tree = new JTree();
frame.add(tree, BorderLayout.CENTER);
JButton button = new JButton("Run");
button.addActionListener(e -> {
tree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode()));
});
frame.add(button, BorderLayout.NORTH);
frame.setVisible(true);
}
}
Currently darklaf
bundles the dependencies to the jar (e.g. darklaf-1.3.3.4.jar
), however, its pom.xml
still has the dependencies:
+--- com.github.weisj:darklaf -> 1.3.3.4
| +--- com.metsci.ext.com.kitfox.svg:svg-salamander:0.1.19
| +--- net.java.dev.jna:jna:4.1.0
| \--- org.swinglabs:jxlayer:3.0.4
It looks that it is not consistent.
It would be great if
a) darklaf
could either avoid shading the dependencies (e.g. to allow other projects to pick versions and avoid class duplication)
b) shade the dependencies (+repackage), and exclude the dependencies from POM file.
It would probably make sense to do both: publish shaded and non-shaded jars at the same time (e.g. under different artifactId or classifier).
Note: it would probably make sense to use Gradle's configurations to clarify which dependencies are included to the jar, and which are not (e.g. https://github.com/apache/calcite-avatica/blob/63525d7c772e3ef3db0747ef38f2f59ccdd9dbf6/standalone-server/build.gradle.kts#L90 )
Thanks for the LaF.
AFAIK, the up to date Darcula is located in IDEA's repository: https://github.com/JetBrains/intellij-community/tree/1bc324ce785de1917f3ad0e0f99ceb4bf895105a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula
Can you please clarify if darklaf
builds upon that version or not?
You have a few themes (dark, light etc.) They are almost OK for me, except for one tiny thing - default border thickness. I would like to change it globally (for all controls and for all themes) from 3 to 1.
Is it possible without creating own themes etc.?
My workaround is to redefine it for each control before calling LafManager. But I've to determine and list all controls here. Possible you already have a solution for my and similar cases?
UIManager.put("TextField.borderThickness", 1);
...
LafManager.install();
I've seen the folder bin/
and think that binaries shouldn't be part of the source repo. You've already released 1.3.1.2 on Maven Central, however, there's currently no tag for that version in the git repository. It'd be good to keep these two consistent, the maven versions and the git tags. This will avoid confusion to whether a version is really what it seems to be.
If a JTabbedPane uses an extra component for displaying the tab information during a DnD operation the component may not be properly hidden.
Also the component for a different tab may dissapear.
See TabbedPaneDemo.java to reproduce.
Now that core is in it's own module no darklaf jar gets published anymore. I renamed the artefact reference in the readme to darklaf-core. Preferably there should probably be a darklaf artefact available to avoid confusion. Any opinions?
Here's a video (see the border around "comments" field): https://recordit.co/3J82f5WGFm
The code is
JTextArea commentField = new JTextArea();
// JTextArea does not have border by default (see https://bugs.openjdk.java.net/browse/JDK-4139076)
// However we want it to look like a text field. So we borrow a border from there
Border border = new JTextField().getBorder();
commentField.setBorder(border);
java.lang.NullPointerException: null
at javax.swing.ScrollPaneLayout.addSingletonComponent(ScrollPaneLayout.java:202) ~[?:1.8.0_222]
at javax.swing.ScrollPaneLayout.addLayoutComponent(ScrollPaneLayout.java:254) ~[?:1.8.0_222]
at com.github.weisj.darklaf.ui.scrollpane.ScrollLayoutManagerDelegate.addLayoutComponent(ScrollLayoutManagerDelegate.java:49) ~[darklaf-core.jar:1.4.0.3-SNAPSHOT]
at java.awt.Container.addImpl(Container.java:1132) ~[?:1.8.0_222]
at java.awt.Container.add(Container.java:975) ~[?:1.8.0_222]
at javax.swing.JScrollPane.setCorner(JScrollPane.java:1267) ~[?:1.8.0_222]
at javax.swing.JTable.configureEnclosingScrollPaneUI(JTable.java:792) ~[?:1.8.0_222]
at javax.swing.JTable.updateUI(JTable.java:3649) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1238) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253) ~[?:1.8.0_222]
at javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1229) ~[?:1.8.0_222]
at com.github.weisj.darklaf.LafManager.updateLafRecursively(LafManager.java:194) ~[darklaf-core.jar:1.4.0.3-SNAPSHOT]
at com.github.weisj.darklaf.LafManager.updateLaf(LafManager.java:186) ~[darklaf-core.jar:1.4.0.3-SNAPSHOT]
at com.github.weisj.darklaf.LafManager.install(LafManager.java:172) ~[darklaf-core.jar:1.4.0.3-SNAPSHOT]
at com.github.weisj.darklaf.LafManager.installTheme(LafManager.java:140) ~[darklaf-core.jar:1.4.0.3-SNAPSHOT]
at org.apache.jmeter.gui.action.LookAndFeelCommand.activateLookAndFeel(LookAndFeelCommand.java:204) ~[ApacheJMeter_core.jar:5.3-SNAPSHOT]
at org.apache.jmeter.gui.action.LookAndFeelCommand.doAction(LookAndFeelCommand.java:225) ~[ApacheJMeter_core.jar:5.3-SNAPSHOT]
at org.apache.jmeter.gui.action.ActionRouter.performAction(ActionRouter.java:87) ~[ApacheJMeter_core.jar:5.3-SNAPSHOT]
at org.apache.jmeter.gui.action.ActionRouter.lambda$actionPerformed$0(ActionRouter.java:69) ~[ApacheJMeter_core.jar:5.3-SNAPSHOT]
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311) [?:1.8.0_222]
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758) [?:1.8.0_222]
at java.awt.EventQueue.access$500(EventQueue.java:97) [?:1.8.0_222]
at java.awt.EventQueue$3.run(EventQueue.java:709) [?:1.8.0_222]
at java.awt.EventQueue$3.run(EventQueue.java:703) [?:1.8.0_222]
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_222]
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74) [?:1.8.0_222]
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728) [?:1.8.0_222]
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205) [?:1.8.0_222]
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) [?:1.8.0_222]
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) [?:1.8.0_222]
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) [?:1.8.0_222]
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) [?:1.8.0_222]
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82) [?:1.8.0_222]
The button is large :(
It looks like it is worth reducing insets in com.github.weisj.darklaf.ui.combobox.DarkComboBoxUI#getInsets
It looks like the drop-down icon has the same color as the background, so the control is hard to distinguish from an edit field.
When combo is open, the rows are much thinner than the combo itself.
When trying to use this LaF for my application I always get this exception on start and all Widgets are invisible. When nagivating to the next widget with "Tab" that widget that now has the focus gets drawn.
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: URI is not hierarchical
at java.io.File.<init>(File.java:418)
at com.github.weisj.darklaf.icons.DarkSVGIcon.ensureLoaded(DarkSVGIcon.java:93)
at com.github.weisj.darklaf.icons.DarkSVGIcon.getSVGIcon(DarkSVGIcon.java:134)
at com.github.weisj.darklaf.icons.ThemedSVGIcon.ensureTheme(ThemedSVGIcon.java:53)
at com.github.weisj.darklaf.icons.ThemedSVGIcon.paintIcon(ThemedSVGIcon.java:46)
at com.github.weisj.darklaf.components.ArrowButton$1.paintTriangle(ArrowButton.java:103)
at com.github.weisj.darklaf.components.ArrowButton$1.paint(ArrowButton.java:83)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5210)
at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:290)
at javax.swing.RepaintManager.paint(RepaintManager.java:1272)
at javax.swing.JComponent._paintImmediately(JComponent.java:5158)
at javax.swing.JComponent.paintImmediately(JComponent.java:4969)
at javax.swing.RepaintManager$4.run(RepaintManager.java:854)
at javax.swing.RepaintManager$4.run(RepaintManager.java:814)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
at javax.swing.RepaintManager.access$1200(RepaintManager.java:64)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
That happens in all cases I tried with, e.g.:
com.github.weisj.darklaf.LafManager.install();
com.github.weisj.darklaf.LafManager.setTheme(new com.github.weisj.darklaf.theme.SolarizedLightTheme());
UIManager.setLookAndFeel(new com.github.weisj.darklaf.DarkLaf())
com.github.weisj.darklaf.LafManager.setTheme(new com.github.weisj.darklaf.theme.SolarizedLightTheme());
UIManager.setLookAndFeel(com.github.weisj.darklaf.DarkLaf.class.getCanonicalName())
Version 1.3.3.6
Either selected through JTextField .selectAll()
method or manually selected text keep selected after JTextField lost focus. The only way I found to unselect focus it to add a listener to JTextField with JTextField..setCaretPosition(0)
on focustLost event.
Is it a bug or expected behavior?
class TextFieldExample {
public static void main(String args[]) {
LafManager.install();
JFrame f = new JFrame("TextField Example");
JTextField t1, t2;
t1 = new JTextField("Selected Text");
t1.setBounds(50, 100, 200, 30);
t1.selectAll();
t2 = new JTextField("Unselected text");
t2.setBounds(50, 150, 200, 30);
f.add(t1);
f.add(t2);
f.setSize(400, 400);
f.setLayout(null);
f.setVisible(true);
}
}
Add a custom component that extends JSlider
and makes use of the volume visual, offering the option to show/hide the volume icon.
When trying to compile with gradlew shadowJar
, it fails at linking the shared libraries.
Console output:
PS D:\repos\darklaf> ./gradlew shadowJar
> Configure project :
Building on OS: Windows 10
Using JDK: C:\Users\msc\scoop\apps\ojdkbuild8-full\current\jre
Copying libraries
> Task :linkJniplatformX64SharedLibrary FAILED
g++.exe: error: dwmapi.lib: No such file or directory
g++.exe: error: user32.lib: No such file or directory
g++.exe: error: Gdi32.lib: No such file or directory
> Task :linkJniplatformX86SharedLibrary FAILED
g++.exe: error: dwmapi.lib: No such file or directory
g++.exe: error: user32.lib: No such file or directory
g++.exe: error: Gdi32.lib: No such file or directory
FAILURE: Build completed with 2 failures.
1: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':linkJniplatformX64SharedLibrary'.
> A build operation failed.
Linker failed while linking jniplatform.dll.
See the complete log at: file:///D:/repos/darklaf/build/tmp/linkJniplatformX64SharedLibrary/output.txt
> Linker failed while linking jniplatform.dll.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
==============================================================================
2: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':linkJniplatformX86SharedLibrary'.
> A build operation failed.
Linker failed while linking jniplatform.dll.
See the complete log at: file:///D:/repos/darklaf/build/tmp/linkJniplatformX86SharedLibrary/output.txt
> Linker failed while linking jniplatform.dll.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
==============================================================================
* Get more help at https://help.gradle.org
BUILD FAILED in 1s
4 actionable tasks: 2 executed, 2 up-to-date
The full logfile doesn't provide any additional information. I am not sure why it can't find those files. I am on a 64-Bit system. I tried running this with and without administrative permissions. Am I missing anything? I am using gcc version 8.1.0.0 and openjdk 8.
I assume it'd be great to have dependencies and necessary steps, that are needed in order to build a usable jar, are documented somewhere.
Currently only windows is fully supported. Without having access specifically to a macOS machine the finer details need to be adjusted for each platform.
Specifically custom window decorations currently are only tailored to suit the windows platform.
The plan is to provide custom decorations for most of the major platforms.
Sent from PPHub
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.