Can't get output to not be null - swing

I'm trying to make a really simple text input field (to replicate later for a more complex purpose). Using IDEA 14 CE, not sure it matters. I wrote this code:
import groovy.swing.SwingBuilder
import groovy.beans.Bindable
import static javax.swing.JFrame.EXIT_ON_CLOSE
import java.awt.*
String word
#Bindable
class UserInput {
String word
//String toString() { "$word" }
}
def userInput = new UserInput(word: null)
def swingBuilder = new SwingBuilder()
swingBuilder.edt {
lookAndFeel 'nimbus'
// frame size
def width = 350
def height = 230
frame (
title: 'Input',
size: [width, height],
show: true,
locationRelativeTo: null,
defaultCloseOperation: EXIT_ON_CLOSE ) {
borderLayout(vgap: 5)
panel(constraints:
BorderLayout.CENTER,
border: compoundBorder([emptyBorder(10), titledBorder('Input:')]))
{
tableLayout {
tr {
td { label 'Input: ' }
td { textField userInput.word, id: userInput.word, columns: 20 }
}
}
}
panel(constraints: BorderLayout.SOUTH) {
button text: 'Print word', actionPerformed: {
println """Word: ${userInput.word}"""
}
}
}
}
When I run it, I get this Swing box:
No matter what I input, when I click Print Word it always prints:
Word: null
What am I doing wrong? Seems like I am failing to assign user input to a parameter or something like that, but I cannot figure it out.

Right, you need to use bean binding to get the text property of the textField bound to your model. This works:
import groovy.swing.SwingBuilder
import groovy.beans.Bindable
import static javax.swing.JFrame.EXIT_ON_CLOSE
import java.awt.*
String word
#Bindable
class UserInput {
String word
}
def userInput = new UserInput(word: null)
def swingBuilder = new SwingBuilder().edt {
lookAndFeel 'nimbus'
// frame size
def width = 350
def height = 230
frame (title: 'Input',
size: [width, height],
show: true,
locationRelativeTo: null ) {
borderLayout(vgap: 5)
panel(constraints: BorderLayout.CENTER,
border: compoundBorder([emptyBorder(10), titledBorder('Input:')])) {
tableLayout {
tr {
td { label 'Input: ' }
td { textField id:'input', columns: 20 }
}
}
}
panel(constraints: BorderLayout.SOUTH) {
button text: 'Print word', actionPerformed: {
println """Word: ${userInput.word}"""
}
}
// Bind the text field to the bean
bean userInput, word: bind { input.text }
}
}

Related

How to validation a url inside a quill editor link

I am using a quill editor with my angular8 project. On the same there is an option to add url with the help of 'link'. Could I know, is there any way to validate the url which I will enter for the 'link' textbox as shown images below. Following are my codes
quill editor module
editorConfig= {
formula: true,
toolbar: [
[{ header: [1, 2, false] }],
['bold', 'italic', 'underline'],
['link']
]
};
html
<quill-editor [modules]="editorConfig" [style]="{height: '200px'}"></quill-editor>
How to validate links inside the textbox which is marked on the image above.
Yeah I find a way to resolve this question
First we need two function to override the default link handler and the function of snowtooltip save
import Emitter from 'quill/core/emitter';
import { message } from 'antd';
/**
* override Snow tooltip save
*/
export function SnowTooltipSave() {
const { value } = this.textbox;
const linkValidityRegex = /^(http|https)/;
switch (this.root.getAttribute('data-mode')) {
case 'link': {
if (!linkValidityRegex.test(value)) {
message.error('链接格式错误,请输入链接 http(s)://...');
return;
}
const { scrollTop } = this.quill.root;
if (this.linkRange) {
this.quill.formatText(this.linkRange, 'link', value, Emitter.sources.USER);
delete this.linkRange;
} else {
this.restoreFocus();
this.quill.format('link', value, Emitter.sources.USER);
}
this.quill.root.scrollTop = scrollTop;
break;
}
default:
}
this.textbox.value = '';
this.hide();
}
export function SnowThemeLinkHandler(value) {
if (value) {
const range = this.quill.getSelection();
if (range == null || range.length === 0) return;
let preview = this.quill.getText(range);
if (/^\S+#\S+\.\S+$/.test(preview) && preview.indexOf('mailto:') !== 0) {
preview = `mailto:${preview}`;
}
const { tooltip } = this.quill.theme;
tooltip.save = DtysSnowTooltipSave;
tooltip.edit('link', preview);
} else {
this.quill.format('link', false);
}
}
then use these function in editor
const SnowTheme = Quill.import('themes/snow');
SnowTheme.DEFAULTS.modules.toolbar.handlers.link = SnowThemeLinkHandler;

Java Key Bindings using Groovy Swing Builder

I am trying to write in Groovy application, using "Calculator like" keys functionality. So I would like swing action to be invoked, when I:
press JButton
press corresponding keyboard key, no matther whether there is focus on JButton or not.
Probably the best solution is to use Java Key Bindings, as described here:
https://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html
Following combination of Groovy and Java seems to work well:
package packageSwingTest4
import groovy.swing.SwingBuilder
import javax.swing.*
import java.awt.*
import javax.swing.WindowConstants as WC
class SwingTest4 {
def static b
static void main(args) {
def swing = new SwingBuilder()
def f2Action = swing.action(name:"F2", shortDescription:"F2 button", accelerator:"F2") {
println "F2 pressed"
}
swing.edt {
def f=frame(title: 'Keborad Binding test', size:[400,300],defaultCloseOperation: JFrame.EXIT_ON_CLOSE, show: true) {
panel {
b = button(text: 'F2', actionPerformed:{println "FFFF2222 pressed"})
b.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("F2"),"F2 pressed")
b.getActionMap().put("F2 pressed",f2Action)
}
}
}
}
}
But I do not like to combine Groovy/Java in this way, namely as I will:
- loose nice structure of Groovy code related to structure of GUI
- I have to define Actions separately and not "nicely" as in case of Groovy swing builder
Do you know about "cleaner" solution of my problem using pure Groovy/ SwingBuilder? I would prefer to use Key Bindings, not Key Listener..
Thank you for help and recommendations
Not 100% sure, but do you mean like this:
import groovy.swing.*
import javax.swing.*
def swing = new SwingBuilder()
def f2Action = swing.action(name:"F2 text", shortDescription:"F2 button", keyStroke:"F2") {
println "F2 pressed"
}
swing.edt {
frame(title: 'Keborad Binding test', size:[400,300],defaultCloseOperation: JFrame.HIDE_ON_CLOSE, show: true) {
panel {
button(text: 'F2',
actionPerformed:{ println "FFFF2222 pressed" }) {
action(f2Action)
}
}
}
}
def swing = new SwingBuilder()
def f2Action = swing.action(name:"F2 text", shortDescription:"F2 button", focus: JComponent.WHEN_IN_FOCUSED_WINDOW, keyStroke:"F2") {
println "F2 pressed"
}
def f3Action = swing.action(name:"F3 text", shortDescription:"F2 button", keyStroke:"F3") {
println "F3 pressed"
}
swing.edt {
frame(title: 'Keborad Binding test', size:[400,300],defaultCloseOperation: JFrame.HIDE_ON_CLOSE, show: true) {
panel {
button('F2') {action(f2Action)}
button('F3') {action(f3Action)}
}
}
}

Grails use SQLQuery result as transient value in domain class rendering

Let's say i have the following domain classes:
The first domain class Tag.groovy allows me to build a dynamic category structure with different layers (layer1, layer2 and layer3). Each activity from Activity.groovy belongs to a certain category and is connected to its category via ActivityTag.groovy. So far so good. :)
Tag.groovy
class Tag {
String name
String layer
Tag parent
static transients = ['activityCount', 'children']
int activityCount
static constraints = {
name nullable: false, unique: true
layer nullable: false, inList:['generic','layer1','layer2','layer3']
parent nullable: true
}
Set<Tag> getChildren() {
return Tag.findAllByParent(this) as Set
}
Set<Activity> getActivities() {
return ActivityTag.findAllByTag(this)*.activity
}
Set<Activity> getActivities(VirtualCity virtualCity) {
def activitiesWithTag = ActivityTag.findAllByTag(this)*.activity
return activitiesWithTag.findAll({it.virtualCity==virtualCity})
}
def getActivityCount(){
if (this.layer == "layer1") {
return this.children*.children*.activityCount.sum().sum()
} else if (this.layer == "layer2") {
return this.children*.activityCount.sum()
} else {
return this.getActivities().size()
}
}
def getActivityCount(VirtualCity virtualCity){
if (this.layer == "layer1") {
return this.children*.children*.activityCount.sum().sum()
} else if (this.layer == "layer2") {
return this.children*.activityCount.sum()
} else {
return this.getActivities(virtualCity).size()
}
}
}
Activity.groovy
class ActivityTag {console
Activity activity
Tag tag
static mapping = {
id composite: ['activity', 'tag']
version false
}
}
ActivityTag.groovy
class Activity {
VirtualCity virtualCity
String name
}
Now I would like to render my categories as JSON in a tree view. Can you tell me how I can achieve this?
I tried render(template: "tree", collection: Tag.findAllByLayer("layer1"), var: 'tag')
with this template _tree.gson:
model {
Tag tag
}
json {
id tag.id
name tag.name
activityCount tag?.activityCount ?: null
children g.render(template: 'tree', collection: tag?.children, var: 'tag') ?: null
}
But this method fails with java.lang.reflect.InvocationTargetException: null

Groovy swingbuilder events for textField

I have the following Code:
textField(id: 'programfilter', actionPerformed: { println("execute some action") })
However, the actionPerformed-closure is only called when the textField has the focus and enter is pressed. What do I have to do so that the closure is called on different events e.g. clicking into the textField, selecting text in it or simply on every update of its text?
You can do that leveraging closure coercion. Just a quick example to demonstrate:
import groovy.swing.SwingBuilder
import java.awt.event.*
import javax.swing.event.*
import javax.swing.WindowConstants as WC
SwingBuilder.build() {
frame(title:'Swing Listener example', size:[300,100],
visible:true, defaultCloseOperation:WC.EXIT_ON_CLOSE) {
gridLayout(cols: 2, rows: 0)
label 'Input text: '
input = textField(columns:10, actionPerformed: { echo.text = input.text.toUpperCase() })
label 'Echo: '
echo = label()
input.document.addDocumentListener(
[insertUpdate: { echo.text = input.text },
removeUpdate: { echo.text = input.text },
changedUpdate: { e -> println e }] as DocumentListener)
input.addFocusListener(
[focusGained: { e -> println "Focus gained: $e.cause"},
focusLost: {e -> println "Focus lost: $e.cause"}] as FocusListener)
input.addCaretListener({ e -> println "Caret event: $e"})
}
}

Changing value in textfield with groovy and SwingBuilder

I want to put the value of a variable (==i) in a textfield, so that its value is shown in the textfield, i.e., changing from 1 to 10.
def sb = new SwingBuilder()
def th = Thread.start {
for(i in 1..10) {
sleep 2000
}
}
def Pan = sb.panel(layout: new BorderLayout()) {
sb.panel(constraints: BorderLayout.NORTH){
gridLayout(cols: 2, rows: 3)
textField id:'tf', text: ?
}
}
You can do that with the doOutside method of SwingBuilder, which allows to run a closure outside the EDT. The code below does what you are trying to do (with a table layout instead of a grid layout).
import groovy.swing.SwingBuilder
import static javax.swing.JFrame.EXIT_ON_CLOSE
import java.awt.*
def swingBuilder = new SwingBuilder()
swingBuilder.edt {
def message
def setMessage = { String s -> message.setText(s) }
frame(title: 'Example', size: [200, 150], show: true, locationRelativeTo: null, defaultCloseOperation: EXIT_ON_CLOSE) {
borderLayout(vgap: 5)
panel(constraints: BorderLayout.CENTER, border: emptyBorder(10)) {
tableLayout(cellpadding: 5) {
tr {
td {
label 'Value' // text property is default, so it is implicit.
}
td {
message = textField(id: 'tf', columns: 5, text: '0')
}
}
}
}
}
doOutside {
for (i in 1..10) {
sleep 1000
edt { setMessage(String.valueOf(i)) }
}
}
}