I have searched ALL the web for an answer and gave up. So my last hope is to find an answer here!!!
I have started to make a Family Tree project using JAVAFX (NOT FXML) and I am stocked in the middle!!!
I have the functionality written in JAVA and can not implement it on JAVAFX. For example the "ADD BUTTON" or "EDIT BUTTON" or ....
Here is the link to all the project: The Codes
Basically this is the part that i get confused, To use the java method in javafx:
Button AddButton = new Button("Add");
Button DeleteButton = new Button("Delete");
Button EditButton = new Button("Edit");
/**
* Adding a person to the family tree
*/
public void addPerson(Person aPerson) {
boolean found = false;
for (Person p : family) {
if (p.compareTo(aPerson) == 1) {
found = true;
}
}
if (!found) {
family.add(aPerson);
System.out.println(aPerson.getName() + " has been added!");
} else {
System.out.println("Error 301 - Person already in the family tree.");
}
}
Any help will be truly appreciated !!!!!
Cheers
Just register a handler with the button:
addButton.setOnAction(e -> {
Person personToAdd = ... ;
addPerson(personToAdd);
});
See the tutorial.
Related
i am using kotlin to create some small application with it, and tornadofx, however i am unfamiliar with how some of the javafx things translate to kotlin.
I am trying to itterate through a list of buttons, and add button to page, but i managed only to add one button per page, and i want to have X items per page, and i want page count to be dynamic
override val root = tabpane{
setPrefSize(800.0,600.0)
tabs.removeAll()
tabClosingPolicy = TabPane.TabClosingPolicy.ALL_TABS
val buttonList = arrayOf(
Button("Btn1"),
Button("Btn2"),
Button("Btn3"),
Button("Btn4")
)
tab("My Tab 1") {
hbox {
button("Click Me!") {
setOnAction {
replaceWith<TestView>()
}
}
button("Add Tab 2") {
setOnAction {
tab("tab2 ")
{
select()
button("Close") { setOnAction { close() } }
pagination(buttonList.size) { setPageFactory { pageIndex -> (buttonList[pageIndex]) } }
style {
arrowsVisible = false
pageInformationVisible = false
}
}
}
}
}
}
}
i tryed to implement a for loop that would add certain amount of items per page (lets say 2 buttons per page) and then proceed to create page. but i had no luck.
If anyone could help me find a proper solution for kotlin based pagination i would be thankful
pagination(buttonList.size)
with this line i can controll amount of pages, so that is at least something, but i dont see how to control amount items per page.
pageIndex -> (buttonList[pageIndex])
i realize issue is here, but i had no luck implementing proper logic.
lets say i want 4 items per page, i could get amount of pages required by dividing my list with number 4 (items per page). but not sure how to add more then 1 item per page.
class SomeView : View() {
private val buttonList = arrayOf(
Button("Btn1"),
Button("Btn2"),
Button("Btn3"),
Button("Btn4"),
Button("Btn5")
)
private var pageSize = 3 //Decide this however you want
override val root = tabpane {
setPrefSize(800.0, 600.0)
tabs.removeAll()
tabClosingPolicy = TabPane.TabClosingPolicy.ALL_TABS
tab("My Tab 1") {
hbox {
button("Click Me!") {
setOnAction {
replaceWith<TestView>()
}
}
button("Add Tab 2") {
setOnAction {
tab("tab2 ")
{
select()
button("Close") { setOnAction { close() } }
//The ceiling calc is for rounding up for the size
pagination(ceil(buttonList.size.toDouble() / pageSize).toInt())
{ setPageFactory { pageIndex -> createPage(pageIndex * pageSize, pageSize) } }
style {
arrowsVisible = false
pageInformationVisible = false
}
}
}
}
}
}
}
private fun createPage(startingIndex: Int, pageSize: Int = 1) : Pane {
val pagePane = VBox() //Create and design whatever pane you want
val endingIndex = minOf(startingIndex + pageSize, buttonList.size) //Don't go out of bounds
for(i in startingIndex until endingIndex) { //Assuming starting index is in bounds
pagePane.add(buttonList[i])
}
return pagePane
}
}
Here is a solution for dynamic pages for pagination. Your main problem was that tab panes only hold one child pane/component. The answer is to nest your buttons in a pane. I haven't tested this hard for edge cases or anything, so this is more proof-of-concept. You'll have to account for those if they come up.
Side Notes: As explained above, this is also why your "Close" button isn't appearing. Also, when I was testing your code I noticed the style wasn't implemented unless I clicked a button in the pane. Maybe it would work if you used a stylesheet, created a cssclass, and added that class to your tabpane (Don't forget to import your stylesheet if you choose to do this).
I have a TableView with a ComboBoxTableCell, when using the default implementation the user have to click three times to select a value from of the ComboBox's list.
I want when the user clicks on the cell to show the combo box list. I based my solution on this one:
JavaFX editable ComboBox in a table view
The cell does get into edit mode (startEdit() is called) but it takes another click to show the list of values, what am I missing?
table.addEventHandler(MouseEvent.MOUSE_CLICKED, (e) ->
{
if (table.getEditingCell() == null)
{
TablePosition focusedCellPos = table.getFocusModel().getFocusedCell();
table.edit(focusedCellPos.getRow(), focusedCellPos.getTableColumn());
}
});
Thanks.
Interesting problem - bubbling up again after quite a while :)
Looks like the approach of the OP is indeed working (as of fx11, some bugs around its editing seem to be fixed) - with a little help from the combo cell:
start editing in a single click handler on the tableView (from OP)
extend ComboBoxTableCell and override its startEdit to open the dropDown
Code snippet:
// set editable to see the combo
table.setEditable(true);
// keep approach by OP
table.addEventHandler(MouseEvent.MOUSE_CLICKED, (e) -> {
TablePosition<Person, ?> focusedCellPos = table.getFocusModel()
.getFocusedCell();
if (table.getEditingCell() == null) {
table.edit(focusedCellPos.getRow(),
focusedCellPos.getTableColumn());
}
});
// use modified standard combo cell shows its popup on startEdit
firstName.setCellFactory(cb -> new ComboBoxTableCell<>(firstNames) {
#Override
public void startEdit() {
super.startEdit();
if (isEditing() && getGraphic() instanceof ComboBox) {
// needs focus for proper working of esc/enter
getGraphic().requestFocus();
((ComboBox<?>) getGraphic()).show();
}
}
});
Maybe not the cleanest solution to this problem, but I found a workaround to make the ComboBoxTableCells drop down its menu in just 1 click:
column.setCellFactory(new Callback<TableColumn<Person, String>, TableCell<Person, String>>() {
#Override
public TableCell<Person, String> call(TableColumn<Person, String> column) {
ComboBoxTableCell cbtCell = new ComboBoxTableCell<>(cbValues);
cbtCell.setOnMouseEntered(new EventHandler<Event>() {
#Override
public void handle(Event event) {
// Without a Person object, a combobox shouldn't open in that row
if (((Person)((TableRow)cbtCell.getParent()).getItem()) != null) {
Robot r = new Robot();
r.mouseClick(MouseButton.PRIMARY);
r.mouseClick(MouseButton.PRIMARY);
}
}
});
return cbtCell;
}
});
PS: I know that this topic is a bit old, but I also stumbled upon this problem recently and could not find any working solution to it online. As I sad, it's not the cleanest workaround, but at least it does its job. ;)
I have partially solved the following problem: JavaFX WebView / WebEngine show on-screen-keyboard automatically for each text input
I stucked at the 6th point because I would like to use the built in JavaFX virtual keyboard but I can not find any reference how can trigger the displaying of it.
Do you know any solution for this? If it is possible I do not want to use 3rd party library.
I am going to answer my question because I found a solution.
First of all I added an event listener for all input tags on webpage, after page loaded:
private void addEventListenersToDOM() {
webview.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
#Override
public void changed(ObservableValue<? extends State> ov, State oldState, State newState) {
if (newState == State.SUCCEEDED) {
JSObject win = (JSObject) webview.getEngine().executeScript("window");
win.setMember("javaFXVirtualKeyboard", new JavaFXVirtualKeyboard());
String script =
"var inputsList = document.getElementsByTagName('input');"
+ "for (var index = 0; index < inputsList.length; ++index) { "
+ "inputsList[index].addEventListener('focus', function() { javaFXVirtualKeyboard.show() }, false); "
+ "inputsList[index].addEventListener('focusout', function() { javaFXVirtualKeyboard.hide() }, false); "
+ "}";
webview.getEngine().executeScript(script);
}
}
});
}
And the key point, how I triggering the keyboard displaying and hiding:
public class JavaFXVirtualKeyboard {
public void show() {
FXVK.init(webview);
FXVK.attach(webview);
}
public void hide() {
FXVK.detach();
}
}
One note: FXVK class is not an API so we get a warning message in all cases but it works without any bug.
Discouraged access: The type 'FXVK' is not API (restriction on required library 'C:\Program Files\Java\jre1.8.0_91\lib\ext\jfxrt.jar')
Good evening,
I ask myself the following head breaks:
I would like to create a Favorites button that has the two following states:
1st state: "Add to Favorites"
2nd state (on OnClick event): "Remove from favorites"
But I'd also be able to return to the 2nd state: "Add to Favorites" by a 2nd OnClick event ect..
Does anyone have a solution for it with a simple OnClickListener it seems impossible.
I finally solved my problem using a custom checkbox !!Is the best way to use favorite things because you can get the state of your drawable !!
like that :
favoris_button = (CheckBox) findViewById(R.id.star);
favoris_button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (((CheckBox) v).isChecked()) {
favoris_button.setText("Supprimer des categories");
}
else
favoris_button.setText("Ajouter aux favoris");
}
});
Run this code inside your listener or wrap a function around it and pass it the boolean and call it when you need to. Startup, reset or whenever you want to change the state. If the button is clicked you need to flip the state.
private Boolean check;
favoris_button = (Button) findViewById(R.id.promotion_favoris);
favoris_button.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
if (check == true)
{
favoris_button.setBackgroundColor(R.drawable.btn_orange9);
favoris_button.setText("Supprimer des favoris");
}
else
{
favoris_button.setBackgroundColor(R.drawable.btn_red9);
favoris_button.setText("Ajouter aux favoris");
}
check ^= true;
}
});
From the examples at Xamarin.com you can build basic M.T. Dialog apps, but how do you build a real life application?
Do you:
1) Create a single DialogViewController and tree every view/RootElement from there or,
2) Create a DialogViewController for every view and use the UINavigationController and push it on as needed?
Depending on your answer, the better response is how? I've built the example task app, so I understand adding elements to a table, click it to go to the 'next' view for editing, but how to click for non-editing? How to click a button, go next view if answer is number 1?
Revised:
There is probably no one right answer, but what I've come up with seems to work for us. Number 2 from above is what was chosen, below is an example of the code as it currently exists. What we did was create a navigation controller in AppDelegate and give access to it throughout the whole application like this:
public partial class AppDelegate : UIApplicationDelegate
{
public UIWindow window { get; private set; }
//< There's a Window property/field which we chose not to bother with
public static AppDelegate Current { get; private set; }
public UINavigationController NavController { get; private set; }
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
Current = this;
window = new UIWindow (UIScreen.MainScreen.Bounds);
NavController = new UINavigationController();
// See About Controller below
DialogViewController about = new AboutController();
NavController.PushViewController(about, true);
window.RootViewController = NavController;
window.MakeKeyAndVisible ();
return true;
}
}
Then every Dialog has a structure like this:
public class AboutController : DialogViewController
{
public delegate void D(AboutController dvc);
public event D ViewLoaded = delegate { };
static About about;
public AboutController()
: base(about = new About())
{
Autorotate = true;
about.SetDialogViewController(this);
}
public override void LoadView()
{
base.LoadView();
ViewLoaded(this);
}
}
public class About : RootElement
{
static AboutModel about = AboutVM.About;
public About()
: base(about.Title)
{
string[] message = about.Text.Split(...);
Add(new Section(){
new AboutMessage(message[0]),
new About_Image(about),
new AboutMessage(message[1]),
});
}
internal void SetDialogViewController(AboutController dvc)
{
var next = new UIBarButtonItem(UIBarButtonSystemItem.Play);
dvc.NavigationItem.RightBarButtonItem = next;
dvc.ViewLoaded += new AboutController.D(dvc_ViewLoaded);
next.Clicked += new System.EventHandler(next_Clicked);
}
void next_Clicked(object sender, System.EventArgs e)
{
// Load next controller
AppDelegate.Current.NavController.PushViewController(new IssuesController(), true);
}
void dvc_ViewLoaded(AboutController dvc)
{
// Swipe location: https://gist.github.com/2884348
dvc.View.Swipe(UISwipeGestureRecognizerDirection.Left).Event +=
delegate { next_Clicked(null, null); };
}
}
Create a sub-class of elements as needed:
public class About_Image : Element, IElementSizing
{
static NSString skey = new NSString("About_Image");
AboutModel about;
UIImage image;
public About_Image(AboutModel about)
: base(string.Empty)
{
this.about = about;
FileInfo imageFile = App.LibraryFile(about.Image ?? "filler.png");
if (imageFile.Exists)
{
float size = 240;
image = UIImage.FromFile(imageFile.FullName);
var resizer = new ImageResizer(image);
resizer.Resize(size, size);
image = resizer.ModifiedImage;
}
}
public override UITableViewCell GetCell(UITableView tv)
{
var cell = tv.DequeueReusableCell(skey);
if (cell == null)
{
cell = new UITableViewCell(UITableViewCellStyle.Default, skey)
{
SelectionStyle = UITableViewCellSelectionStyle.None,
Accessory = UITableViewCellAccessory.None,
};
}
if (null != image)
{
cell.ImageView.ContentMode = UIViewContentMode.Center;
cell.ImageView.Image = image;
}
return cell;
}
public float GetHeight(UITableView tableView, NSIndexPath indexPath)
{
float height = 100;
if (null != image)
height = image.Size.Height;
return height;
}
public override void Selected(DialogViewController dvc, UITableView tableView, NSIndexPath indexPath)
{
//base.Selected(dvc, tableView, path);
tableView.DeselectRow(indexPath, true);
}
}
#miquel
The current idea of a workflow is an app that starts with a jpg of the Default.png that fades into the first view, with a flow control button(s) that would move to the main app. This view, which I had working previous to M.T.D. (MonoTouch.Dialog), which is a table of text rows with an image. When each row is clicked, it moves to another view that has the row/text in more detail.
The app also supports in-app-purchasing, so if the client wishes to purchase more of the product, then switch to another view to transact the purchase(s). This part was the main reason for switching to M.T.D., as I thought M.T.D. would be perfect for it.
Lastly there would be a settings view to re-enable purchases, etc.
PS How does one know when the app is un-minimized? We would like to show the fade in image again.
I have been asking myself the same questions. I've used the Funq Dependency Injection framework and I create a new DialogViewController for each view. It's effectively the same approach I've used previously developing ASP.NET MVC applications and means I can keep the controller logic nicely separated. I subclass DialogViewController for each view which allows me to pass in to the controller any application data required for that particular controller. I'm not sure if this is the recommended approach but so far it's working for me.
I too have looked at the TweetStation application and I find it a useful reference but the associated documentation specifically says that it isn't trying to be an example of how to structure a MonoTouch application.
I use option 2 that you stated as well, it works pretty nicely as you're able to edit the toolbar options on a per-root-view basis and such.
Option 2 is more feasible, as it also gives you more control on each DialogViewController. It can also helps if you want to conditionally load the view.