This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 26 - Pages: 2 [ 1 2 | Next ] - Last Post: 26 Sep 20, 08:57 Last Post By: davidekholm Threads: [ Previous | Next ]
RobM

Posts: 3,815
Registered: 4-Aug-2006
JSmartSyntaxTextArea fallback to JSmartTextArea
Posted: 19 Sep 20, 23:11
 
  Click to reply to this thread Reply
David, you mentioned that you can use try/catch to enable the new syntax highlighting for jAlbum 22 but fallback to JSmartTextArea for earlier versions. I have got it working in my Journal skin, but I'm sure my code is ugly, not just clumsy!

In essence, I wrap the control panel in a try block and then in the catch I use the same control ui code, except using just the JSmartTextArea. To make it 'catch' the first line inside that block check for the JSmartSyntaxTextArea class
try {
            Class.forName( "se.datadosen.component.JSmartSyntaxTextArea" );
            ControlPanel ui;
            ...
        };  //End of Control Panel
        // Set the UI
        window.setSkinUI(ui);
        window.pack();        
        } 
        catch( ClassNotFoundException  e ) {
        ControlPanel ui;
        //Use JSmartTextArea

After you have stopped laughing/crying ;) , can you show me how to do it properly?

From https://jalbum.net/forum/message.jspa?messageID=342697#342697
jGromit wrote:
davidekholm wrote:
  • Developers: New JSmartSyntaxTextArea component for enabling syntax highlighting in your skins. (It's a drop-in replacement to JSmartTextArea which defaults to html syntax)

I'm guessing that if a skin uses this component, that skin will blow up in any version of jAlbum prior to 21.1, right?

True. There are ways to write code that falls back to the previous editor using try/catch blocks though, and if that makes your code look clumsy, then one can write a little framework for that.

davidekholm

Posts: 3,442
Registered: 18-Oct-2002
Re: JSmartSyntaxTextArea fallback to JSmartTextArea
Posted: 21 Sep 20, 13:18   in response to: RobM in response to: RobM
 
  Click to reply to this thread Reply
I'm not laughing. I'd just put that less intuitive looking code in a (preferably static) method, like this:
JTextArea createTextArea(int rows, int cols) {
	try {
		Class.forName("se.datadosen.component.JSmartSyntaxTextArea");
		return new JSmartSyntaxTextArea(rows, cols);
	} catch (Throwable t) {
		return new JSmartTextArea(rows, cols);
	}
	
}
You can now call this code multiple times to get the best version of the text area component no matter what jAlbum version the user is running. Calling the code looks like this of course:
JTextArea ta = createTextArea(4,30);
The Class.forName seems necessary as it triggers a dynamic class loading. Just loading the class statically will cause an exception to be thrown before the try - catch is entered.
RobM

Posts: 3,815
Registered: 4-Aug-2006
Re: JSmartSyntaxTextArea fallback to JSmartTextArea
Posted: 21 Sep 20, 13:50   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
davidekholm wrote:
I'm not laughing. I'd just put that less intuitive looking code in a (preferably static) method, like this:
JTextArea createTextArea(int rows, int cols) {
	try {
		Class.forName("se.datadosen.component.JSmartSyntaxTextArea");
		return new JSmartSyntaxTextArea(rows, cols);
	} catch (Throwable t) {
		return new JSmartTextArea(rows, cols);
	}
	
}
You can now call this code multiple times to get the best version of the text area component no matter what jAlbum version the user is running. Calling the code looks like this of course:
JTextArea ta = createTextArea(4,30);
The Class.forName seems necessary as it triggers a dynamic class loading. Just loading the class statically will cause an exception to be thrown before the try - catch is entered.
Thanks, I’ll give it a go tonight. At least I got the Class.forName line right ;)
The syntax highlighting is great for skins that offer CSS/HTML/JavaScript code panels.
RobM

Posts: 3,815
Registered: 4-Aug-2006
Re: JSmartSyntaxTextArea fallback to JSmartTextArea
Posted: 22 Sep 20, 00:59   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
The code works in jAlbum 22 but still dies in 19 with error.

se.datadosen.util.ScriptException: javax.script.ScriptException: Sourced file: inline evaluation of: ``new Journal(engine);'' : Unknown class: Journal : at Line: 1 : in file: inline evaluation of: ``new Journal(engine);'' : new Journal ( engine ) 
 in onload.bsh at line number 1
	at se.datadosen.util.ScriptException.of(ScriptException.java:59)
	at se.datadosen.jalbum.AlbumBean.processScript(AlbumBean.java:2480)
	at se.datadosen.jalbum.JAlbumFrame.executeScript(JAlbumFrame.java:1270)
	at se.datadosen.jalbum.JMainSettingsPanel$5$1.run(JMainSettingsPanel.java:311)
Caused by: javax.script.ScriptException: Sourced file: inline evaluation of: ``new Journal(engine);'' : Unknown class: Journal : at Line: 1 : in file: inline evaluation of: ``new Journal(engine);'' : new Journal ( engine ) 
 in inline evaluation of: ``new Journal(engine);'' at line number 1
	at bsh.BshScriptEngine.evalSource(BshScriptEngine.java:96)
	at bsh.BshScriptEngine.eval(BshScriptEngine.java:57)
	at java.scripting/javax.script.AbstractScriptEngine.eval(Unknown Source)
	at se.datadosen.jalbum.AlbumBean.doProcessExpression(AlbumBean.java:2530)
	at se.datadosen.jalbum.AlbumBean.processExpression(AlbumBean.java:2522)
	at se.datadosen.jalbum.AlbumBean.processScript(AlbumBean.java:2478)
	... 2 more


I put the code just inside the skin's class declaration, as below
public class Journal extends CompiledBase {
    JTextArea createTextArea(int rows, int cols) {
	try {
            Class.forName("se.datadosen.component.JSmartSyntaxTextArea");
            return new JSmartSyntaxTextArea(rows, cols);
	} catch (Throwable t) {
            return new JSmartTextArea(rows, cols);
	}	
    }
    
    public Journal(AlbumBean engine) {
        super(engine);
 
        //and later call the method in my custom CSS panel
        ControlPanel cssPanel = new ControlPanel() {
            JTextArea insertCss = createTextArea(18, 75);
            JScrollPane insertCssPane = new JScrollPane(insertCss);


I also modified your method to make it more flexible, passing in default text, the syntax to be used, line and word wrap options. It too works in v22, but of course also crashes in 19.
static JTextArea makeTA(int rows, int cols, String defaultText, String syntax, boolean lWrap, boolean wWrap) {
        try {
            Class.forName("se.datadosen.component.JSmartSyntaxTextArea");
            JSmartSyntaxTextArea STA = new JSmartSyntaxTextArea(defaultText, rows, cols);
            if(syntax.equals("CSS"))
                STA.setSyntaxEditingStyle(SYNTAX_STYLE_CSS);
            else if(syntax.equals("HTML"))
                STA.setSyntaxEditingStyle(SYNTAX_STYLE_HTML);
            else
                STA.setSyntaxEditingStyle(SYNTAX_STYLE_JAVASCRIPT);
            STA.setLineWrap(lWrap);
            STA.setWrapStyleWord(wWrap);
            return STA;
        }
        catch (Throwable t) {
            JSmartTextArea TA = new JSmartTextArea(defaultText, rows, cols);
            TA.setLineWrap(lWrap);
            TA.setWrapStyleWord(wWrap);
            return TA;      
        }           
    }
davidekholm

Posts: 3,442
Registered: 18-Oct-2002
Re: JSmartSyntaxTextArea fallback to JSmartTextArea
Posted: 22 Sep 20, 12:04   in response to: RobM in response to: RobM
 
  Click to reply to this thread Reply
Really odd. It worked before you added that static method I take it? What if you put it in a separate utility class?
RobM

Posts: 3,815
Registered: 4-Aug-2006
Re: JSmartSyntaxTextArea fallback to JSmartTextArea
Posted: 22 Sep 20, 12:42   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
davidekholm wrote:
Really odd. It worked before you added that static method I take it? What if you put it in a separate utility class?
No, even without the static it fails. I tried making the method throw a ClassNotFoundException, and catching that instead of Throwable, but NetBeans reports an error when the method is called - error: unreported exception ClassNotFoundException; must be caught or declared to be thrown.

I have tried putting it in a Util class but it now complains about the return statements. It states the methods return should be either a JSmartSyntaxTextArea or JSmartTextArea, not a JTextArea. (It also complains about calling the method using Util.methodName() - do I need to do something else, or is it because of the error?)

Maybe the simple answer is not to make the skins have a fallback, or use my original code, which while crazy does actually work.
RobM

Posts: 3,815
Registered: 4-Aug-2006
Re: JSmartSyntaxTextArea fallback to JSmartTextArea
Posted: 22 Sep 20, 13:06   in response to: RobM in response to: RobM
 
  Click to reply to this thread Reply
I have got rid of the return issue, now have Util class as
public class Util extends CompiledBase {
	
	public Util(AlbumBean engine) {
		super(engine);
	}
 
    JTextArea makeTA(int rows, int cols, String defaultText, String syntax, boolean lWrap, boolean wWrap) throws ClassNotFoundException {
        try {
            Class.forName("se.datadosen.component.JSmartSyntaxTextArea");
            new se.datadosen.component.JSmartSyntaxTextArea();
            JSmartSyntaxTextArea STA = new JSmartSyntaxTextArea(defaultText, rows, cols);
            if(syntax.equals("CSS"))
                STA.setSyntaxEditingStyle(SYNTAX_STYLE_CSS);
            else if(syntax.equals("HTML"))
                STA.setSyntaxEditingStyle(SYNTAX_STYLE_HTML);
            else
                STA.setSyntaxEditingStyle(SYNTAX_STYLE_JAVASCRIPT);
            STA.setLineWrap(lWrap);
            STA.setWrapStyleWord(wWrap);            
            return STA;
        }
        catch (ClassNotFoundException  e) {
        //catch (Throwable e) {
            System.out.println("Error " + e);
            JSmartTextArea TA = new JSmartTextArea(defaultText, rows, cols);
            TA.setLineWrap(lWrap);
            TA.setWrapStyleWord(wWrap);
            return TA;
        }
    }
}

Now when I call
JTextArea insertCss = Util.makeTA(18, 75, "", "CSS", true, true);

I get' error: non-static method makeTA(int,int,String,String,boolean,boolean) cannot be referenced from a static context'
RobM

Posts: 3,815
Registered: 4-Aug-2006
Re: JSmartSyntaxTextArea fallback to JSmartTextArea
Posted: 22 Sep 20, 21:15   in response to: RobM in response to: RobM
 
  Click to reply to this thread Reply
If I make the JTextArea method static, it gets rid of the errors, compiles and works in 22. Still crashes in 19 with syntax error as before, so the try catch is not working properly. Completely out of ideas and my comfort zone!
davidekholm

Posts: 3,442
Registered: 18-Oct-2002
Re: JSmartSyntaxTextArea fallback to JSmartTextArea
Posted: 23 Sep 20, 10:21   in response to: RobM in response to: RobM
 
  Click to reply to this thread Reply
Change public class Util extends CompiledBase to simply public class Util and add "static" to that support method, compile it and pass me the compiled skin and source. I'll test on jAlbum 22 and 19 and see if I can resolve this.
RobM

Posts: 3,815
Registered: 4-Aug-2006
Re: JSmartSyntaxTextArea fallback to JSmartTextArea
Posted: 23 Sep 20, 15:23   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
Attachment Journal.zip (25.9 KB)
I've attached the Skin which includes the Netbeans project, zipped up under folder Netbeans project.
RobM

Posts: 3,815
Registered: 4-Aug-2006
Re: JSmartSyntaxTextArea fallback to JSmartTextArea
Posted: 23 Sep 20, 22:40   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
I have got it to work with both 19 (fallback) and 22 (syntax), but, again, not ideal. Maybe it will point to a proper solution?

I have changed the utility method JTextArea makeTA() to
    static JTextArea makeTA(int rows, int cols, String defaultText, String syntax, boolean lWrap, boolean wWrap) throws ClassNotFoundException, NoClassDefFoundError {
        try {
            JSmartSyntaxTextArea temp = new se.datadosen.component.JSmartSyntaxTextArea();
            JSmartSyntaxTextArea STA = new JSmartSyntaxTextArea(defaultText, rows, cols);
            if(syntax.equals("CSS"))
                STA.setSyntaxEditingStyle(SYNTAX_STYLE_CSS);
            else if(syntax.equals("HTML"))
                STA.setSyntaxEditingStyle(SYNTAX_STYLE_HTML);
            else
                STA.setSyntaxEditingStyle(SYNTAX_STYLE_JAVASCRIPT);
            STA.setLineWrap(lWrap);
            STA.setWrapStyleWord(wWrap);            
            return STA;
        }
        catch (NoClassDefFoundError  e) {
            System.out.println("Class Error " + e);
            JSmartTextArea TA = new JSmartTextArea(defaultText, rows, cols);
            TA.setLineWrap(lWrap);
            TA.setWrapStyleWord(wWrap);
            return TA;
        }
    }

Then I followed the instructions at Stackoverflow>how to include jars in lib into project

So the skin's lib now has (10MB of files!)
jalbum-core.jar
javafx.graphics.jar
Journal.jar
rsyntaxtextarea-3.1.2-SNAPSHOT.jar
davidekholm

Posts: 3,442
Registered: 18-Oct-2002
Re: JSmartSyntaxTextArea fallback to JSmartTextArea
Posted: 24 Sep 20, 12:00   in response to: RobM in response to: RobM
 
  Click to reply to this thread Reply
Attachment Journal.zip (62.6 KB)
You should naturally not need to include dependent libs into your code. That makes for bad code duplication. I've now fixed your project so it's forward compatible with regards to JSmartSyntaxTextArea. I've modified the following:
  • Set the default text for the font boxes in SkinModel
  • Put the dynamic test loading of JSmartSyntaxTextArea in a utility method of Journal.java and refer to it instead. This code in turn calls Util.makeSTA if the dynamic test works
  • Cleared fallback from Util.makeSTA (resides under Journal.STA now)
  • Changed the rather verbose use of the StateMonitor to the ComponentUtilities shorthands

What I've essentially done is to ensure that the classloader does a dynamic test for the existence before loading Util. Only after such test is it safe to refer to Util. The previous try-catch under Util.makeSTA is now under Journal.makeSTA as Java would throw a ClassNotFoundException before even entering this try-catch block. (The error happened on class loading of Util.java). This is one of those tricky things that differs between languages doing "early-binding" like Java and "late-binding" languages like JavaScript.
JeffTucker

Posts: 8,039
Registered: 31-Jan-2006
Re: JSmartSyntaxTextArea fallback to JSmartTextArea
Posted: 24 Sep 20, 14:21   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
davidekholm wrote:
  • Changed the rather verbose use of the StateMonitor to the ComponentUtilities shorthands

I'm interested in knowing what the "shorthand" method is, but I'm not seeing anything different about the use of the StateMonitor in the code you've provided. Looks like what we've been doing for years.
RobM

Posts: 3,815
Registered: 4-Aug-2006
Re: JSmartSyntaxTextArea fallback to JSmartTextArea
Posted: 24 Sep 20, 14:58   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
Thanks David. I’ll add the new try catch method to the wiki’s code snippets page, as an example of keeping skins with new features working on old versions of jAlbum.

And thanks for your patience with us (me, anyway) amateur coders.
davidekholm

Posts: 3,442
Registered: 18-Oct-2002
Re: JSmartSyntaxTextArea fallback to JSmartTextArea
Posted: 24 Sep 20, 16:58   in response to: JeffTucker in response to: JeffTucker
 
  Click to reply to this thread Reply
jGromit wrote:
davidekholm wrote:
  • Changed the rather verbose use of the StateMonitor to the ComponentUtilities shorthands

I'm interested in knowing what the "shorthand" method is, but I'm not seeing anything different about the use of the StateMonitor in the code you've provided. Looks like what we've been doing for years.


I just changed to http://jalbum.net/api/se/datadosen/component/ComponentUtilities.html#whenSelectedEnable(javax.swing.AbstractButton,javax.swing.JComponent...)

StateMonitor is still recommended for general use, but in this case the code became shorter and easier to read.
Legend
Forum admins
Helpful Answer
Correct Answer

Point your RSS reader here for a feed of the latest messages in all forums