I have a standalone Swing application and I'm using Groovy as programing language.
Trying to apply styles using CSS and searching for some tool for this purpose, I've found CSSBuilder.
The problem is that CSSBuilder comes integrated with Griffon framework, so I cannot use all of its features isolated from Griffon, such as 'cssClass' selector.
Therefore my question is simply: has anyone managed to do something like this?
Just wrote a quick test, and this seems to work:
#GrabResolver( name='codehaus', root='http://repository.codehaus.org' )
#Grab( 'org.codehaus.griffon:cssbuilder:0.4' )
import griffon.builder.css.*
import groovy.swing.SwingBuilder
import java.awt.BorderLayout as BL
def style = '''* {
background-color: red;
}
jbutton {
background-color: blue;
}
.active {
color: green ;
font-size: 50%;
}
jlabel {
color: pink ;
font-size: 200% ;
}'''
Class klass = javax.swing.JComponent
if( !AbstractSyntheticMetaMethods.hasBeenEnhanced(klass) ) {
AbstractSyntheticMetaMethods.enhance(klass,[
"getCssClass": {-> delegate.getClientProperty(ClarityConstants.CLIENT_PROPERTY_CLASS_KEY) },
"setCssClass": { String cssClass -> delegate.putClientProperty(ClarityConstants.CLIENT_PROPERTY_CLASS_KEY, cssClass) }
])
}
new SwingBuilder().edt {
int count = 0
def frame = frame( title:'CSS Test', size:[ 300, 300 ], show: true ) {
borderLayout()
textlabel = label(text:"Click the button!", constraints: BL.NORTH)
button(text:'Click Me',
cssClass: 'active',
actionPerformed: {count++; textlabel.text = "Clicked ${count} time(s)."; println "clicked"},
constraints:BL.SOUTH)
}
CSSDecorator.applyStyle( style, frame )
}
The meta-class enhancing code I took from the source of CSSBuilder
Related
I'm using FullCalendar in angular and I would like to change the specific day grid background I have tried some options but it didn't work.
HTML
<full-calendar #calendar [options]="calendarOptions"></full-calendar>
TS
export class CalendarComponent implements OnInit{
calendarData: CalendarData[] = [];
calendarVisible = false;
calendarOptions: CalendarOptions = {
headerToolbar: {
right: 'title,prev,next',
center: '',
left: 'timeGridDay,timeGridWeek,dayGridMonth'
},
initialView: 'dayGridMonth',
eventColor: '#F4C584',
};
#ViewChild('calendar') calendarComponent!: FullCalendarComponent;
isData = false;
calendarPlugins = [listPlugin,dayGridPlugin,timeGridPlugin]
getCalendar(): void{
this.calendarService.getCalendar(2022).subscribe((res) => {
this.calendarOptions.events = [];
const data = Object.entries(res.data).map((val: any) => {
return val;
});
for(let i = 0; i < data.length; i++){
console.log(data[i][0]);
for(let j = 0; j < data[i][1].length; j++){
this.calendarOptions.events.push( //here I'm pushing into event options array my data
{
title : data[i][1][j].date.split(' ')[0],
date: data[i][0]
background: '#000000' //I tried to give a color like this but it didn't work
});
}
}
});
}
link to the full calendar
Had the same problem and I discovered that FullCalendar styles for Angular just work after the page is rendered, meaning, if you apply the style into your styles.scss it will work :)
For example, i did this:
.fc .fc-daygrid-day.fc-day-today {
background-color: rgb(229, 248, 225, 0.5) !important;
}
Hope that it helps :)
If you use bootstrap in your project, then u must use ": host ::ng-deep" before the property u want to modify in the CSS file. This works I have applied it.
e.g. :- : host:: ng-deep color: '#ffffff'
I am still learning and playing with fp-ts and can't figure this out.
I have an array of Either<any, number>[] and I would like to get an Either<any, number[]>.
I have looked at Apply.sequenceT and the example sequenceToOption and it looks close.
import { NumberFromString } from 'io-ts-types/lib/NumberFromString'
import { Either } from 'fp-ts/lib/Either'
const a:Either<any,number>[] = ['1','2','3'].map(NumberFromString.decode)
console.log(a)
// [ { _tag: 'Right', right: 1 },
// { _tag: 'Right', right: 2 },
// { _tag: 'Right', right: 3 } ]
I want instead either an error or array of numbers.
To go from Array<Either<L, A>> to Either<L, Array<A>> you can use sequence:
import { array } from 'fp-ts/lib/Array'
import { either } from 'fp-ts/lib/Either'
array.sequence(either)(arrayOfEithers)
Your example can also be further simplified using traverse
array.traverse(either)(['1','2','3'], NumberFromString.decode)
If you are already using io-ts I would recommend adding your array to the decoder like so:
import { NumberFromString } from 'io-ts-types/lib/NumberFromString'
import * as t from 'io-ts'
const { decode } = t.array(NumberFromString)
const resultA = decode(['1','2','3']);
const resultB = decode(['1','2','junk']);
console.log(resultA) // { _tag: 'Right', right: [1, 2, 3] }
console.log(resultB) // { _tag: 'Left', left: <ERRORS> }
Otherwise the answer from Giovanni should be fine.
I'm looking to add a react element with H.ui.Control. Is this possible? and how might it be done?
// sudo code of what I did
componentDidMount() {
...
let button = new H.ui.Control(this.myButtonControl);
button.setPosition('top-left');
this._ui.addControl('button-control', button);
...
}
myButtonControl() {
return <button className="H_btn">Hello World</button>
}
A new <div class="H_ctl"></div>, appears where the control was suppose to be, but not the button.
While it's not exactly what I wanted to do, I did find a solution. I created a generic class that extends H.ui.Control, in this case ButtonGroupControl.
class ButtonGroupControl extends H.ui.Control {
constructor(buttons: []) {
super();
this._buttons = buttons;
this.addClass('H_grp');
}
renderInternal(el, doc) {
this._buttons.forEach((button, i) => {
let btn = doc.createElement('button');
btn.className = 'H_btn';
btn.innerText = this._buttons[i].label;
btn.onclick = this._buttons[i].callback;
el.appendChild(btn);
})
super.renderInternal(el, doc);
}
}
export default ButtonGroupControl;
Then, inside my map component, I created passed array of items into the control, like so:
const mapToolsControl: ButtonGroupControl = new ButtonGroupControl([
{
label: 'Add Field',
callback: () => {
console.log('callback: adding field');
}
},
{
label: 'Remove Field',
callback: () => {
console.log('callback: remove field');
}
}
]);
Lastly, I added the control to the map like:
this._map.addControl('map-tools-control', mapToolsControl);
This results in the following (it's a link because I don't have enough points to embed yet):
Screenshot of Result
Here is what i have done (adding two buttons to the map)
var U_I = new H.ui.UI(map);
var container = new H.ui.Control();
container.addClass('here-ctrl here-ctrl-group');
var button = new H.ui.base.Element('button', 'here-ctrl-icon map_control');
container.addChild(button);
button.addEventListener('click', function() { alert(1); });
var button = new H.ui.base.Element('button', 'here-ctrl-icon map_center');
container.addChild(button);
button.addEventListener('click', function() { alert(2); });
container.setAlignment('top-right');
U_I.addControl('myControls', container );
U_I.addControl('ScaleBar', new H.ui.ScaleBar() );
the rendering is made by css (here is an extract)
button.here-ctrl-icon {
width: 25px;
height: 25px;
margin: 2px 0 0 2px;
}
.map_control { background: url("images/map_control.png") no-repeat scroll 0 0 transparent; }
.map_center { background: url("images/map_center.png") no-repeat scroll 0 0 transparent; }
H.ui.base.Button(); is not working ... it creates a div
It is not possible to add attributes to button such as alt or title thru the api.
I still have to deal with the addEventListener ... (not working !)
the result :
my new nice controls
I'm using Codekit 2.1.8 to compile my LESS files. In my LESS files I have empty lines and I want to have them in compilied CSS file too, but Codekit seems to delete them. I can't find any options in Codekit related to this issue.
Example:
LESS file:
p {
font-size: 14px;
}
a {
color: red;
}
Compilied CSS file with Codekit:
p {
font-size: 14px;
}
a {
color: red;
}
When using the default command line or client side you can easily add your own plugins since v2. Less preserves /**/ comments.
Add in your LESS code for instance /*3*/ for 3 newlines.
Now write the plugin, call this file less-plugin-add-newlines.js:
var getCommentsProcessor = require("./comments-processor");
module.exports = {
install: function(less, pluginManager) {
var CommentsProcessor = getCommentsProcessor(less);
pluginManager.addPostProcessor(new CommentsProcessor());
}
};
Than write the comments-processor.js:
String.prototype.repeat = function( num )
{
return new Array( num + 1 ).join( this );
}
module.exports = function(less) {
function CommentProcessor(options) {
this.options = options || {};
};
CommentProcessor.prototype = {
process: function (css) {
var r = new RegExp("(\\/\\*)([0-9]+)(\\*\\/)","g");
return css.replace(r,function(m1,m2,m3){ return "\n".repeat(m3*1-1); });
}
};
return CommentProcessor;
};
less
p1 {
p:3;
}
/*3*/
p2 {
p:3;
}
/*4*/
p2 {
p:3;
}
The preceding will compile into when running lessc --plugin=less-plugin-add-newlines.js index.less:
p1 {
p: 3;
}
p2 {
p: 3;
}
p2 {
p: 3;
}
I am trying to test this code but I am encountering problems. I have netbeans with default JavaFX platform.
This example is from this web site: http://onjava.com/pub/a/onjava/2007/07/27/introduction-to-javafx-script.html?page=4
package captureexample1;
import java.io.*;
import javafx.ui.*;
import javafx.ui.canvas.*;
import javafx.ui.filter.*;
import java.awt.Robot;
import java.awt.Rectangle;
import java.awt.image.RenderedImage;
import javax.imageio.ImageIO;
import java.lang.System;
class CaptureExample extends CompositeNode{
attribute lx: Integer;
attribute ly: Integer;
operation CaptureExample();
}
attribute CaptureExample.lx = 0;
attribute CaptureExample.ly = 0;
operation saveCapture(lx_copy:Integer, ly_copy:Integer) {
var robot = new Robot();
var rect = new Rectangle (lx_copy, ly_copy, 50, 50);
var BI=robot.createScreenCapture(rect);
var file = new File(".//capture.jpg");
ImageIO.write((RenderedImage)BI, "jpg", file);
}
function CaptureExample.composeNode() =
Group{
transform: []
content:[ImageView {
transform: []
image: Image { url: ".//app//Sunset.gif" }
cursor: DEFAULT
onMouseClicked: operation(e:CanvasMouseEvent) {
saveCapture(e.source.XOnScreen,e.source.YOnScreen);
}
onMouseMoved: operation(e:CanvasMouseEvent) {
lx = e.x;
ly = e.y;
}
},
Rect{
x: bind lx
y: bind ly
width: 50
height:50
strokeWidth: 1
stroke: black
}]
};
Frame {
centerOnScreen: true
visible: true
height: 230
width: 300
title: "Capture the screen..."
onClose: operation() {System.exit(0);}
content: ScrollPane {
background: white
view: Canvas {
background: black
cursor: DEFAULT
content: CaptureExample
}
}
}
It seems you are mixing JavaFX script and JavaFX2.
JavaFX script (aka JavaFX 1.3) is obsolete, not supported and old.
modern JavaFX 2 uses Java as language instead of FX script. You can see examples here: http://docs.oracle.com/javafx/2/get_started/jfxpub-get_started.htm
If you really want to use JavaFX 1.3:
get older NetBeans, like 6.1
rename you .java file to .fx
But if you just trying to learn JavaFX I really advise you to try JavaFX 2.