File browser in JavaFX - javafx

I am starting to learn JavaFX (2 days in) and I am making an implementation of a file browser. So to give you an example I am looking for something like this
What element should I use for the representation of the right panel (the one with the icon view of the files)?
I need it to point at a specific directory in my system, lets say 'music', and display all folders stored in it.
I looked for tutorials online and other examples but I couldn't find anything similar.
My only requirement is to look this way and also to support drag and drop.
Thanks
EDIT: I am using Scene builder btw

Use a ControlsFX GridView for the right pane of file icons.
GridView is a fast, virtualised grid container similar to ListView, except that there can be multiple cells on each row. Great for showing images!
GridView probably doesn't natively support drag and drop, so you will need to code that up yourself.
Here is a sample of some drag and drop functionality in a virtualized control (in this case a ListView), which you might be able to adapt: How to create a reorder-able TableView in JavaFx.

Related

JavaFX Make WebView behave like Label in VBox

I have a program that allows users to take notes. When they take notes, I use a JavaFX HTMLEditor, which allows for tables, lists, etc. I then need to display these notes to the user, and only way I can find to display HTML in JavaFX is WebEngine (unfortunately).
The problem is WebEngine has different behaviours inside containers than labels, and I need the WebView to behave as a label would.
I have simplified my problem with this example. Here is a VBox with 1 component inside it, a Label:
As you can see, the label (red) takes up no more vertical space than necessary inside the VBox container, and wraps text which is exactly the behaviour I want.
If I now add a WebView and then a second label, the result changes to this:
The webview in the middle (white) is now expanding vertically as much as possible, and the labels are no longer wrapping. So if in my actual program I had two WebViews stacked on top of each other, they would both fight for 50% of the available vertical space, instead of only taking up as much space as necessary, which is what I need.
Furthermore, with Label/WebView/Label like in last image, If I shrink the width of the window like so:
There is another problem where the WebView starts to scroll vertically. This is not what I want, as I want it to be just like a label (expand to take up as much space as necessary and no more at all times).
I have tried setting the vgrow property of the webview to both null and Priority.NEVER, but it seems to have no effect.
Here is the complete code. Thanks for your help.
Main.java
package main;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebView;
public class Main extends Application {
#Override
public void start(Stage _primaryStage) {
// create the view
VBox vBox = new VBox();
vBox.setPrefHeight(600);
vBox.setPrefWidth(600);
String textString = "";
textString += "It's the end of the world as we know it and I feel fine. ";
textString += textString;
textString += textString;
textString += textString;
textString += textString;
Label testLabel = new Label(textString);
testLabel.getStyleClass().add("label");
testLabel.setWrapText(true);
vBox.getChildren().add(testLabel);
WebView testWebView = new WebView();
testWebView.getStyleClass().add("webview");
testWebView.getEngine().loadContent(textString);
vBox.getChildren().add(testWebView);
VBox.setVgrow(testWebView, Priority.NEVER);
Label testLabel2 = new Label(textString);
testLabel2.getStyleClass().add("label");
testLabel2.setWrapText(true);
vBox.getChildren().add(testLabel2);
Scene scene = new Scene(vBox);
scene.getStylesheets().add("/main/styles.css");
_primaryStage.setTitle("Notes Program");
_primaryStage.setScene(scene);
_primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
styles.css
.label {
-fx-background-color: 'red';
}
.webview {
}
Currently (at the time this answer was written), no out of the box, easily implemented or adaptable solution to your problem exists in either JavaFX or available 3rd party libraries.
This is not a concrete answer to the question, but a suggestion of approaches which may be tried to solve problems such as this one.
Fitting a WebView to its content
Your current approach to solving the problem could be summarized as: render HTML content in a resizable JavaFX node the behaves similarly to a Label.
For the most direct assistance in trying to achieve that, review the information in answers to the linked question below, it is not re-iterated in detail here.
This question is related to a similar one which provides some information on ways to address sizing WebView to the displayed content of its HTML page, though the information there is currently not definitive and compete for all cases, so it won't immediately solve your problem:
Correct sizing of Webview embedded in Tabelcell
The suggestion there is to use some JavaScript scripting to determine the size of the document, then set re-size constraints on the WebView node to fit the node to the content, dynamically updating the sizing link when the content changes or is re-rendered or the available space for the WebView changes.
FAQ
Answers to additional and clarifying questions which were included in comments.
I was hoping I could accomplish this with JavaFX layouts or stylesheets to avoid scripts.
I think to accomplish your original solution idea of treating a WebView like a label, it will not be possible to avoiding writing some code in both JavaScript and JavaFX.
The in-built JavaFX layout panes and CSS style sheets will not be
sufficient.
The current WebView doesn’t provide the appropriate
support to work as nicely as desired with JavaFX layout systems.
If somebody has already wrotethe code and scripting to create the behavior and skin for a WebViewLabel control, then you could just use that and customize it with just JavaFX APIs similar to other controls, however that doesn’t exist as far as I know.
Is there another solution that could support lists and tables
I don't think RichTextFX has this support (I haven't looked at it in detail, so I don't know for sure).
Markdown will support lists well. It will also support tables, likely mapped to a GridView in a JavaFX node, not a TableView. But, the syntax for creating tables may be hard on users if the Markdown is just edited with a plain text editor without icon widget support. I suggest you search the web for JavaFX based Markdown viewers and see if they support your required functionality adequately.
My concern though is if i have a page with 100 webviews on it, do you see performance issues? User could only intereact with 1 at a time ofcourse, but there would still be 100 of them loaded into memory potentially. If it was Java Swing i could simply load content into labels but I didn't realise JavaFX doesnt have that
There might be performance issue with such a setup or it might perform OK.
You should create a minimal app to study and benchmark the performance of many WebView nodes.
A single WebView is slow to initialize with detectable lag when it is the first one shown in the app, but that might just because to display the first WebView the first time the JavaFX system may need to run a lot of runtime setup and initialization.
I never tried with many WebView nodes simultaneously displayed in a scene. Perhaps the internal implementation will allow good performance for that, but you have to test it to make sure or you might expend a lot of effort and be disappointed in the result.
I would guess maybe 100 WebViews would be an upper limit and would be surprised if performance didn't tend to drop either a lot earlier with less of them or soon thereafter with a few more of them.
JavaFX isn't really setup to simultaneously display 1000's of nodes, and, usually that isn't required anyway, you only need to display the stuff which is currently visible to the user. No user could immediately take in all of the data if there is too much of it and no output device could render it.
This is why there exist virtualized controls like TableView and ListView, which feature reusable cells created in factories to display interactive views into the underlying data rather then rendering display notes for the complete (perhaps 1000s or millions of lines) of underlying data.
If you find yourself in a situation where you want to create 1000s of nodes, usually that can be better solved by using cell factories and virtualization like ListView.
Creating a new control with these facilities is an advanced topic and difficult to implement well.
What follows is a list of alternate approaches to the problem from what you outlined in your question. These approaches may not be directly applicable to your application but may be applicable to somebody with a different application who has a similar problem to solve.
Alternate Approach: Do more in HTML and less in JavaFX
Where your multiple WebViews are clustered for rendering output, instead just use a single WebView instance and manage more of the layout via HTML and JavaScript.
There are certain layout tasks (like laying out html) that a web engine is better at than JavaFX. Use the best tool for the job. JavaFX includes both tools (an internal JavaFX rendering engine for rendering the scene graph and an internal Web Engine for rendering html). So you can choose one rendering implementation or the other (or a mixture of the two), whichever best suits the current task you are implementing.
Alternate Approach: Use RichTextFX
For some similar applications RichTextFX may be a preferred solution.
RichTextFX provides a memory-efficient text area for JavaFX that allows the developer to style ranges of text, display custom objects in-line (no more HTMLEditor), and override the default behavior only where necessary without overriding any other part of the behavior.
RichTextFX may not have full support for all of the required features, but can still accomplish many tasks, so investigate its functionality to see if it is a good fit before implementing your own solution.
Alternate Approach: Use Markdown
Under this approach:
Use an editor to edit the Markdown.
Use a viewer to view the rendered Markdown.
It is not necessary to provide full Markdown support, only as much as might be very useful for your application users.
There are various JavaFX Markdown editors and viewers available in third party implementations that you can find if you search the web. There are also many HTML based Markdown editors and viewers which you can use from a WebView. So you could choose to integrate or modify one of those, rather than implementing this from scratch.
For a general purpose library or utility it would be best to make these two things custom controls (e.g MarkDownEditor and MarkDownView) which hide their implementation in a JavaFX control skin and expose their public API in a JavaFX control subclass.
Markdown editor
For the editor which creates (not renders) the Markdown, that can be different from the viewer.
The editor implementation, instead of using the built-in JavaFX HTMLEditor, which is a what-you-see-is-what-you-get (wysiwyg) editor the generates HTML output, you would provide either:
A plain text editor to create the markdown OR
A wysiwyg editor that generates Markdown output.
For the implementation you could use either:
100 percent JavaFX solutions OR
HTML embedded in WebView Markdown editor solutions (e.g. similar to the editor used in StackOverflow for editing questions and answers).
A JavaFX based editor could be as simple as a TextArea, or more complex with additional formatting support widgets implemented in JavaFX (again similar to the editing toolbar provided in the StackOverflow Markdown editor JavaScript implementation, just implemented in JavaFX rather than HTML).
Markdown viewer
Again for the viewer you could choose either:
100 percent JavaFX solutions OR
HTML embedded in WebView Markdown editor solutions (e.g. similar to the editor used in StackOverflow for editing questions and answers).
Whereas, for the editor, using a HTML markdown editor embedded in a WebView would likely be fine, for the viewer, you would likely be better off with a 100 percent JavaFX solution if you wanted to view many snippets of documents and display and size them like Label controls.
Essentially the JavaFX solution would be similar to the implementation of a new control called say, MarkDownLabel, which would render a formatted label like thing based on MarkDown text input.
If the view needs to render a large document, it could be equipped with scrolling, scaling and panning functionality, but a simple view for small documents would not need this. Also a cell style factory style implementation (similar to ListView) could allow the nodes used to render the view to be updated and repurposed for different content rather than recreated (for efficiency), but that is just a performance optimization (and quite tricky) so may not be necessary.

Complex UI with MVC

I'm trying to recreate a text editor I've made but using the MVC design pattern; I'm not totally sure about certain parts of it.
For example, I have a tree view displaying my project directory, and a text editor showing the contents of a file, along with this i have output from compilation of files being displayed as well as a tabbed interface.
Would this be split into a few different models or under one big model? If it's under 1 big model how would I go about using the Qt model classes for such a thing?
Open up Qt Designer and drag and drop all the stuff you need. It should get you pretty far.
I think the only model/view you should worry about is the QFileSystemModel and pairing it up with a QTreeView. Everything else Qt has some nice examples showing how to do it.
If you are showing multiple files at once in separate tabs, then you might want to look into the Tabbed Browser Example to see how its done.
http://doc.qt.io/qt-5/examples-mainwindow.html
http://doc.qt.io/qt-5/qtwidgets-richtext-syntaxhighlighter-example.html
http://doc.qt.io/qt-5/qtwidgets-widgets-codeeditor-example.html
http://doc.qt.io/qt-5/qtwebkitexamples-webkitwidgets-browser-example.html
I like QDockWidgets and using QActions and putting them on the QToolbar in a QMainWindow.
http://doc.qt.io/qt-5/model-view-programming.html
http://doc.qt.io/qt-5/qfilesystemmodel.html#details
http://doc.qt.io/qt-5/qmdiarea.html#details
http://doc.qt.io/qt-5/qtextedit.html
For the compilation part you will just need to create a QProcess and connect its output to a QTextEdit.
Hope that helps.

Adding horizontal separator and Auto-Complete feature in Flex Combo-box

I am developing a Panel in Flex. The Panel has a combo-box which displays the system fonts. I have created an array collection and filled it with available system fonts and set this array collection as data provider of the combobox. I want to do the following but is not able to do so:
Adding non-clickable horizontal seperator in the combo-box-
I wanted to display a horizontal separator in the dropdown list of the combo-box at some particular locations. But I found examples to add horizontal separator in popup button control.
Auto complete feature in the combo-box-
I want to implement the auto-complete feature of the combo-box as done in "font-family" combo-box of Character Panel in Photoshop.
Can someone please provide me some sample code or guidance to achieve the above.
I want to implement the auto-complete feature of the combo-box
Well, I'm biased, but I strongly recommend you check out our AutoComplete component. We have an MX Version, a Spark version, and a mobile version. It is also available for free for development / production use.
Aside from that; Hillel Coren's AutoComplete is held in high regards by many developers.
[Every other Flex AutoComplete component I've come across appears to be half baked]

Create drag-able panels in Flex like its in netvibes.com

I want to create a news application for my website.
My question is how should i create drag-able panels/canvas inside another panel/canvas.
What i exactly intend to do can be seen on netvibes.com . The website has different panels of every news group, and this panel could be moved from one place to other, but in a well defined manner. And the other panel take over the place of dragged panel.
Is there any component in flex, which can help me make something like that.
If i was unable to make my question clear, plz let me know, i will try to make it more clear.
Regards
Zeeshan
A TileList with drag and drop enabled should be able to accomplish something like that. Or, use a Spark List with a custom layout that you create.
It might be a bit tricky getting the list elements to drag and drop based on clicking the title, but it should be doable.
I think you should consider a more advanced solution with drap-n-drop with a custom panel based component. The places the panels can move can be implemented with a different custom canvas based component. The advantage would be to move the components into different custom positions and panels can be resized independent of each other.
Adobe has some good tutorials for drag-drop operations.

Flex workflow and best practice

While reviewing the tutorials and example Flex projects, they seem to focus mainly on form elements and data grids, rather than delivering content in a more visual way. Which is what I will need for this upcoming project. As a result, I have a gap in my comfort level that I'm hoping that a seasoned Flex developer can help me hurtle.
The project that I have is a collaboration index tool to display customers products and services using an user interface with four separate panels.
the top-left panel will contain a list of categories in a vertical scroll.
The bottom left panel will contain a wheel effect of sub-categories, based on the category chosen.
The top right panel will contain the detail information - The selected Category Title and Description. And below that, the selected sub-category title and description.
The bottom right panel will contain a list of the service and product items that belong to the sub-category. Below each item in the list will be a link-group accordion with url links for more information in each.
There will be an XML file containing the complete data tree driving this collaboration index.
Additionally, depending on the category chosen, color variances will occur in the background of the some of layout sections.
So, It appears that I will need to create a few custom components, maybe adopt a few existing components, and re-skin everything so that it carries a synonymous look and feel to the client's branding.
Although I have a bunch of questions, tackling the first section seems logical, and the first question that comes to mind in this section is: in the top left panel, should the list of categories be standard Flex buttons that are re-skinned? or should they be object instances somehow brought in to Flex.
Then in the second section, I was had seen a component that displayed images in a way that was perfect for this section. But, the items show here would be just visual, rounded corner blocks with subcategory names in them. So, I'm not sure if that component will work or not.
AS3 is very different from AS2. I'm sure you've noticed by now, but it's worth mentioning in case you hadn't.
Flex Components are basically just a package of Flash objects. So you can, sort of, write every Flex component on your own using just Sprites and/or TextFields. This includes skins. A skin is pretty much just a Shape attached to an object with custom drawing.
A button is just a combination of image+textField+skin, with all the events and skin transitions managed for you.
The reason I mention this is that there is no right way to do what you want. If you're using the List control, you should probably write a component that implements IListItemRenderer. Button does, so you can simply override the Button, no problems. You can have buttons with a label + icon. Or just icon. Or just a label. You can also define where the label is positioned relative to the icon (labelPosition="above|below|left|right"). There is a lot of built-in flexibility.
Thanks for the mention of FlexSpaces. Note that it was finally ported to Flex 4 including a first pass conversion to spark controls earlier this year. Still to do: add dependency injection with Spring ActionScript, remove use of Cairngorm 2.x.
I have been developing Flex 4 quite heavily the past 6 months and must say it would make your job very easy.
Here's what I would do:
1) Check out FlexSpaces for the best Flex 3 project architecture. It's a fully featured CMS in Flex with categories, tags, searching, filesystem, collaboration, etc.
2) Download the Flex 4 SDK and install that. There's no need to use Flex 3 anymore, if you're just getting started, DEFINITELY go with Flex 4. If you need custom components, Spark (the new component architecture) has a very simple way of doing them (here's a cool blog post building a Rating Component in Spark that shows you how do it). Flex 4 is backward compatible with Flex 3 components, so you can use projects/components you find on the internet if you want to, no problem.
3) For the top-left category list, if the categories aren't nested, I would use the spark.components.List, (here's one using more complex item renderers). Then just extend the spark.components.supportClasses.ItemRenderer, which acts just like a Skin. If categories are nested, just use the mx.controls.Tree. Check out that FlexSpaces project for that (they show how to use XML/ArrayCollections in the tree, your "object instances brought into flex somehow" question).
4) For the wheel effect, the only thing I don't like about Spark so far is that it's difficult to animate layouts. But people are starting to make 3D layouts, check out Here's 5 3D Layouts for Flex 4 by Ryan Campbell. There's also OpenFlux if you want very easily animated layouts. Flex effects in general are quite clunky, so I end up just using Tweener or TweenMax for animations.
5) As for reskinning, trying to reskin using the Flex 3 architecture would be a monumental task, if you wanted to make it look clean and nice, and it would be insane trying to reuse that code in the next project. For Spark, it's a snap, and it's 100% mxml. Just copy the whole sparkSkins folder from the SDK and start changing things, and you're good to go.
But yeah, that FlexSpaces project is a very solid example for what you're talking about. Totally open source.
Cheers

Resources