How can I modify data from another controller class? - javafx-8

I have a main class (Main.java), two FXML files (FXML1.fxml, FXML2.fxml) and the corresponding controller (FXML1Controller.java, FXML2Controller.java).
In the FXML1.fxml I have two text fields and two buttons.
In the associated controller (FXML1Controller.java) I have declared the text fields and the button as follows:
public TextField textField1;
public TextField textField2;
public Button buttonchange;
public Button buttonOpenWindow;
public void open ()
{
...
stage.show ();
}
public void change ()
{
textField2.setText (textField1.getText ());
}
I type text into textField1. When I click on the buttonChange, then the text should be set in textfield2. Works. It's simple.
When I click the buttonOpen, then a new window opens.
There, I have only one button, but want to do the same.
So something in the way like this:
public void changeFromHere ()
{
FXMLController1 c1 = new FXMLController1 ();
c1.change ();
}
I also know that similar questions have been asked here.
But somehow it does not work the way I want it.
I always get a NullPointerException. For sure. I know.
So I have done the following:
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
...
public class FXML2Controller implements Initializable
{
...
public Button buttonChangeFromHere;
URL location;
FXMLLoader fxmlLoader;
Pane root;
FXMLController1 fc1;
public voidChangeFromHere ()
{
fc1.change ();
}
#Override
public void initialize (URL url, ResourceBundle rb)
{
try
{
location = getClass ().getResource ("FXML1.fxml");
fxmlLoader = new FXMLLoader (location);
root = (Pane) fxmlLoader.load ();
fc1 = (FXMLController1) fxmlLoader.getController ();
} catch (IOException ex)
{
Logger.getLogger (FXML2Controller.class.getName ()) .log (Level.SEVERE, null, ex);
}
}
...
}
Now I can not get a NullPointerException and it should work this way. But nothing happened !?
If I use for testing System.out.println (fc1.textField2.getText ());, then I get the text "Hello", which I have defined in JavaFXSceneBuilder.
If I remove the text in SceneBuilder, then I get "null". Sure. Likewise, I get "null" when I type in the term "Hello" (in textField1) while program is running.
I have also tried to initialize the textfields first in the initialize method. Then I also get always the text "Hello", although I typed "Byebye".
The solutions to similar questions in this forum can not help me.
That's why I put so a similar question again.
This code is also just an example. I can not paste my whole code here. What I really want to do is:
In my program I have a list (listView).
In the list are paths to files that I save as a file. Works fine (In the Main Controller, Main.fxml). There, I have a method public void save (). Now I want to call from another controller class's the save () method. But almost all variables are "null".
But they can't be "null", because the listView shows me the entrys.
I do not think that getter and setter methods are appropriate, because it would be very much redundant code. And I don't want that.
If someone could answer the question how to do it with textfields from example, then I would be grateful.
If it does not work with textfields, it will not work with other components, too:-(.
Thanks in advance.

Related

Create new NetBeans "save as" module

My goal is simple - save the current HTML file in the NetBeans editor with one additional line at the top and bottom of the file, and with the extension of ".h".
This is my first attempt at a NetBeans module, but following some tutorials and research, I got as far as adding an entry to the popup menu when you right-click on an HTML file in the editor. It currently just shows a "Hello World" message:
The code to do that is here:
package ksmiller99.savehtmlasarduinoresource;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionRegistration;
import org.openide.util.NbBundle.Messages;
#ActionID(
category = "Edit",
id = "ksmiller99.savehtmlasarduinoresource.SaveHtmlAsArduinoResource"
)
#ActionRegistration(
displayName = "#CTL_SaveHtmlAsArduinoResource"
)
#ActionReference(path = "Editors/text/html/Popup")
#Messages("CTL_SaveHtmlAsArduinoResource=Save as Arduino Resource")
public final class SaveHtmlAsArduinoResource implements ActionListener {
#Override
public void actionPerformed(ActionEvent ev) {
//todo add a line to top and bottom of current file and save with .h extension
JOptionPane.showMessageDialog(null, "Hello Save As World");
}
}
How can I access the contents of the current editor? Would a different approach make more sense?
I'm using NetBeans 12.0, JDK 13, Windows 10.
Use the New Action wizard to create the source code for a Conditionally Enabled action, enabled when User Selects One Node.
In the 2nd wizard panel select File Type Context Menu and choose text/html as content type. If you want your action to appear only in the context menu you can disable Global Menu Item.
You should end up with code like this:
#ActionID(
category = "File",
id = "org.test.TestHtmlAction"
)
#ActionRegistration(
displayName = "#CTL_TestHtmlAction"
)
#ActionReference(path = "Loaders/text/html/Actions", position = 0)
#Messages("CTL_TestHtmlAction=TestHtmlAction")
public final class TestHtmlAction implements ActionListener
{
private final DataObject context;
private static final Logger LOGGER = Logger.getLogger(TestHtmlAction.class.getName());
public TestHtmlAction(DataObject context)
{
this.context = context;
}
#Override
public void actionPerformed(ActionEvent ev)
{
FileObject file = context.getPrimaryFile();
LOGGER.info("context=" + context.getName() + " file.getPath()=" + file.getPath());
}
}
The wizard creates a context aware action, which is enabled only when user selects a single HTML file node. The DataObject parameter gives you the context of the selected node, so you can retrieve the file path etc.

Eclipse 4 RCP - how to remove Part from application model?

I have this utility method which allows easily to change what is shown in specific location of my application.
The problem is it looks more like that the new Part is on top of the old Part (the old Part is not removed and it is still visible under the new Part).
package cz.vutbr.fit.xhriba01.bc.ui;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
public class UI {
public static final String PART_INSPECTOR_ID = "bc.part.inspector";
public static void changeInspectorView(String partDescriptorId, EPartService partService, EModelService modelService) {
MPart part = partService.createPart(partDescriptorId);
MPart oldPart = partService.findPart(UI.PART_INSPECTOR_ID);
MPartSashContainer parent = (MPartSashContainer) modelService.getContainer(oldPart);
parent.getChildren().remove(oldPart);
part.setElementId(UI.PART_INSPECTOR_ID);
parent.getChildren().add(0, part);
}
}
You should use:
partService.hidePart(oldPart);
to hide the old part (also removes it from the children).
You might also just be able to do:
oldPart.setToBeRendered(false);
but I am not sure that does enough to update the Eclipse internal state.

Wait before Reacting to a Property Change JavaFX 8

Is there a way to keep listening to a property change, for a few seconds, then fire an event (call a method)?
For example, when the user enter data in a text field:
textField.textProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> arg0, String arg1, String arg2) {
//before calling a method to do something.. wait for a few seconds ...
}
});
A scenario would be firing an action based on the string value. For example, hitting "M" for move, or "MA" for mask. I would like to "keep listening" for 2 seconds before making an action.
As Jeffrey pointed out, you can use ReactFX:
EventStreams.valuesOf(textField.textProperty())
.successionEnds(Duration.ofSeconds(2))
.subscribe(s -> doSomething(s));
There are a few ways to solve this.
Usually I would recommend the Java Timer API, but if by "making an action" you imply updating stuff on the FX thread, you would have to synchronize the threads, which is bothersome.
Depending on your use case, you could instead use Transitions or the Timeline in FX.
Here is an example with a transition:
package application;
import javafx.animation.RotateTransition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
import javafx.util.Duration;
public class TransitionedInputExample extends Application {
#Override
public void start(final Stage stage) {
final ImageView spinner =
new ImageView("https://cdn1.iconfinder.com/data/icons/duesseldorf/16/process.png");
spinner.setVisible(false);
final Label title = new Label("Timed Action Commander Example", spinner);
title.setContentDisplay(ContentDisplay.BOTTOM);
title.setFont(Font.font("Helvetica", FontWeight.BOLD, FontPosture.REGULAR, 16));
final TextField textInput = new TextField();
textInput.setPromptText("Enter command");
final TextArea textOutput = new TextArea();
textOutput.setPromptText("Command results will show up here");
final VBox layout = new VBox(title, textInput, textOutput);
layout.setSpacing(24);
// setup some transition that rotates an icon for 2 seconds
final RotateTransition rotateTransition = new RotateTransition(Duration.seconds(1), spinner);
rotateTransition.setByAngle(90);
// delay rotation so that user can type without being distracted at once
rotateTransition.setDelay(Duration.seconds(1));
// restart transition on user input
textInput.textProperty().addListener((observable, oldText, newText) -> {
spinner.setVisible(true);
rotateTransition.playFromStart();
});
rotateTransition.setOnFinished((finishHim) -> {
// execute command
textOutput.setText("Executing " + textInput.getText());
spinner.setVisible(false);
});
final Scene scene = new Scene(layout);
stage.setScene(scene);
stage.show();
}
public static void main(final String[] args) {
launch(args);
}
}
For a solutition using a Timeline see this post .
You might consider using Inhibeans. It allows you to block the handling of an event until you want the change events to fire. The whole ReactFX project might also be useful because what essentially what you need to do is build a state machine of events. You are looking for patterns in the events like regex.
For example, let's say you use 'M' for move and 'MA' for mask. You'll have two paths through your state machine.
M
M -> A
Then you can use a timer to determine how long you'll wait for the events to pile up before you process it.
Checkout this sample copied from the ReactFX site:
reduceSuccessions
Accumulates events emitted in close temporal succession into one.
EventSource<Integer> source = new EventSource<>();
EventStream<Integer> accum = source.reduceSuccessions((a, b) -> a + b, Duration.ofMillis(200));
source.push(1);
source.push(2);
// wait 150ms
source.push(3);
// wait 150ms
source.push(4);
// wait 250ms
source.push(5);
// wait 250ms
In the above example, an event that is emitted no later than 200ms after the previous one is accumulated (added) to the previous one. accum emits these values: 10, 5.

Disabling toolbar from icePDF viewer

I am trying a sample with icePDF . Everything is working fine but i need to disable the toolbar which appears at the top. i tried few things but its not working. Can some body please help me out with it. Below is my code.
//package XML.test;
package applet;
import java.util.ResourceBundle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.icepdf.ri.common.ComponentKeyBinding;
import org.icepdf.ri.common.SwingController;
import org.icepdf.ri.common.SwingViewBuilder;
import org.icepdf.ri.util.PropertiesManager;
import org.icepdf.core.pobjects.fonts.*;
import org.icepdf.core.views.DocumentViewController;
import org.icepdf.core.*;
public class ViewerComponentExample
{
static void buildFrame(String filepath)
{
System.getProperties().put("org.icepdf.core.scaleImages", "false");
System.getProperties().put("org.icepdf.core.imageReference","smoothScaled");
System.getProperties().put("org.icepdf.core.target.dither", "VALUE_DITHER_DISABLE");
System.getProperties().put("org.icepdf.core.target.fractionalmetrics", "VALUE_FRACTIONALMETRICS_OFF");
System.getProperties().put("org.icepdf.core.target.interpolation", "VALUE_INTERPOLATION_NEAREST_ NEIGHBOR");
System.getProperties().put("org.icepdf.core.screen.interpolation", "VALUE_INTERPOLATION_NEAREST_NEIGHBOR");
System.getProperties().put("org.icepdf.core.awtFontLoading","true");
SwingController controller = new SwingController();
PropertiesManager properties = new PropertiesManager(System.getProperties(), ResourceBundle.getBundle(PropertiesManager.DEFAULT_MESSAGE_BUNDLE));
properties.setBoolean(PropertiesManager.PROPERTY_SHOW_TOOLBAR_ANNOTATION, Boolean.FALSE);
properties.setBoolean(PropertiesManager.PROPERTY_SHOW_TOOLBAR_FIT, Boolean.FALSE);
// Build a SwingViewFactory configured with the controller
SwingViewBuilder factory = new SwingViewBuilder(controller);
JPanel viewerComponentPanel = factory.buildViewerPanel();
// add copy keyboard command
ComponentKeyBinding.install(controller, viewerComponentPanel);
// add interactive mouse link annotation support via callback
controller.getDocumentViewController().setAnnotationCallback(
new org.icepdf.ri.common.MyAnnotationCallback(
controller.getDocumentViewController()));
// Use the factory to build a JPanel that is pre-configured
//with a complete, active Viewer UI.
// Create a JFrame to display the panel in
JFrame window = new JFrame("Metrics Wizard Help");
window.getContentPane().add(viewerComponentPanel);
window.pack();
window.setVisible(true);
controller.setPageFitMode(DocumentViewController.PAGE_FIT_WINDOW_WIDTH, false);
controller.openDocument(filepath);
}
public static void main(String args[])
{
String filepath = "C:/Users/vishalt/Workspaces/Eclipse 4.2 Java/htmltopdf/src/XML/output/SCB_TEST.pdf";
buildFrame(filepath);
}
}
private SwingController controller;
controller = new SwingController();
SwingViewBuilder viewBuilder = new SwingViewBuilder(controller, properties);
JPanel panel = viewBuilder.buildViewerPanel();
controller.setToolBarVisible(false);
You have to set the toolbar invisible because icePdf looks in the PDF-document for the property and overwrites your setting with default when there is no document opened!
There are two ways to this.
1) Follow this example to set all the toolbars to false.
http://www.icesoft.org/JForum/posts/list/17673.page#sthash.48ICrL2A.dpbs
2) You can modify or remove the toolbar by editing the source code for SwingViewBuilder.
Here is a link to the code: http://sventon.icesoft.org/svn/repos/repo/show//icepdf/trunk/icepdf/viewer/src/org/icepdf/ri/common/SwingViewBuilder.java?revision=34004
You probably want to comment out lines 481 - 483.
481 JToolBar toolBar = buildCompleteToolBar(embeddableComponent);
482 if (toolBar != null)
483 cp.add(toolBar, BorderLayout.NORTH)
Remove your import for SwingViewBuilder and create your own class with those lines commented out.

How to customize style sheet of Apache wicket HeadersToolbar?

I've got problem with rendering table's header .it is not display any color on table.
I used HeadersToolbar with my data some thing like below.
import org.apache.wicket.Component;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable;
import org.apache.wicket.extensions.markup.html.repeater.data.table.HeadersToolbar;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
import org.apache.wicket.extensions.markup.html.repeater.data.table.NavigationToolbar;
import org.apache.wicket.markup.html.internal.HtmlHeaderContainer;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.OddEvenItem;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
public class CustomTable extends DataTable {
private static final long serialVersionUID = 5912216230302446976L;
public CustomTable(String id, List columns,
ISortableDataProvider dataProvider, int rowsPerPage) {
this(id, (IColumn[]) columns.toArray(new IColumn[columns.size()]),
dataProvider, rowsPerPage);
}
public CustomTable(String id, IColumn[] columns,
ISortableDataProvider dataProvider, int rowsPerPage) {
super(id, columns, dataProvider, rowsPerPage);
// super(id, columns, dataProvider, rowsPerPage);
addTopToolbar(new NavigationToolbar(this));
addTopToolbar(new HeadersToolbar(this, dataProvider));
}
protected Item newRowItem(String id, int index, IModel model) {
return new OddEvenItem(id, index, model);
}
}
I saw HeaderToolbar in details it will generate CSS class "headers" .And then i see in View Source . i have got css class in name "headers".
How to do customize HeaderToolbar to get correctly table row header display color or Can i create new one Css class instead ?
Any one can help me to solve this problem ? :)
I don't understand your goal. Do you want the color of the table header to change dynamically, or are you just trying to set the color of the header statically?
If setting the color statically, you can just use css th.header {background-color: #7FFF00;} for html: <th class="header">...</th>.
If you want it dynamically set I have had success with leaving the class out of the html & injecting it with wicket when condition is met:
if(...) {
header.add(new AttributeModifier("class", "header")`;
}
With more information I may be able to provide a more complete answer. Let me know if you have additional questions.