问:
java highlevel rest client connection is giving ssl error
I am getting bellow error some time and not able to get search results.

```<code> 2020-05-26 16:03:30.207 ERROR [default task-284][SearchMVCAction:148]
 exception in getting response java.io.IOException: Unrecognized SSL
 message, plaintext connection?
 at org.elasticsearch.client.RestClient$SyncResponseListener.get(RestClient.java:954)
 at org.elasticsearch.client.RestClient.performRequest(RestClient.java:229)
</code>```

my code is as below.

```<code>try{
    RestClientBuilder builder = SearchResultsUtil.getRestClientBuilder();
    RestHighLevelClient esClient = new RestHighLevelClient(builder);
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    sourceBuilder.timeout(new TimeValue(600, TimeUnit.SECONDS)); // Request timeout
    sourceBuilder.from(pagenumber);
    sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); //Result set ordering
    BoolQueryBuilder query = new BoolQueryBuilder();
         query.must(QueryBuilders.queryStringQuery("*"+searchWildKeyword+"*").field("content").field("title",10.0f).field("description").lenient(true).escape(true).analyzeWildcard(true).fuzziness(Fuzziness.ZERO).defaultOperator(Operator.OR).boost(1.0f));
    sourceBuilder.query(query);
    SearchRequest searchRequest = new SearchRequest(esIndice);
    searchRequest.source(sourceBuilder);
    SearchResponse searchResponse  = esClient.search(searchRequest, RequestOptions.DEFAULT);
    SearchHits hits = searchResponse.getHits();
    System.out.println("results:"+hits);
    }catch (Exception e) {
        _log.error("Exception Getting Response",e);

    }finally {
        _log.info("inside finally block");
        esClient.close();
    }
</code>```

also i tried flush() but no luck.

```<code>finally {
    _log.info("inside finally block");
    esClient.close();
    esClient.indices().flush(new FlushRequest(esIndice), RequestOptions.DEFAULT);
}
</code>```

kindly help what might be the cause and i am using ES 9200 port and https protocol.

答:
You will have to refactor your code a bit. Please find working example with regards to RestHighLevelClient below. </p>

```<code>    @Bean
public RestHighLevelClient elasticRestClient () {
    String[] httpHosts = httpHostsProperty.split(";");
    HttpHost[] httpHostsAsArray = new HttpHost[httpHosts.length];
    int index = 0;

    for (String httpHostAsString : httpHosts) {
        HttpHost httpHost = new HttpHost(httpHostAsString.split(":")[0], new Integer(httpHostAsString.split(":")[1]), "http");
        httpHostsAsArray[index++] = httpHost;
    }

    RestClientBuilder restClientBuilder = RestClient.builder(httpHostsAsArray)
            .setRequestConfigCallback(builder -> builder
                    .setConnectTimeout(connectTimeOutInMs)
                    .setSocketTimeout(socketTimeOutInMs)
            );

    return new RestHighLevelClient(restClientBuilder);
}
</code>```

<p>and the class using the RestHighLevelClient: </p>

```<code>    @Autowired
private RestHighLevelClient restClient;

        IndexResponse indexResponse = restClient.index(indexRequest, RequestOptions.DEFAULT);
</code>```

Body:
I am getting bellow error some time and not able to get search results.

 2020-05-26 16:03:30.207 ERROR [default task-284][SearchMVCAction:148]
 exception in getting response java.io.IOException: Unrecognized SSL
 message, plaintext connection?
 at org.elasticsearch.client.RestClient$SyncResponseListener.get(RestClient.java:954)
 at org.elasticsearch.client.RestClient.performRequest(RestClient.java:229)

my code is as below.

try{
    RestClientBuilder builder = SearchResultsUtil.getRestClientBuilder();
    RestHighLevelClient esClient = new RestHighLevelClient(builder);
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    sourceBuilder.timeout(new TimeValue(600, TimeUnit.SECONDS)); // Request timeout
    sourceBuilder.from(pagenumber);
    sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); //Result set ordering
    BoolQueryBuilder query = new BoolQueryBuilder();
         query.must(QueryBuilders.queryStringQuery("*"+searchWildKeyword+"*").field("content").field("title",10.0f).field("description").lenient(true).escape(true).analyzeWildcard(true).fuzziness(Fuzziness.ZERO).defaultOperator(Operator.OR).boost(1.0f));
    sourceBuilder.query(query);
    SearchRequest searchRequest = new SearchRequest(esIndice);
    searchRequest.source(sourceBuilder);
    SearchResponse searchResponse  = esClient.search(searchRequest, RequestOptions.DEFAULT);
    SearchHits hits = searchResponse.getHits();
    System.out.println("results:"+hits);
    }catch (Exception e) {
        _log.error("Exception Getting Response",e);

    }finally {
        _log.info("inside finally block");
        esClient.close();
    }

also i tried flush() but no luck.

finally {
    _log.info("inside finally block");
    esClient.close();
    esClient.indices().flush(new FlushRequest(esIndice), RequestOptions.DEFAULT);
}

kindly help what might be the cause and i am using ES 9200 port and https protocol.

Body:
You will have to refactor your code a bit. Please find working example with regards to RestHighLevelClient below.

    @Bean
public RestHighLevelClient elasticRestClient () {
    String[] httpHosts = httpHostsProperty.split(";");
    HttpHost[] httpHostsAsArray = new HttpHost[httpHosts.length];
    int index = 0;

    for (String httpHostAsString : httpHosts) {
        HttpHost httpHost = new HttpHost(httpHostAsString.split(":")[0], new Integer(httpHostAsString.split(":")[1]), "http");
        httpHostsAsArray[index++] = httpHost;
    }

    RestClientBuilder restClientBuilder = RestClient.builder(httpHostsAsArray)
            .setRequestConfigCallback(builder -> builder
                    .setConnectTimeout(connectTimeOutInMs)
                    .setSocketTimeout(socketTimeOutInMs)
            );

    return new RestHighLevelClient(restClientBuilder);
}

and the class using the RestHighLevelClient:

    @Autowired
private RestHighLevelClient restClient;

        IndexResponse indexResponse = restClient.index(indexRequest, RequestOptions.DEFAULT);


来源: stackexchange

问:
Produce two shiny widgets from the same uiOutput() at the same time
I have the shiny dashboard below in which I select from the pickerInput() "Select Database/s" if I will display the values of either Sepal.Length if only this is selected or Sepal.Width if only this is selected or both if both selected. Is it possible to achieve it inside the same uiOutput("fnamesid") and without having to use 2 different uiOutput()?

```<code>library(shiny)
library(shinydashboard)
library(shinyWidgets)
ui <- dashboardPage(
    header = dashboardHeader(title = "My dashboard"),
    sidebar = dashboardSidebar(
        uiOutput("dbs"),
        uiOutput("fnamesid")
    ),
    body = dashboardBody(

    )
)

server <- function(input, output, session) {
    output$dbs<-renderUI({

            pickerInput("DB", "Select Database/s",
                        choices = c("Sepal.Length","Sepal.Width"),
                        multiple = T,options = list(`actions-box` = TRUE),
                        selected = "Sepal.Length")

    })
    output$fnamesid<-renderUI({

            if("Sepal.Length"%in% input$DB){
                pickerInput("sn", "Select sn_ID for x-axis",
                            choices = unique(iris$Sepal.Length),
                            multiple = T,options = list(`actions-box` = TRUE),
                            selected = head(unique(iris$Sepal.Length)))

            }
        else if("Sepal.Width"%in% input$DB){
            pickerInput("sn2", "Select sn_ID for x-axis",
                        choices = unique(iris$Sepal.Width),
                        multiple = T,options = list(`actions-box` = TRUE),
                        selected = head(unique(iris$Sepal.Width)))

        }
        else if("Sepal.Length"%in% input$DB&"Sepal.Width"%in% input$DB){
            pickerInput("sn", "Select sn_ID for x-axis",
                        choices = unique(iris$Sepal.Length),
                        multiple = T,options = list(`actions-box` = TRUE),
                        selected = head(unique(iris$Sepal.Length)))

            pickerInput("sn2", "Select sn_ID for x-axis",
                        choices = unique(iris$Sepal.Width),
                        multiple = T,options = list(`actions-box` = TRUE),
                        selected = head(unique(iris$Sepal.Width)))

        }

    })

}

shinyApp(ui, server)
</code>```

答:
Your problem is that if both options are selected in input$DB, then the condition of the first if () statement is TRUE and that is the element of your if-then-else chain that gets executed.  So, the first thing to do is to move the "both are selected" element of the chain to the top and adjust your logic accordingly.

Second, to return two (or more) UI elements from the same call to renderUI(), wrap them in a tagList().  Here's a version of your output$fnamesid that works for me:

```<code>  output$fnamesid<-renderUI({
    if ("Sepal.Length" %in% input$DB & "Sepal.Width" %in% input$DB){
      tagList(
        pickerInput("sn", "Select sn_ID for x-axis",
                  choices = unique(iris$Sepal.Length),
                  multiple = T,options = list(`actions-box` = TRUE),
                  selected = head(unique(iris$Sepal.Length))),
        pickerInput("sn2", "Select sn_ID for x-axis",
                  choices = unique(iris$Sepal.Width),
                  multiple = T,options = list(`actions-box` = TRUE),
                  selected = head(unique(iris$Sepal.Width)))
      )
    }
    else if("Sepal.Length"%in% input$DB){
      pickerInput("sn", "Select sn_ID for x-axis",
                  choices = unique(iris$Sepal.Length),
                  multiple = T,options = list(`actions-box` = TRUE),
                  selected = head(unique(iris$Sepal.Length)))
    }
    else if("Sepal.Width"%in% input$DB){
      pickerInput("sn2", "Select sn_ID for x-axis",
                  choices = unique(iris$Sepal.Width),
                  multiple = T,options = list(`actions-box` = TRUE),
                  selected = head(unique(iris$Sepal.Width)))
    }
</code>```

Notice the comma between the two pickerInputs in the tagList.  It's important! ;)

ContentLicense: CC BY-SA 4.0

Body:
I have the shiny dashboard below in which I select from the pickerInput() "Select Database/s" if I will display the values of either Sepal.Length if only this is selected or Sepal.Width if only this is selected or both if both selected. Is it possible to achieve it inside the same uiOutput("fnamesid") and without having to use 2 different uiOutput()?

library(shiny)
library(shinydashboard)
library(shinyWidgets)
ui <- dashboardPage(
    header = dashboardHeader(title = "My dashboard"),
    sidebar = dashboardSidebar(
        uiOutput("dbs"),
        uiOutput("fnamesid")
    ),
    body = dashboardBody(

    )
)

server <- function(input, output, session) {
    output$dbs<-renderUI({

            pickerInput("DB", "Select Database/s",
                        choices = c("Sepal.Length","Sepal.Width"),
                        multiple = T,options = list(`actions-box` = TRUE),
                        selected = "Sepal.Length")

    })
    output$fnamesid<-renderUI({

            if("Sepal.Length"%in% input$DB){
                pickerInput("sn", "Select sn_ID for x-axis",
                            choices = unique(iris$Sepal.Length),
                            multiple = T,options = list(`actions-box` = TRUE),
                            selected = head(unique(iris$Sepal.Length)))

            }
        else if("Sepal.Width"%in% input$DB){
            pickerInput("sn2", "Select sn_ID for x-axis",
                        choices = unique(iris$Sepal.Width),
                        multiple = T,options = list(`actions-box` = TRUE),
                        selected = head(unique(iris$Sepal.Width)))

        }
        else if("Sepal.Length"%in% input$DB&"Sepal.Width"%in% input$DB){
            pickerInput("sn", "Select sn_ID for x-axis",
                        choices = unique(iris$Sepal.Length),
                        multiple = T,options = list(`actions-box` = TRUE),
                        selected = head(unique(iris$Sepal.Length)))

            pickerInput("sn2", "Select sn_ID for x-axis",
                        choices = unique(iris$Sepal.Width),
                        multiple = T,options = list(`actions-box` = TRUE),
                        selected = head(unique(iris$Sepal.Width)))

        }

    })

}

shinyApp(ui, server)

Body:
Your problem is that if both options are selected in input$DB, then the condition of the first if () statement is TRUE and that is the element of your if-then-else chain that gets executed.  So, the first thing to do is to move the "both are selected" element of the chain to the top and adjust your logic accordingly.

Second, to return two (or more) UI elements from the same call to renderUI(), wrap them in a tagList().  Here's a version of your output$fnamesid that works for me:

  output$fnamesid<-renderUI({
    if ("Sepal.Length" %in% input$DB & "Sepal.Width" %in% input$DB){
      tagList(
        pickerInput("sn", "Select sn_ID for x-axis",
                  choices = unique(iris$Sepal.Length),
                  multiple = T,options = list(`actions-box` = TRUE),
                  selected = head(unique(iris$Sepal.Length))),
        pickerInput("sn2", "Select sn_ID for x-axis",
                  choices = unique(iris$Sepal.Width),
                  multiple = T,options = list(`actions-box` = TRUE),
                  selected = head(unique(iris$Sepal.Width)))
      )
    }
    else if("Sepal.Length"%in% input$DB){
      pickerInput("sn", "Select sn_ID for x-axis",
                  choices = unique(iris$Sepal.Length),
                  multiple = T,options = list(`actions-box` = TRUE),
                  selected = head(unique(iris$Sepal.Length)))
    }
    else if("Sepal.Width"%in% input$DB){
      pickerInput("sn2", "Select sn_ID for x-axis",
                  choices = unique(iris$Sepal.Width),
                  multiple = T,options = list(`actions-box` = TRUE),
                  selected = head(unique(iris$Sepal.Width)))
    }

Notice the comma between the two pickerInputs in the tagList.  It's important! ;)


问:
Screen Capture with OpenCV and Python-2.7
I'm using Python 2.7 and OpenCV 2.4.9.

I need to capture the current frame that is being shown to the user and load it as an cv::Mat object in Python.

Do you guys know a fast way to do it recursively?

I need something like what's done in the example below, that captures Mat frames from a webcam recursively:

```<code>import cv2

cap = cv2.VideoCapture(0)
while(cap.isOpened()):
    ret, frame = cap.read()
    cv2.imshow('WindowName', frame)
    if cv2.waitKey(25) & 0xFF == ord('q'):
        cap.release()
        cv2.destroyAllWindows()
        break
</code>```

In the example it's used the VideoCapture class to work with the captured image from the webcam.

With VideoCapture.read() a new frame is always being readed and stored into a Mat object.

Could I load a "printscreens stream" into a VideoCapture object? Could I create a streaming of my computer's screen with OpenCV in Python, without having to save and delete lots of .bmp files per second?

I need this frames to be Mat objects or NumPy arrays, so I can perform some Computer Vision routines with this frames in real time.

答:
This is the updated answer for the answer by @Neabfi

import time

import cv2
import numpy as np
from mss import mss

mon = {'top': 160, 'left': 160, 'width': 200, 'height': 200}
with mss() as sct:
    # mon = sct.monitors[0]
    while True:
        last_time = time.time()
        img = sct.grab(mon)
        print('fps: {0}'.format(1 / (time.time()-last_time)))
        cv2.imw('test', np.array(img))
        if cv2.waitKey(25) & 0xFF == ord('q'):
            cv2.destroyAllWindows()
            break
```

<p>And to save to a mp4 video </p>

<pre class="lang-py prettyprint-override"><code>import time

import cv2
import numpy as np
from mss import mss

def record(name):
    with mss() as sct:
        # mon = {'top': 160, 'left': 160, 'width': 200, 'height': 200}
        mon = sct.monitors[0]
        name = name + '.mp4'
        fourcc = cv2.VideoWriter_fourcc(*'mp4v')
        desired_fps = 30.0
        out = cv2.VideoWriter(name, fourcc, desired_fps,
                              (mon['width'], mon['height']))
        last_time = 0
        while True:
            img = sct.grab(mon)
            # cv2.imshow('test', np.array(img))
            if time.time() - last_time > 1./desired_fps:
                last_time = time.time()
                destRGB = cv2.cvtColor(np.array(img), cv2.COLOR_BGRA2BGR)
                out.write(destRGB)
            if cv2.waitKey(25) & 0xFF == ord('q'):
                cv2.destroyAllWindows()
                break

record("Video")

</code>```

ContentLicense: CC BY-SA 3.0

Body:
I'm using Python 2.7 and OpenCV 2.4.9.

I need to capture the current frame that is being shown to the user and load it as an cv::Mat object in Python.

Do you guys know a fast way to do it recursively?

I need something like what's done in the example below, that captures Mat frames from a webcam recursively:

import cv2

cap = cv2.VideoCapture(0)
while(cap.isOpened()):
    ret, frame = cap.read()
    cv2.imshow('WindowName', frame)
    if cv2.waitKey(25) & 0xFF == ord('q'):
        cap.release()
        cv2.destroyAllWindows()
        break

In the example it's used the VideoCapture class to work with the captured image from the webcam.

With VideoCapture.read() a new frame is always being readed and stored into a Mat object.

Could I load a "printscreens stream" into a VideoCapture object? Could I create a streaming of my computer's screen with OpenCV in Python, without having to save and delete lots of .bmp files per second?

I need this frames to be Mat objects or NumPy arrays, so I can perform some Computer Vision routines with this frames in real time.

Body:
This is the updated answer for the answer by @Neabfi

import time

import cv2
import numpy as np
from mss import mss

mon = {'top': 160, 'left': 160, 'width': 200, 'height': 200}
with mss() as sct:
    # mon = sct.monitors[0]
    while True:
        last_time = time.time()
        img = sct.grab(mon)
        print('fps: {0}'.format(1 / (time.time()-last_time)))
        cv2.imw('test', np.array(img))
        if cv2.waitKey(25) & 0xFF == ord('q'):
            cv2.destroyAllWindows()
            break

And to save to a mp4 video

import time

import cv2
import numpy as np
from mss import mss

def record(name):
    with mss() as sct:
        # mon = {'top': 160, 'left': 160, 'width': 200, 'height': 200}
        mon = sct.monitors[0]
        name = name + '.mp4'
        fourcc = cv2.VideoWriter_fourcc(*'mp4v')
        desired_fps = 30.0
        out = cv2.VideoWriter(name, fourcc, desired_fps,
                              (mon['width'], mon['height']))
        last_time = 0
        while True:
            img = sct.grab(mon)
            # cv2.imshow('test', np.array(img))
            if time.time() - last_time > 1./desired_fps:
                last_time = time.time()
                destRGB = cv2.cvtColor(np.array(img), cv2.COLOR_BGRA2BGR)
                out.write(destRGB)
            if cv2.waitKey(25) & 0xFF == ord('q'):
                cv2.destroyAllWindows()
                break

record("Video")


问:
Javascript - Counting array elements by reduce method until specific value occurs doesn't give a correct output
```<code>const arr = [5,6,0,7,8];
const sum = (arr,num) => arr.reduce((total)=>(num==0 ? total : total+num), 0)
console.log(sum(arr, 0))
</code>```

<p>Please check how can I make it work. Did some mistake but don't know what exactly. Output is a function instead of a result. </p>

答:
Since you need to stop summing values part way through the array, this might be most simply implemented using a for loop:

const arr = [5, 6, 0, 7, 8];
const num = 0;

let sum = 0;
for (let i = 0; i < arr.length; i++) {
  if (arr[i] == num) break;
  sum += arr[i];
}
console.log(sum);```
</div>
</div>
</p>

<p>If you want to use <code>reduce</code>, you need to keep a flag that says whether you have seen the <code>num</code> value so you can stop adding values from the array:</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>const arr = [5, 6, 0, 7, 8];

const sum = (arr, num) => {
  let seen = false;
  return arr.reduce((c, v) => {
    if (seen || v == num) {
      seen = true;
      return c;
    }
    return c + v;
  }, 0);
}

console.log(sum(arr, 0));
console.log(sum(arr, 8));</code>```

Body:
const arr = [5,6,0,7,8];
const sum = (arr,num) => arr.reduce((total)=>(num==0 ? total : total+num), 0)
console.log(sum(arr, 0))

Please check how can I make it work. Did some mistake but don't know what exactly. Output is a function instead of a result.

Body:
Since you need to stop summing values part way through the array, this might be most simply implemented using a for loop:

const arr = [5, 6, 0, 7, 8];
const num = 0;

let sum = 0;
for (let i = 0; i < arr.length; i++) {
  if (arr[i] == num) break;
  sum += arr[i];
}
console.log(sum);

If you want to use reduce, you need to keep a flag that says whether you have seen the num value so you can stop adding values from the array:

const arr = [5, 6, 0, 7, 8];

const sum = (arr, num) => {
  let seen = false;
  return arr.reduce((c, v) => {
    if (seen || v == num) {
      seen = true;
      return c;
    }
    return c + v;
  }, 0);
}

console.log(sum(arr, 0));
console.log(sum(arr, 8));


问:
Why am I getting "Trying to get property 'username' of non-object" when trying to access "$comment->users->username"?
I'm trying to get the usernames of the users who have posted comments, however, I keep getting "Trying to get property 'username' of non-object" error. I believe my relationships are done correctly but I might be wrong.

My tables:

```<code>Table: Users
Columns: id, username, password

Table: Comments
Columns: id, user_id, image_id, comment
</code>```

Comment model:

```<code>class Comment extends Model
{
    public function users(){
        return $this->belongsTo('App\User');
    }
}
</code>```

User model:

```<code>class User extends Model implements Authenticatable
{
    public function comments(){
        return $this->hasMany('App\Comment');
    }
}
</code>```

I'm getting the comments like this:

```<code>$comments = Comment::with('users')->where('image_id', $id)->get();
</code>```

And then trying to loop through them in the view like this:

```<code>@foreach($comments as $comment)
    <p>{{ $comment->comment }}</p>
    <p>{{ $comment->users->username }}</p>
@endforeach
</code>```

And when I dd($comments), I see:

```<code> #relations: array:1 [▼
        "users" => null
 ]
</code>```

I'm not sure why is it null though.

答:
```<code>@foreach($comments as $comment)
<p>{{ $comment->comment }}</p>
<p>{{ optional($comment->users)->username}}</p>
@endforeach
</code>```

Try this approach.

Body:
I'm trying to get the usernames of the users who have posted comments, however, I keep getting "Trying to get property 'username' of non-object" error. I believe my relationships are done correctly but I might be wrong.

My tables:

Table: Users
Columns: id, username, password

Table: Comments
Columns: id, user_id, image_id, comment

Comment model:

class Comment extends Model
{
    public function users(){
        return $this->belongsTo('App\User');
    }
}

User model:

class User extends Model implements Authenticatable
{
    public function comments(){
        return $this->hasMany('App\Comment');
    }
}

I'm getting the comments like this:

$comments = Comment::with('users')->where('image_id', $id)->get();

And then trying to loop through them in the view like this:

@foreach($comments as $comment)

{{ $comment->comment }}

{{ $comment->users->username }}

@endforeach

And when I dd($comments), I see:

 #relations: array:1 [▼
        "users" => null
 ]

I'm not sure why is it null though.

Body:
@foreach($comments as $comment)
<p>{{ $comment->comment }}</p>
<p>{{ optional($comment->users)->username}}</p>
@endforeach

Try this approach.


问:
Handling AVPlayerLayer when wrapping AVPlayer behaviour
I'm trying to wrap AVPlayer in my own class so I can provide a nicer API to use throughout my app and so I can mock player behaviour for testing with other objects (and because the AVPlayer KVOs are quite ugly to use!). Here's a simplified model of what I'm trying to do with just the play and pause functionality:

```<code>protocol VideoPlayerProtocol {
    func play()
    func pause()
}

class AVPlayerWrapped: VideoPlayerProtocol {

    private let player = AVPlayer()

    init(playerItem: AVPlayerItem) {
        self.player.replaceCurrentItem(with: playerItem)
    }

    func play() {
        player.play()
    }

    func pause() {
        player.pause()
    }
}
</code>```

I also have a PlayerView which adds an AVPlayerLayer to a view. From the Apple docs, this is set by providing the view an AVPlayer:

```<code>class PlayerView: UIView {

    override class var layerClass: AnyClass {
        return AVPlayerLayer.self
    }

    var playerLayer: AVPlayerLayer {
        return layer as! AVPlayerLayer
    }

    var player: AVPlayer? {
        get { playerLayer.player }
        set { playerLayer.player = newValue }
    }
}
</code>```

The problem is that when I setup an AVPlayerWrapped object, in order to display the playback in a view I need to reveal the underlying AVPlayer to the player property on PlayerView which defeats the purpose of me wrapping the player.

Is there a way for me to somehow use an AVPlayerLayer without my AVPlayerWrapped having to reveal its underlying player please? Or am I taking the wrong approach?

Any guidance much appreciated!

答:
```<code>class AVPlayerWrapped: VideoPlayerProtocol {

    fileprivate let player = AVPlayer()

    init(playerItem: AVPlayerItem) {
        self.player.replaceCurrentItem(with: playerItem)
    }

    func play() {
        player.play()
    }

    func pause() {
        player.pause()
    }
}

extension AVPlayerLayer {
    func setPlayerWrapper(_ playerWrapped: AVPlayerWrapped) {
        player = playerWrapped.player
    }
}
</code>```

And

```<code>class PlayerView: UIView {

    override class var layerClass: AnyClass {
        return AVPlayerLayer.self
    }

    var playerLayer: AVPlayerLayer {
        return layer as! AVPlayerLayer
    }

    func setPlayerWrapper(_ playerWrapped: AVPlayerWrapped) {
        playerLayer.setPlayerWrapper(playerWrapped)
    }
}
</code>```

I believe you don't need a getter for your view - in my practice I haven't used it. But in case you do, you can do it with an associatedObject, but it's much slower than a real property and I would advise you to use this approach only in special cases.

Body:
I'm trying to wrap AVPlayer in my own class so I can provide a nicer API to use throughout my app and so I can mock player behaviour for testing with other objects (and because the AVPlayer KVOs are quite ugly to use!). Here's a simplified model of what I'm trying to do with just the play and pause functionality:

protocol VideoPlayerProtocol {
    func play()
    func pause()
}

class AVPlayerWrapped: VideoPlayerProtocol {

    private let player = AVPlayer()

    init(playerItem: AVPlayerItem) {
        self.player.replaceCurrentItem(with: playerItem)
    }

    func play() {
        player.play()
    }

    func pause() {
        player.pause()
    }
}

I also have a PlayerView which adds an AVPlayerLayer to a view. From the Apple docs, this is set by providing the view an AVPlayer:

class PlayerView: UIView {

    override class var layerClass: AnyClass {
        return AVPlayerLayer.self
    }

    var playerLayer: AVPlayerLayer {
        return layer as! AVPlayerLayer
    }

    var player: AVPlayer? {
        get { playerLayer.player }
        set { playerLayer.player = newValue }
    }
}

The problem is that when I setup an AVPlayerWrapped object, in order to display the playback in a view I need to reveal the underlying AVPlayer to the player property on PlayerView which defeats the purpose of me wrapping the player.

Is there a way for me to somehow use an AVPlayerLayer without my AVPlayerWrapped having to reveal its underlying player please? Or am I taking the wrong approach?

Any guidance much appreciated!

Body:
class AVPlayerWrapped: VideoPlayerProtocol {

    fileprivate let player = AVPlayer()

    init(playerItem: AVPlayerItem) {
        self.player.replaceCurrentItem(with: playerItem)
    }

    func play() {
        player.play()
    }

    func pause() {
        player.pause()
    }
}

extension AVPlayerLayer {
    func setPlayerWrapper(_ playerWrapped: AVPlayerWrapped) {
        player = playerWrapped.player
    }
}

And

class PlayerView: UIView {

    override class var layerClass: AnyClass {
        return AVPlayerLayer.self
    }

    var playerLayer: AVPlayerLayer {
        return layer as! AVPlayerLayer
    }

    func setPlayerWrapper(_ playerWrapped: AVPlayerWrapped) {
        playerLayer.setPlayerWrapper(playerWrapped)
    }
}

I believe you don't need a getter for your view - in my practice I haven't used it. But in case you do, you can do it with an associatedObject, but it's much slower than a real property and I would advise you to use this approach only in special cases.


问:
Should screen reader announce short form label or long form value?
I have an Australian state dropdown.

The label is like ACT, VIC, NSW (short form)

But the value is like Australian Capital Territory, Victoria (long form)

Should the screen reader announce the short form or the long form?

答:
First of all, it's nearly always a bad idea to have a difference between what is written and what is spoken, for at least two reasons:

Blind people aren't the only ones to use screen readers. There are also partially sighted people, people with dyslexia or cognitive impairments. For these people you create a useless contradiction in their brain.

In braille, should you consider the written text because braille is a form of writing, or the accessible label (corresponding to the spoken text)? All screen readers don't answer equally to this question and/or have settings to decide

Now, you could certainly ask what is the best to show in your list: the short or the long form, independently of pure design constraints.

For this question, there is no definitive answer best suited for all cases.

In fact you have four possibilities:

Short form alone, i.e. "VIC"

Long form alone, i.e. "Victoria"

Both, short form first, then long form, such as "VIC - Victoria"

Both, long form first, then short form, such as "Victoria (VIC)"

The following points can help you decide:

How many elements there are in the list ? 5, 10, 20, 50, 100, more ? The more elements there are, the less it's intuitive to use short form only

Can the user type the first letters of the short and/or long form in order to quickly find the corresponding element in the list ? Only the very first letter, or several (possibly three or four) ? Above 10 or 15 elements, you should almost always allow full letter navigation and not only the first letter

How well are the abbreviations known to the users ? Are they used to using them ?

What are users usually writing and expect to read?

How similar the short form compared to the long one ? e.g. difficulty to find "Victoria" only based on the abbreviation, if it is "VIC" compared to if it was something less obviously related like "VCT".

You are talking about Australian states. I don't know Australia at all, but I assume that there aren't more than a few dozens options, and if your site is mostly made for Australians, they are certainly used to the short form.
So it shouldn't be a major problem to keep the short form only.
If you want to be more foreigner-friendly, you might have both.


问:
How to sort list of string in ascending way?
I have a list of strings. They are actually files.

```<code>image_files = ["1.jpg", "3.jpg", "2.jpg", "4.jpg", "6.jpg", "5.jpg", "20.jpg", "29.jpg", "11.jpg", "9.jpg"]
</code>```

I want to sort them like:

```<code>['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg', '6.jpg', '9.jpg', '11.jpg', '20.jpg', '29.jpg']
</code>```

I tried with sorted(image_files, key = len) but failed.

答:
This can be done in many ways. But the code which I made I tried making it as elaborative and conception as possible I tried breaking each part in many subparts which can be done easily but to make understanding of the viewer tougher I broke the code into 3 parts the first part takes all the num value then second part sorts it in asc order then third part brings the whole file and makes a new list.i also put a feature that would accept duplicate values without any error I also added new items in image_list for improved understanding of viewer.

```<code>    image_files = ["1.jpg", "3.jpg", "2.jpg", "4.jpg", "6.jpg", "5.jpg", "20.jpg", "29.jpg", "11.jpg", "9.jpg","5.img","6.img","100.png","20.jpg"]
    name_of_folder_list = [] #list of ints in the fine name
    for i in image_files:
        num = i.split('.')[0]
        name_of_folder_list.append(int(num))
    asc_name_of_folder_list = sorted(name_of_folder_list, reverse=False)#sorting the number list in ascending order
    output_list = []
    for i in asc_name_of_folder_list:
        for j in image_files:
            if int(j.split('.')[0]) == int(i):
                output_list.append(j)#this will add the item to new list
                image_files.remove(j)#this will remove from old list avoiding double values of duplicates

            else:
                pass

print(output_list)
</code>```

the output is:

```<code>['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg', '5.img', '6.jpg', '6.img', '9.jpg', '11.jpg', '20.jpg', '20.jpg', '29.jpg', '100.png']

Process finished with exit code 0
</code>```

This works with any format and is easily understood by beginners too.

Hope this helps you

Body:
I have a list of strings. They are actually files.

image_files = ["1.jpg", "3.jpg", "2.jpg", "4.jpg", "6.jpg", "5.jpg", "20.jpg", "29.jpg", "11.jpg", "9.jpg"]

I want to sort them like:

['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg', '6.jpg', '9.jpg', '11.jpg', '20.jpg', '29.jpg']

I tried with sorted(image_files, key = len) but failed.

Body:
This can be done in many ways. But the code which I made I tried making it as elaborative and conception as possible I tried breaking each part in many subparts which can be done easily but to make understanding of the viewer tougher I broke the code into 3 parts the first part takes all the num value then second part sorts it in asc order then third part brings the whole file and makes a new list.i also put a feature that would accept duplicate values without any error I also added new items in image_list for improved understanding of viewer.

    image_files = ["1.jpg", "3.jpg", "2.jpg", "4.jpg", "6.jpg", "5.jpg", "20.jpg", "29.jpg", "11.jpg", "9.jpg","5.img","6.img","100.png","20.jpg"]
    name_of_folder_list = [] #list of ints in the fine name
    for i in image_files:
        num = i.split('.')[0]
        name_of_folder_list.append(int(num))
    asc_name_of_folder_list = sorted(name_of_folder_list, reverse=False)#sorting the number list in ascending order
    output_list = []
    for i in asc_name_of_folder_list:
        for j in image_files:
            if int(j.split('.')[0]) == int(i):
                output_list.append(j)#this will add the item to new list
                image_files.remove(j)#this will remove from old list avoiding double values of duplicates

            else:
                pass

print(output_list)

the output is:

['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg', '5.img', '6.jpg', '6.img', '9.jpg', '11.jpg', '20.jpg', '20.jpg', '29.jpg', '100.png']

Process finished with exit code 0

This works with any format and is easily understood by beginners too.

Hope this helps you


问:
Preserving white space through XML/XSLT processing chain

User types text into a multi-line text box in the browser

Data is stored as part of an XML snippet in a  SQL Server xml column

XML snippet is later incorporated into a larger xml document

Document is processed via XSLT into an HTML email

Recipient is expected to see the original line breaks

I tried:

CDATA (removed by SQL)

 tag in the output around the comments and encoding of the NL character

encoded
 tag in the data (does not get decoded in the HTML)

Can this be done without rearchitecting everything?

Per request in the comments, here is the actual code:

The XSL

```<code><TD>
    <xsl:value-of select="//MemoComment"/>
</TD>
</code>```

Variations of input data into the XSLT

<MemoComment>Previous job: Associate, Boston
Test1
Test2</MemoComment>

<MemoComment>Previous job: Associate, Boston \nTest1 \nTest2</MemoComment>

<MemoComment>Previous job: Associate, Boston
Test1
Test2</MemoComment>

Corresponding XSLT Results

Previous job: Associate, BostonTest1Test2

Previous job: Associate, Boston\nTest1\nTest2

Previous job: Associate, Boston
Test1
Test2

None of which renders correctly in Outlook.

答:
Reason for your problem was that you used <xsl:value-of>

```<code><TD>
    <xsl:value-of select="//MemoComment"/>
</TD>
</code>```

when you actually needed <xsl:copy-of>

```<code><TD>
    <xsl:copy-of select="//MemoComment/node()"/>
</TD>
</code>```

<xsl:value-of> only selects the string value of the selected node. What you actually wanted is to copy of whole node including the elements that it contained. Then you can save the data as a formatted XHTML snippet without the need of element syntax escaping (format number 1 on your input list).

Usage of disabe-output-escaping="yes" is often discouraged because it can lead to outputting malformed XML. Also all XSLT processors don't implement this feature since it actually takes effect only when the document is serialized, and might not have any effect if the output document is passed on from the processor as a data structure.

Body:
User types text into a multi-line text box in the browser

Data is stored as part of an XML snippet in a  SQL Server xml column

XML snippet is later incorporated into a larger xml document

Document is processed via XSLT into an HTML email

Recipient is expected to see the original line breaks

I tried:

CDATA (removed by SQL)

 tag in the output around the comments and encoding of the NL character

encoded
 tag in the data (does not get decoded in the HTML)

Can this be done without rearchitecting everything?

Per request in the comments, here is the actual code:

The XSL

    <xsl:value-of select="//MemoComment"/>

Variations of input data into the XSLT

<MemoComment>Previous job: Associate, Boston
Test1
Test2</MemoComment>

<MemoComment>Previous job: Associate, Boston &#xA;Test1 &#xA;Test2</MemoComment>

<MemoComment>Previous job: Associate, Boston&lt;br/&gt;Test1
Test2</MemoComment>

Corresponding XSLT Results

Previous job: Associate, BostonTest1Test2

Previous job: Associate, Boston&#xA;Test1&#xA;Test2

Previous job: Associate, Boston&lt;br/&gt;Test1
Test2

None of which renders correctly in Outlook.

Body:
Reason for your problem was that you used <xsl:value-of>

<TD>
    <xsl:value-of select="//MemoComment"/>
</TD>

when you actually needed <xsl:copy-of>

<TD>
    <xsl:copy-of select="//MemoComment/node()"/>
</TD>

<xsl:value-of> only selects the string value of the selected node. What you actually wanted is to copy of whole node including the elements that it contained. Then you can save the data as a formatted XHTML snippet without the need of element syntax escaping (format number 1 on your input list).

Usage of disabe-output-escaping="yes" is often discouraged because it can lead to outputting malformed XML. Also all XSLT processors don't implement this feature since it actually takes effect only when the document is serialized, and might not have any effect if the output document is passed on from the processor as a data structure.


问:
how to parse json where key is variable using scala play json reader?
how can i access i4x-IITB-CS101-problem-33e4aac93dc84f368c93b1d08fa984fc_2_1 key and data inside this key ? I have never seen an example json reader that describes how the reader works when the key attribute is a variable such as below example.</p>

```<code>{
    "username": "batista",
    "event_type": "problem_check",
    "ip": "127.0.0.1",
    "event": {
        "submission": {
            "i4x-IITB-CS101-problem-33e4aac93dc84f368c93b1d08fa984fc_2_1": {
                "input_type": "choicegroup",
                "question": "",
                "response_type": "multiplechoiceresponse",
                "answer": "MenuInflater.inflate()",
                "variant": "",
                "correct": true
            }
        },
        "success": "correct",
        "grade": 1,
        "correct_map": {
            "i4x-IITB-CS101-problem-33e4aac93dc84f368c93b1d08fa984fc_2_1": {
                "hint": "",
                "hintmode": null,
                "correctness": "correct",
                "npoints": null,
                "msg": "",
                "queuestate": null
            }
        }
</code>```

答:
You may use an iterator. Don't know the exact structure of your json and how flexible it is, but you get the idea with this Java code.</p>

```<code>JsonNode events = jsonOutput.get("event");
for (Iterator<JsonNode> it = invoices.iterator(); it.hasNext(); ){
    // With this line you will get submission, success, grade and correct_map.
    JsonNode node = it.next();

    // if e.g. submission always has one element it is accessible through node.get(0),
    // you may also iterate through e.g. node.elements()
}
</code>```

Body:
how can i access i4x-IITB-CS101-problem-33e4aac93dc84f368c93b1d08fa984fc_2_1 key and data inside this key ? I have never seen an example json reader that describes how the reader works when the key attribute is a variable such as below example.

{
    "username": "batista",
    "event_type": "problem_check",
    "ip": "127.0.0.1",
    "event": {
        "submission": {
            "i4x-IITB-CS101-problem-33e4aac93dc84f368c93b1d08fa984fc_2_1": {
                "input_type": "choicegroup",
                "question": "",
                "response_type": "multiplechoiceresponse",
                "answer": "MenuInflater.inflate()",
                "variant": "",
                "correct": true
            }
        },
        "success": "correct",
        "grade": 1,
        "correct_map": {
            "i4x-IITB-CS101-problem-33e4aac93dc84f368c93b1d08fa984fc_2_1": {
                "hint": "",
                "hintmode": null,
                "correctness": "correct",
                "npoints": null,
                "msg": "",
                "queuestate": null
            }
        }

Body:
You may use an iterator. Don't know the exact structure of your json and how flexible it is, but you get the idea with this Java code.

JsonNode events = jsonOutput.get("event");
for (Iterator<JsonNode> it = invoices.iterator(); it.hasNext(); ){
    // With this line you will get submission, success, grade and correct_map.
    JsonNode node = it.next();

    // if e.g. submission always has one element it is accessible through node.get(0),
    // you may also iterate through e.g. node.elements()
}


问:
column-wise correlation between all pairs of columns of two data frame
Hi so I have created a function to check the correlation between 2 variables, anyone knows how can I create a new data frame from this?

```<code>In [1]:from scipy.stats import pearsonr
for colY in Y.columns:
    for colX in X.columns:
    #print('Pearson Correlation')
        corr, _ = pearsonr(numerical_cols_target[colX], numerical_cols_target[colY])
        alpha = 0.05
        print('Pearson Correlation', (alpha, corr))
        if corr <= alpha:
            print(colX +' and ' +colY+ ' two ariables are not correlated ')
        else:
            print(colX +' and ' +colY+ ' two variables are highly correlated ')
        print('\n')
    print('\n')
</code>```

here's a sample output from the correlation function:

```<code>Out [1]:
Pearson Correlation (0.05, -0.1620045985125294)
banana and orange are not correlated

Pearson Correlation (0.05, 0.2267582070839226)
apple and orange are highly correlated
```
```

答:
You can just do the following.

df = pd.DataFrame(index=X.columns, columns=Y.columns)

#In your loop
df[colY][colX] = corr
```

<p>Your loop would then be</p>

<pre class="lang-py prettyprint-override"><code>for colY in Y.columns:
    for colX in X.columns:
    #print('Pearson Correlation')
        corr, _ = pearsonr(numerical_cols_target[colX], numerical_cols_target[colY])
        alpha = 0.05
        print('Pearson Correlation', (alpha, corr))
        df[colY][colX] = corr
        if corr <= alpha:
            print(colX +' and ' +colY+ ' two ariables are not correlated ')
        else:
            print(colX +' and ' +colY+ ' two variables are highly correlated ')
        print('\n')
    print('\n')
</code>```

Body:
Hi so I have created a function to check the correlation between 2 variables, anyone knows how can I create a new data frame from this?

In [1]:from scipy.stats import pearsonr
for colY in Y.columns:
    for colX in X.columns:
    #print('Pearson Correlation')
        corr, _ = pearsonr(numerical_cols_target[colX], numerical_cols_target[colY])
        alpha = 0.05
        print('Pearson Correlation', (alpha, corr))
        if corr <= alpha:
            print(colX +' and ' +colY+ ' two ariables are not correlated ')
        else:
            print(colX +' and ' +colY+ ' two variables are highly correlated ')
        print('\n')
    print('\n')

here's a sample output from the correlation function:

Out [1]:
Pearson Correlation (0.05, -0.1620045985125294)
banana and orange are not correlated

Pearson Correlation (0.05, 0.2267582070839226)
apple and orange are highly correlated
```

Body:
You can just do the following.

df = pd.DataFrame(index=X.columns, columns=Y.columns)

#In your loop
df[colY][colX] = corr

Your loop would then be

for colY in Y.columns:
    for colX in X.columns:
    #print('Pearson Correlation')
        corr, _ = pearsonr(numerical_cols_target[colX], numerical_cols_target[colY])
        alpha = 0.05
        print('Pearson Correlation', (alpha, corr))
        df[colY][colX] = corr
        if corr <= alpha:
            print(colX +' and ' +colY+ ' two ariables are not correlated ')
        else:
            print(colX +' and ' +colY+ ' two variables are highly correlated ')
        print('\n')
    print('\n')


问:
Symfony and doctrine issues
I did not use the sudo when installing doctrine in symfony
So this is what i got..

```<code>The "https://flex.symfony.com/aliases.json" file could not be downloaded: failed to open stream: Connection refused https://flex.symfony.com/aliases.json could not be fully loaded, package information was loaded from the local cache and may be out of date
to fix that i did this curl -XGET https://flex.symfony.com/aliases.json
</code>```

and then i installed composer require symfony/orm-pack composer require --dev symfony/maker-bundle

The problem is that it wont add any db config in the env file....
and when i do the composer require doctrine
i get this

```<code>Pontuss-MacBook-Air:cauldron_overflow Pontus$ composer require doctrine
Using version ^1.0 for symfony/orm-pack
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Restricting packages listed in "symfony/symfony" to "4.4.*"
Nothing to install or update
Package zendframework/zend-code is abandoned, you should avoid using it. Use laminas/laminas-code instead.
Package zendframework/zend-eventmanager is abandoned, you should avoid using it. Use laminas/laminas-eventmanager instead.
Generating autoload files
34 packages you are using are looking for funding.
Use thecomposer fundcommand to find out more!
ocramius/package-versions:  Generating version class...
ocramius/package-versions: ...done generating version class
Executing script cache:clear [OK]
Executing script assets:install public [OK]
Executing script security-checker security:check [OK]
</code>```

So why wont it add the correct data to my env files?
Please any advice

答:
When you install a recipe it installs some sample data to your .env.dist file.

This is only for the first run when you install the recipe. After the install you can do what you want and remove that variables and use it from your Docker for example. So perhaps i don't understood your problem because you wrote that you don't want db config in your env file and in the last line you write that it won't add it.

https://symfony.com/doc/current/configuration.html

I know you use flex but there are some good examples how to use and how to do it. Flex should use the DotEnv-Component.

The last thing is your error (https://flex.symfony.com/aliases.json). I think you have firewall that blocks the load of the aliases file. So you have to check that first. That call should work if you run it in your browser or with curl. Otherwise it could give a problem to load all components.

Title: Symfony and doctrine issues

Body:
I did not use the sudo when installing doctrine in symfony
So this is what i got..

The "https://flex.symfony.com/aliases.json" file could not be downloaded: failed to open stream: Connection refused https://flex.symfony.com/aliases.json could not be fully loaded, package information was loaded from the local cache and may be out of date
to fix that i did this curl -XGET https://flex.symfony.com/aliases.json

and then i installed composer require symfony/orm-pack composer require --dev symfony/maker-bundle

The problem is that it wont add any db config in the env file....
and when i do the composer require doctrine
i get this

Pontuss-MacBook-Air:cauldron_overflow Pontus$ composer require doctrine
Using version ^1.0 for symfony/orm-pack
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Restricting packages listed in "symfony/symfony" to "4.4.*"
Nothing to install or update
Package zendframework/zend-code is abandoned, you should avoid using it. Use laminas/laminas-code instead.
Package zendframework/zend-eventmanager is abandoned, you should avoid using it. Use laminas/laminas-eventmanager instead.
Generating autoload files
34 packages you are using are looking for funding.
Use thecomposer fundcommand to find out more!
ocramius/package-versions:  Generating version class...
ocramius/package-versions: ...done generating version class
Executing script cache:clear [OK]
Executing script assets:install public [OK]
Executing script security-checker security:check [OK]

So why wont it add the correct data to my env files?
Please any advice


问:
OnBuffer props in react-native-video is not working
I am using react-native-video for playing videos from url. I am using onBuffer prop to show loader if the video is buffering. But in my case onBuffer is not working. If the video size is large then in case of a slow network or unstable network video is taking time to play, so I want to show loader if the video is not playing but in buffering mode. </p>

答:
You can use onLoad and onEnd prop of react-native-video to show loader.

For Example

```<code><Video
    poster={/*uri*/}
    posterResizeMode="cover"
    source={/*source*/}
    onLoad={()=>/* set loader to true*/}
    onEnd={()=>/* set loader to false*/}
  />
</code>```

Body:
You can use onLoad and onEnd prop of react-native-video to show loader.

For Example

<Video
    poster={/*uri*/}
    posterResizeMode="cover"
    source={/*source*/}
    onLoad={()=>/* set loader to true*/}
    onEnd={()=>/* set loader to false*/}
  />


问:
Extracting ListItems from a List in a SharePoint Site
I am trying to extract a list of items in a SharePoint Site below the root site at host.sharepoint.com/sites/mysite. I've tried a bunch of different methods, but only one seems to work:

```<code>var host        = "host.sharepoint.com:/";
var siteName    = "mysite";
var listName    = "MyList";

// Generate the Client Connection
var graphHelper = new ApplicationAuthenticatedClient(ClientId, Tenant, ClientSecret);
await graphHelper.ConnectAsync().ConfigureAwait(false);

// Code: itemNotFound
//Message: The provided path does not exist, or does not represent a site
//var list = await graphHelper.GraphClient.Sites[$"{host}{siteName}"].Request().GetAsync();

// Returns a Site, no Lists.
//var list = await graphHelper.GraphClient.Sites[host].Sites[siteName].Request().GetAsync();

//Code: itemNotFound
//Message: The provided path does not exist, or does not represent a site
//var list = await graphHelper.GraphClient.Sites[host].Sites[siteName].Lists[listName].Request().GetAsync();

// List retrieved, but no Items
//var site = await graphHelper.GraphClient.Sites[host].Sites[siteName].Request().Expand("lists").GetAsync();
//var list = await graphHelper.GraphClient.Sites[site.Id].Lists[listName].Request().Expand("Items").GetAsync();

//Code: invalidRequest
//Message: Can only provide expand and select for expand options
//var queryOptions = new List<QueryOption>() { new QueryOption("expand", "fields") };

// This works
var site = await graphHelper.GraphClient.Sites[host].Sites[siteName].Request().GetAsync();
var list = await graphHelper.GraphClient.Sites[site.Id].Lists[listName].Items.Request().Expand("Fields").GetAsync();
</code>```

I've finally managed to get it to connect, but I'm wondering if there's a better way to navigate to the list, rather than the two API calls? (Assuming that I don't know the Site ID beforehand)

Edit: Using the Graph Explorer, I can access the items using https://graph.microsoft.com/v1.0/sites/{host}.sharepoint.com:/sites/{siteName}:/lists/{listName}/items?expand=fields, but I don't know how to  (or if) access that API call in a single call in the .NET API.

答:
It appears that I was on the right track with var list = await graphHelper.GraphClient.Sites[$"{host}{siteName}"].Request().GetAsync(); but the URI was not formatted correctly.

The correct Site ID for https://host.sharepoint.com/sites/mysite/MyList is:

```<code>Sites[host.sharepoint.com:/sites/mysite:"]
</code>```

Retrieving the list from the code in my original question would look like this:

```<code>var host        = "host.sharepoint.com";
var siteName    = "mysite";
var listName    = "MyList";

// Generate the Client Connection
var graphHelper = new ApplicationAuthenticatedClient(ClientId, Tenant, ClientSecret);
await graphHelper.ConnectAsync().ConfigureAwait(false);

var list = await graphHelper.GraphClient.Sites[$"{host}:/sites/{siteName}:"].Lists[listName].Request().GetAsync();
</code>```

Body:
I am trying to extract a list of items in a SharePoint Site below the root site at host.sharepoint.com/sites/mysite. I've tried a bunch of different methods, but only one seems to work:

var host        = "host.sharepoint.com:/";
var siteName    = "mysite";
var listName    = "MyList";

// Generate the Client Connection
var graphHelper = new ApplicationAuthenticatedClient(ClientId, Tenant, ClientSecret);
await graphHelper.ConnectAsync().ConfigureAwait(false);

// Code: itemNotFound
//Message: The provided path does not exist, or does not represent a site
//var list = await graphHelper.GraphClient.Sites[$"{host}{siteName}"].Request().GetAsync();

// Returns a Site, no Lists.
//var list = await graphHelper.GraphClient.Sites[host].Sites[siteName].Request().GetAsync();

//Code: itemNotFound
//Message: The provided path does not exist, or does not represent a site
//var list = await graphHelper.GraphClient.Sites[host].Sites[siteName].Lists[listName].Request().GetAsync();

// List retrieved, but no Items
//var site = await graphHelper.GraphClient.Sites[host].Sites[siteName].Request().Expand("lists").GetAsync();
//var list = await graphHelper.GraphClient.Sites[site.Id].Lists[listName].Request().Expand("Items").GetAsync();

//Code: invalidRequest
//Message: Can only provide expand and select for expand options
//var queryOptions = new List<QueryOption>() { new QueryOption("expand", "fields") };

// This works
var site = await graphHelper.GraphClient.Sites[host].Sites[siteName].Request().GetAsync();
var list = await graphHelper.GraphClient.Sites[site.Id].Lists[listName].Items.Request().Expand("Fields").GetAsync();

I've finally managed to get it to connect, but I'm wondering if there's a better way to navigate to the list, rather than the two API calls? (Assuming that I don't know the Site ID beforehand)

Edit: Using the Graph Explorer, I can access the items using https://graph.microsoft.com/v1.0/sites/{host}.sharepoint.com:/sites/{siteName}:/lists/{listName}/items?expand=fields, but I don't know how to  (or if) access that API call in a single call in the .NET API.

Body:
It appears that I was on the right track with var list = await graphHelper.GraphClient.Sites[$"{host}{siteName}"].Request().GetAsync(); but the URI was not formatted correctly.

The correct Site ID for https://host.sharepoint.com/sites/mysite/MyList is:

Sites[host.sharepoint.com:/sites/mysite:"]

Retrieving the list from the code in my original question would look like this:

var host        = "host.sharepoint.com";
var siteName    = "mysite";
var listName    = "MyList";

// Generate the Client Connection
var graphHelper = new ApplicationAuthenticatedClient(ClientId, Tenant, ClientSecret);
await graphHelper.ConnectAsync().ConfigureAwait(false);

var list = await graphHelper.GraphClient.Sites[$"{host}:/sites/{siteName}:"].Lists[listName].Request().GetAsync();


问:
Visual Studio 2019 - Function Syntax Highlight in Gold (Olive)
Starting with Visual Studio 2019, the syntax highlighter now colors functions in a goldish color (actually called Olive I guess). Since yesterday, somehow this no longer works.

I went to Tools -> Options -> Fonts & Color, changed the Identifier to Olive but it actually switched most of the code to Olive.

For example, previously, AddGlobalServices, AddMvc, SetCompatibilityVersion and AddMemoryCache where Olive colored.

How can I fix this?

答:
Instead, go to Options -> Text Editor -> Basic -> Advanced -> Editor Color Scheme and set it to Visual Studio 2019

This way, the highlighting of functions and methods will change to Gold.


问:
What's the fastest way to delete a large folder in Windows?
I want to delete a folder that contains thousands of files and folders. If I use Windows Explorer to delete the folder it can take 10-15 minutes (not always, but often). Is there a faster way in Windows to delete folders?

Other details:

I don't care about the recycle bin.

It's an NTFS drive.

答:
The worst way is to send to Recycle Bin: you still need to delete them. Next worst is shift+delete with Windows Explorer: it wastes loads of time checking the contents before starting deleting anything.

Next best is to use rmdir /s/q foldername from the command line. del /f/s/q foldername is good too, but it leaves behind the directory structure.

The best I've found is a two line batch file with a first pass to delete files and outputs to nul to avoid the overhead of writing to screen for every singe file. A second pass then cleans up the remaining directory structure:

```<code>del /f/s/q foldername > nul
rmdir /s/q foldername
</code>```

This is nearly three times faster than a single rmdir, based on time tests with a Windows XP encrypted disk, deleting ~30GB/1,000,000 files/15,000 folders: rmdir takes ~2.5 hours, del+rmdir takes ~53 minutes. More info at Super User.

This is a regular task for me, so I usually move the stuff I need to delete to C:\stufftodelete and have those del+rmdir commands in a deletestuff.bat batch file. This is scheduled to run at night, but sometimes I need to run it during the day so the quicker the better.

Technet documentation for del command can be found here.  Additional info on the parameters used above:

/f - Force (i.e. delete files even if they're read only)

/s - Recursive / Include Subfolders (this definition from SS64, as technet simply states "specified files", which isn't helpful).

/q - Quiet (i.e. do not prompt user for confirmation)

Documentation for rmdir here.  Parameters are:

/s - Recursive (i.e. same as del's /s parameter)

/q - Quiet (i.e. same as del's /q parameter)

OwnerDisplayName: Brent Plump

LastEditorDisplayName: Mark Ingram

Body:
The worst way is to send to Recycle Bin: you still need to delete them. Next worst is shift+delete with Windows Explorer: it wastes loads of time checking the contents before starting deleting anything.

Next best is to use rmdir /s/q foldername from the command line. del /f/s/q foldername is good too, but it leaves behind the directory structure.

The best I've found is a two line batch file with a first pass to delete files and outputs to nul to avoid the overhead of writing to screen for every singe file. A second pass then cleans up the remaining directory structure:

del /f/s/q foldername > nul
rmdir /s/q foldername

This is nearly three times faster than a single rmdir, based on time tests with a Windows XP encrypted disk, deleting ~30GB/1,000,000 files/15,000 folders: rmdir takes ~2.5 hours, del+rmdir takes ~53 minutes. More info at Super User.

This is a regular task for me, so I usually move the stuff I need to delete to C:\stufftodelete and have those del+rmdir commands in a deletestuff.bat batch file. This is scheduled to run at night, but sometimes I need to run it during the day so the quicker the better.

Technet documentation for del command can be found here.  Additional info on the parameters used above:

/f - Force (i.e. delete files even if they're read only)

/s - Recursive / Include Subfolders (this definition from SS64, as technet simply states "specified files", which isn't helpful).

/q - Quiet (i.e. do not prompt user for confirmation)

Documentation for rmdir here.  Parameters are:

/s - Recursive (i.e. same as del's /s parameter)

/q - Quiet (i.e. same as del's /q parameter)


问:
Change JavaFX 11 implementation in IntelliJ from "build and run with jvm options inside IDE" to "create runtime image"

EDIT #3 (SOLUTION)

I have solved this issue using none of the proposed answers. At the end of this I have some folders and files that I can zip and send around, that do not require a java installation and that can be run by double-clicking a .bat-file. The following procedure worked for me:

Create a new gradle project from scratch

Add all modules/code into the src/main/java folder

create an AppLauncher.java that calls the main-method

move all fxml/css from inside one of the java-folders to the resources-folder

make sure your calls to fxml-/css-files are not being refactored erroneously and use the following code:

//Main start method
Parent root = FXMLLoader.load(new File("fxml/main.fxml").toURI().toURL());

//Other FXML loading operations
FXMLLoader loader = null;
try { loader = new FXMLLoader(new File("fxml/GRAPHISO_proof.fxml").toURI().toURL()); }
...
```

<p>and for stylesheets:</p>

<pre class="lang-java prettyprint-override"><code>scene.getStylesheets().add("file:///" + new File("css/text-field-red-border.css").getAbsolutePath().replace('\\', '/'));
</code>```

create module-info.java inside of src/main/java folder with this structure:

module XYZ {
    requires javafx.controls;
    requires javafx.graphics;
    requires java.desktop;
    requires javafx.fxml;
    requires javafx.base;

    opens main.controller to javafx.fxml;
    //Open ALL controller-modules (all of my modules have a controller-submodule, e.g. main/controller, dlog/controller, graphiso/controller, ...) to javafx.fxml
    //...

    exports main;
}
```

<ul>
<li><p>make sure gradle/wrapper/gradle-wrapper.properties is set to a not-so-old version of gradle (<code>distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip</code>)</p></li>
<li><p>use this as your build.gradle:</p></li>
</ul>

```buildscript {
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath 'org.openjfx:javafx-plugin:0.0.8'
        classpath 'com.github.jengelman.gradle.plugins:shadow:5.2.0'
    }
}

plugins {
    id 'java'
    id 'org.beryx.jlink' version '2.19.0'
}

apply plugin: 'org.openjfx.javafxplugin'
apply plugin: 'com.github.johnrengelman.shadow'

group 'org.example.abc'
version '1.0'

sourceCompatibility = 1.14

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

javafx {
    sdk = 'C:\\Program Files\\Java\\javafx-sdk-14.0.1'
    modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.base' ]
}

jlink {
    mainClassName = 'main.AppLauncher'
    launcher {
        name = 'Whatever you want as name'
    }
}

tasks.jlink.doLast {
    copy {
        from('src/main/resources')
        into("$buildDir/image/bin")
    }
    copy {
        from 'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\glass.dll',
             'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\javafx_font.dll',
             'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\prism_d3d.dll',
             'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\prism_sw.dll'
        into("$buildDir/image/bin")
    }
}
```

Note how I included some dll-files in tasks.jlink.doLast. Without them, the program keeps crashing and refers to the QuantumRenderer.

install openjdk-14.0.1 binaries and set your %JAVA_HOME% accordingly, also install openjfx-14.0.1 (program needs some DLLs as mentioned above)

Original Question

I am trying to create a runtime image from a project that I have implemented in JavaFX 11 by just using the "run configuration" functionality in IntelliJ. It seems to me a big problem here is that my knowledge of maven/gradle are almost non-existent and that those build tools are crucial for this step.

Inside of C:\Program Files\Java I've installed:

javafx-sdk-11.0.2 and

jdk-13.0.2

I configured the VM options inside IntellJ's "run configuration" to be --module-path "C:\Program Files\Java\javafx-sdk-11.0.2\lib" --add-modules javafx.controls,javafx.fxml and set the Main Class to "main.Main".

My project structure looks like this: Project folder structure

The highlighted Main.java is an usual Main-file (extending Application, calling launch(args) inside of main). It can load other windows located in the other packages. It is not a Launcher-file that doesn't extend Application and calls the actual main-file (as suggested by a few solutions for gradle-building).

Initially I've tried to get a .jar-file that can be run without any further parameters on Windows and Linux. After some reading I figured that this wouldn't be a clean solution and a lot of sources stated that in modern solutions the .jar-files will be put together and shipped with a .bat/.sh file that includes all necessary parameters.

My question is: How do I best proceed and which configurations/additional files do I need to transform this "click-to-run-inside-IDE" project into an "standalone-application" that I can share through e-mail or similar?

I have tried to create a new gradle project through IntelliJ (following https://openjfx.io/openjfx-docs) and copy-pasted the source files into src/main/java. I then tried out the provided build.gradle-file and - after that didn't work - made some changes suggested by various blogs/forums/etc. None of them allowed me to run the project through IntelliJ or from the command line.

Most of these approaches let me build the project but when trying to run using either "gradlew run" or calling the "java -jar file.jar" I got error messages due to class exceptions or saying I am still missing the javafx modules. I've also tried an approach to convert my current project into a gradle-project but that wouldn't even let me build the project afterwards.

EDIT #1 (JPackageScriptFX)

I have looked at the JPackageScriptFX-link. Now I am getting an installer (using mvn clean install) that works on my machine, but when running the resulting executable, I receive an error message that says "Failed to launch JVM".

What I have done so far is:

installed jdk-14.0.1 and set JAVA_HOME, installed wix311

created a new IntelliJ maven project called "bachelor_maven"

removed initial src-folder

added new module "ZKP_Inspector" and my old modules inside of the resulting src/main/java folder

added and edited src/main/logo/windows/duke.ico, the two pom.xml files and build_app.bat from JPackageScriptFX

implemented AppLauncher.java that calls Main.java

My configuration files:

New project structure: Imgur

pom.xml (Project level, bachelor_maven): Pastebin

pom.xml (module level, ZKP_Inspector): Pastebin

build_app.bat: Pastebin

EDIT #2

I tried removing --runtime-image target/java-runtime ^ from the jpackage parameters in the build_app.bat file as to let jpackage decide what to include. This increased the file size of the installer (as expected) but lead to the same error when trying to execute the resulting program.

I have also downloaded the JMOD files and used them in the jlink task in the build_app.bat as hinted here.

So I replaced --add-modules %detected_modules%,%manual_modules% ^ with

--module-path "C:\Program Files\Java\javafx-jmods-11.0.2" --add-modules %detected_modules%,%manual_modules%,javafx.controls,javafx.fxml

This produced another installer that ran fine and whose resulting program threw the same error.

答:
Alright, I will try to show how to achieve this with jlink only.
Suppose we have an example project in a directory 'C:\Users\Alexiy\IdeaProjects\AnotherBuildTool\rundir'. Its structure is:

```<code>/rundir
--classes [compilation output]
--source  [source code]
--images  [runtime image output]
</code>```

I have a class 'source\io\github\alexiyorlov\calculator\Program.java':

```<code>package io.github.alexiyorlov.calculator;

import javafx.application.Application;
import javafx.stage.Stage;
import java.nio.file.Path;
public class Program extends Application {

   @Override
   public void start(Stage primaryStage) throws Exception {
       System.out.println("I'm a simple application");
       primaryStage.show();
   }
}
</code>```

And an appropriate 'source\module-info.java':

```<code>module io.github.alexiyorlov{
   requires javafx.controls;
   requires javafx.graphics;
   exports io.github.alexiyorlov.calculator;
}
</code>```

If I want to make a runtime image out of this, the syntax of jlink command will be like this:

jlink --launcher [name for the launch script]=[reference to the main class]
--module-path '[separated list of project's dependency jars + compile output directory]' --add-modules [my module reference] --compress=2 --output [directory for the resulting runtime image]

So, for my example project it resolves into this command:

```<code>jlink
--launcher launch=io.github.alexiyorlov/io.github.alexiyorlov.calculator.Program
--module-path 'C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-controls\11.0.2\javafx-controls-11.0.2-win.jar;C:\Users\Alexiy\.m2\repository\org\junit\jupiter\junit-jupiter-engine\5.7.0-M1\junit-jupiter-engine-5.7.0-M1.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-base\11.0.2\javafx-base-11.0.2.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-base\11.0.2\javafx-base-11.0.2-win.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-graphics\11.0.2\javafx-graphics-11.0.2.jar;C:\Users\Alexiy\.m2\repository\dev\buildtool\json-tools\0.1.0\json-tools-0.1.0.jar;C:\Users\Alexiy\IdeaProjects\AnotherBuildTool\rundir\org\openjfx\javafx\11.0.2\javafx-11.0.2/.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-controls\11.0.2\javafx-controls-11.0.2.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-graphics\11.0.2\javafx-graphics-11.0.2-win.jar;C:\Users\Alexiy\IdeaProjects\AnotherBuildTool\rundir/classes'
--add-modules io.github.alexiyorlov
--compress=2
--output .\images\0.0.1
</code>```

It will create an image in a directory 'images\0.0.1' with start scripts '0.0.1\bin\launch'.

Note that I used an automated way to get the right argument for --module-path; be sure to include class output directory in it.

--add-modules specifies which modules of your application to include.

--output specifies a directory to put all files of the image.

--launcher specifies the name of the launch scripts and the correct reference to the main class after '='.

--compress=2 makes it to apply a ZIP compression to the image.

Feel free to request more info from me.

Body:
EDIT #3 (SOLUTION)

I have solved this issue using none of the proposed answers. At the end of this I have some folders and files that I can zip and send around, that do not require a java installation and that can be run by double-clicking a .bat-file. The following procedure worked for me:

Create a new gradle project from scratch

Add all modules/code into the src/main/java folder

create an AppLauncher.java that calls the main-method

move all fxml/css from inside one of the java-folders to the resources-folder

make sure your calls to fxml-/css-files are not being refactored erroneously and use the following code:

//Main start method
Parent root = FXMLLoader.load(new File("fxml/main.fxml").toURI().toURL());

//Other FXML loading operations
FXMLLoader loader = null;
try { loader = new FXMLLoader(new File("fxml/GRAPHISO_proof.fxml").toURI().toURL()); }
...

and for stylesheets:

scene.getStylesheets().add("file:///" + new File("css/text-field-red-border.css").getAbsolutePath().replace('\\', '/'));

create module-info.java inside of src/main/java folder with this structure:

module XYZ {
    requires javafx.controls;
    requires javafx.graphics;
    requires java.desktop;
    requires javafx.fxml;
    requires javafx.base;

    opens main.controller to javafx.fxml;
    //Open ALL controller-modules (all of my modules have a controller-submodule, e.g. main/controller, dlog/controller, graphiso/controller, ...) to javafx.fxml
    //...

    exports main;
}

make sure gradle/wrapper/gradle-wrapper.properties is set to a not-so-old version of gradle (distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip)

use this as your build.gradle:

buildscript {
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath 'org.openjfx:javafx-plugin:0.0.8'
        classpath 'com.github.jengelman.gradle.plugins:shadow:5.2.0'
    }
}

plugins {
    id 'java'
    id 'org.beryx.jlink' version '2.19.0'
}

apply plugin: 'org.openjfx.javafxplugin'
apply plugin: 'com.github.johnrengelman.shadow'

group 'org.example.abc'
version '1.0'

sourceCompatibility = 1.14

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

javafx {
    sdk = 'C:\\Program Files\\Java\\javafx-sdk-14.0.1'
    modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.base' ]
}

jlink {
    mainClassName = 'main.AppLauncher'
    launcher {
        name = 'Whatever you want as name'
    }
}

tasks.jlink.doLast {
    copy {
        from('src/main/resources')
        into("$buildDir/image/bin")
    }
    copy {
        from 'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\glass.dll',
             'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\javafx_font.dll',
             'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\prism_d3d.dll',
             'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\prism_sw.dll'
        into("$buildDir/image/bin")
    }
}

Note how I included some dll-files in tasks.jlink.doLast. Without them, the program keeps crashing and refers to the QuantumRenderer.

install openjdk-14.0.1 binaries and set your %JAVA_HOME% accordingly, also install openjfx-14.0.1 (program needs some DLLs as mentioned above)

Original Question

I am trying to create a runtime image from a project that I have implemented in JavaFX 11 by just using the "run configuration" functionality in IntelliJ. It seems to me a big problem here is that my knowledge of maven/gradle are almost non-existent and that those build tools are crucial for this step.

Inside of C:\Program Files\Java I've installed:

javafx-sdk-11.0.2 and

jdk-13.0.2

I configured the VM options inside IntellJ's "run configuration" to be --module-path "C:\Program Files\Java\javafx-sdk-11.0.2\lib" --add-modules javafx.controls,javafx.fxml and set the Main Class to "main.Main".

My project structure looks like this: Project folder structure

The highlighted Main.java is an usual Main-file (extending Application, calling launch(args) inside of main). It can load other windows located in the other packages. It is not a Launcher-file that doesn't extend Application and calls the actual main-file (as suggested by a few solutions for gradle-building).

Initially I've tried to get a .jar-file that can be run without any further parameters on Windows and Linux. After some reading I figured that this wouldn't be a clean solution and a lot of sources stated that in modern solutions the .jar-files will be put together and shipped with a .bat/.sh file that includes all necessary parameters.

My question is: How do I best proceed and which configurations/additional files do I need to transform this "click-to-run-inside-IDE" project into an "standalone-application" that I can share through e-mail or similar?

I have tried to create a new gradle project through IntelliJ (following https://openjfx.io/openjfx-docs) and copy-pasted the source files into src/main/java. I then tried out the provided build.gradle-file and - after that didn't work - made some changes suggested by various blogs/forums/etc. None of them allowed me to run the project through IntelliJ or from the command line.

Most of these approaches let me build the project but when trying to run using either "gradlew run" or calling the "java -jar file.jar" I got error messages due to class exceptions or saying I am still missing the javafx modules. I've also tried an approach to convert my current project into a gradle-project but that wouldn't even let me build the project afterwards.

EDIT #1 (JPackageScriptFX)

I have looked at the JPackageScriptFX-link. Now I am getting an installer (using mvn clean install) that works on my machine, but when running the resulting executable, I receive an error message that says "Failed to launch JVM".

What I have done so far is:

installed jdk-14.0.1 and set JAVA_HOME, installed wix311

created a new IntelliJ maven project called "bachelor_maven"

removed initial src-folder

added new module "ZKP_Inspector" and my old modules inside of the resulting src/main/java folder

added and edited src/main/logo/windows/duke.ico, the two pom.xml files and build_app.bat from JPackageScriptFX

implemented AppLauncher.java that calls Main.java

My configuration files:

New project structure: Imgur

pom.xml (Project level, bachelor_maven): Pastebin

pom.xml (module level, ZKP_Inspector): Pastebin

build_app.bat: Pastebin

EDIT #2

I tried removing --runtime-image target/java-runtime ^ from the jpackage parameters in the build_app.bat file as to let jpackage decide what to include. This increased the file size of the installer (as expected) but lead to the same error when trying to execute the resulting program.

I have also downloaded the JMOD files and used them in the jlink task in the build_app.bat as hinted here.

So I replaced --add-modules %detected_modules%,%manual_modules% ^ with

--module-path "C:\Program Files\Java\javafx-jmods-11.0.2" --add-modules %detected_modules%,%manual_modules%,javafx.controls,javafx.fxml

This produced another installer that ran fine and whose resulting program threw the same error.

Body:
Alright, I will try to show how to achieve this with jlink only.
Suppose we have an example project in a directory 'C:\Users\Alexiy\IdeaProjects\AnotherBuildTool\rundir'. Its structure is:

/rundir
--classes [compilation output]
--source  [source code]
--images  [runtime image output]

I have a class 'source\io\github\alexiyorlov\calculator\Program.java':

package io.github.alexiyorlov.calculator;

import javafx.application.Application;
import javafx.stage.Stage;
import java.nio.file.Path;
public class Program extends Application {

   @Override
   public void start(Stage primaryStage) throws Exception {
       System.out.println("I'm a simple application");
       primaryStage.show();
   }
}

And an appropriate 'source\module-info.java':

module io.github.alexiyorlov{
   requires javafx.controls;
   requires javafx.graphics;
   exports io.github.alexiyorlov.calculator;
}

If I want to make a runtime image out of this, the syntax of jlink command will be like this:

jlink --launcher [name for the launch script]=[reference to the main class]
--module-path '[separated list of project's dependency jars + compile output directory]' --add-modules [my module reference] --compress=2 --output [directory for the resulting runtime image]

So, for my example project it resolves into this command:

jlink
--launcher launch=io.github.alexiyorlov/io.github.alexiyorlov.calculator.Program
--module-path 'C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-controls\11.0.2\javafx-controls-11.0.2-win.jar;C:\Users\Alexiy\.m2\repository\org\junit\jupiter\junit-jupiter-engine\5.7.0-M1\junit-jupiter-engine-5.7.0-M1.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-base\11.0.2\javafx-base-11.0.2.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-base\11.0.2\javafx-base-11.0.2-win.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-graphics\11.0.2\javafx-graphics-11.0.2.jar;C:\Users\Alexiy\.m2\repository\dev\buildtool\json-tools\0.1.0\json-tools-0.1.0.jar;C:\Users\Alexiy\IdeaProjects\AnotherBuildTool\rundir\org\openjfx\javafx\11.0.2\javafx-11.0.2/.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-controls\11.0.2\javafx-controls-11.0.2.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-graphics\11.0.2\javafx-graphics-11.0.2-win.jar;C:\Users\Alexiy\IdeaProjects\AnotherBuildTool\rundir/classes'
--add-modules io.github.alexiyorlov
--compress=2
--output .\images\0.0.1

It will create an image in a directory 'images\0.0.1' with start scripts '0.0.1\bin\launch'.

Note that I used an automated way to get the right argument for --module-path; be sure to include class output directory in it.

--add-modules specifies which modules of your application to include.

--output specifies a directory to put all files of the image.

--launcher specifies the name of the launch scripts and the correct reference to the main class after '='.

--compress=2 makes it to apply a ZIP compression to the image.

Feel free to request more info from me.


问:
How can I get the HTML from a Microsoft.Toolkit WebView?
I am using Microsoft.Toolkit.Forms.UI.Controls.WebView, available from https://www.nuget.org/packages/Microsoft.Toolkit.Forms.UI.Controls.WebView

I have added the WebView into my WinForms application - Designer code:

```<code>namespace Testing
{
    partial class TestForm
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.pnlWebPage = new System.Windows.Forms.Panel();
            this.webView = new Microsoft.Toolkit.Forms.UI.Controls.WebView();
            this.pnlWebPage.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.webView)).BeginInit();
            this.SuspendLayout();
            //
            // pnlWebPage
            //
            this.pnlWebPage.Controls.Add(this.webView);
            this.pnlWebPage.Dock = System.Windows.Forms.DockStyle.Fill;
            this.pnlWebPage.Location = new System.Drawing.Point(0, 101);
            this.pnlWebPage.Margin = new System.Windows.Forms.Padding(4);
            this.pnlWebPage.Name = "pnlWebPage";
            this.pnlWebPage.Size = new System.Drawing.Size(1205, 624);
            this.pnlWebPage.TabIndex = 3;
            //
            // webView
            //
            this.webView.Dock = System.Windows.Forms.DockStyle.Fill;
            this.webView.Location = new System.Drawing.Point(0, 0);
            this.webView.Margin = new System.Windows.Forms.Padding(4);
            this.webView.MinimumSize = new System.Drawing.Size(27, 25);
            this.webView.Name = "webView";
            this.webView.Size = new System.Drawing.Size(1205, 624);
            this.webView.Source = new System.Uri("https://www.bbc.com", System.UriKind.Absolute);
            this.webView.TabIndex = 0;
            this.webView.NavigationCompleted += new System.EventHandler<Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT.WebViewControlNavigationCompletedEventArgs>(this.webView_NavigationCompleted);
            //
            // TestForm
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(1505, 725);
            this.Controls.Add(this.pnlWebPage);
            this.Margin = new System.Windows.Forms.Padding(4);
            this.Name = "TestForm";
            this.Text = "TestForm";
            this.pnlWebPage.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.webView)).EndInit();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Panel pnlWebPage;
        private Microsoft.Toolkit.Forms.UI.Controls.WebView webView;
    }
}
</code>```

Once a website has loaded into the WebView, I want to be able to extract the page's HTML and store it as a string or similar.

I've added the following method, which is called when the WebView's NavigationCompleted event happens.

```<code>private async void wvLI_NavigationCompleted(object sender, Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT.WebViewControlNavigationCompletedEventArgs e)
        {
           \\ HTML extraction to go here
}
</code>```

I can't see a way to access the HTML however - there doesn't seem to be a property or similar for it.  When researching how to do this I can only find questions and answers relating to Android or Xamarin - and none of the solutions for those work for the Microsoft Toolkit WebView.  Does anyone know how I can achieve this?

答:
You can invoke the JavaScript eval() function by calling InvokeScriptAsync (or InvokeScript) to get the outerHTML (or innerHTML or whatever you need) as follows:

```<code>private async void wvLI_NavigationCompleted(object sender, Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT.WebViewControlNavigationCompletedEventArgs e)
{
     string html = await webView.InvokeScriptAsync("eval", new string[] { "document.documentElement.outerHTML;" });
}
</code>```

It is important that this goes in the NavigationCompleted event, rather than, say, DOMContentLoaded, as the page is only fully loaded at the point of NavigationCompleted firing

Body:
I am using Microsoft.Toolkit.Forms.UI.Controls.WebView, available from https://www.nuget.org/packages/Microsoft.Toolkit.Forms.UI.Controls.WebView

I have added the WebView into my WinForms application - Designer code:

namespace Testing
{
    partial class TestForm
    {
        ///
        /// Required designer variable.
        ///
        private System.ComponentModel.IContainer components = null;

        ///
        /// Clean up any resources being used.
        ///
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        ///
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        ///
        private void InitializeComponent()
        {
            this.pnlWebPage = new System.Windows.Forms.Panel();
            this.webView = new Microsoft.Toolkit.Forms.UI.Controls.WebView();
            this.pnlWebPage.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.webView)).BeginInit();
            this.SuspendLayout();
            //
            // pnlWebPage
            //
            this.pnlWebPage.Controls.Add(this.webView);
            this.pnlWebPage.Dock = System.Windows.Forms.DockStyle.Fill;
            this.pnlWebPage.Location = new System.Drawing.Point(0, 101);
            this.pnlWebPage.Margin = new System.Windows.Forms.Padding(4);
            this.pnlWebPage.Name = "pnlWebPage";
            this.pnlWebPage.Size = new System.Drawing.Size(1205, 624);
            this.pnlWebPage.TabIndex = 3;
            //
            // webView
            //
            this.webView.Dock = System.Windows.Forms.DockStyle.Fill;
            this.webView.Location = new System.Drawing.Point(0, 0);
            this.webView.Margin = new System.Windows.Forms.Padding(4);
            this.webView.MinimumSize = new System.Drawing.Size(27, 25);
            this.webView.Name = "webView";
            this.webView.Size = new System.Drawing.Size(1205, 624);
            this.webView.Source = new System.Uri("https://www.bbc.com", System.UriKind.Absolute);
            this.webView.TabIndex = 0;
            this.webView.NavigationCompleted += new System.EventHandler<Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT.WebViewControlNavigationCompletedEventArgs>(this.webView_NavigationCompleted);
            //
            // TestForm
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(1505, 725);
            this.Controls.Add(this.pnlWebPage);
            this.Margin = new System.Windows.Forms.Padding(4);
            this.Name = "TestForm";
            this.Text = "TestForm";
            this.pnlWebPage.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.webView)).EndInit();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Panel pnlWebPage;
        private Microsoft.Toolkit.Forms.UI.Controls.WebView webView;
    }
}

Once a website has loaded into the WebView, I want to be able to extract the page's HTML and store it as a string or similar.

I've added the following method, which is called when the WebView's NavigationCompleted event happens.

private async void wvLI_NavigationCompleted(object sender, Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT.WebViewControlNavigationCompletedEventArgs e)
        {
           \\ HTML extraction to go here
}

I can't see a way to access the HTML however - there doesn't seem to be a property or similar for it.  When researching how to do this I can only find questions and answers relating to Android or Xamarin - and none of the solutions for those work for the Microsoft Toolkit WebView.  Does anyone know how I can achieve this?

Body:
You can invoke the JavaScript eval() function by calling InvokeScriptAsync (or InvokeScript) to get the outerHTML (or innerHTML or whatever you need) as follows:

private async void wvLI_NavigationCompleted(object sender, Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT.WebViewControlNavigationCompletedEventArgs e)
{
     string html = await webView.InvokeScriptAsync("eval", new string[] { "document.documentElement.outerHTML;" });
}

It is important that this goes in the NavigationCompleted event, rather than, say, DOMContentLoaded, as the page is only fully loaded at the point of NavigationCompleted firing