JavaFX - Remove Element from SwingNode - java

Suppose I've done this -
SwingNode deviceView = new SwingNode();
JDesktopPane desktop = new JDesktopPane();
// Add elements to desktop
deviceView.setContent(desktop);
Is there a way remove desktop from deviceView? The best way I can come up with is -
deviceView.setContent(new JPanel());
But is there a way to simply remove it?
As noted in the comments I've tried deviceView.setContent(null); which appears to be bugged.

You may try this out and let us know how it goes, although I have not tried it out.
deviceView.getContent().removeAll();

Late to the party but here is what you could try.
deviceView.getContent().removeAll(); /****Note : The UI may not show any updates even if you run it inside the SwingUtilities.invokeLater method */
/**** Now set a new instance that would allow you to set any other content later. At least that is what i have done in one of our Java FX App.*/
deviceView = new SwingNode();

Related

How to reload an Application in JavaFX?

I have a small game which has New Game button. There are many variables which need reset when the New Game button is pressed. Is there any method which can easily reload the whole application or any alternative to refresh the scene, stage or variables? I just want to bring the application to it's initial stage when It's first loaded.
I went through different topics on internet and read many questions and answers here also, but I there is no easy method to implement it. Most of the answers suggest to reuse the whole code or put the whole code in class and reload it.
Questions reviewed:
How to restart a JavaFX application when button is clicked?
How can you reload or refresh a scene with javafx 1.3
I would certainly recommend a clean approach as discussed in the questions you linked.
A quick and dirty way however might be the following:
restartButton.setOnAction( __ ->
{
System.out.println( "Restarting app!" );
primaryStage.close();
Platform.runLater( () -> new ReloadApp().start( new Stage() ) );
} );
Close the main stage, create a new one and pass it to a new instance of your App. I cannot make any guarantees about the memory behavior of this hack. Use it carefully.
Full example: https://gist.github.com/bugabinga/ce9e0ae2328ba34133bd
for reload application you must create new instance of your main class and call
the start method of it with stage parameter.for example
restartButton.setOnAction(e->{yourAPP app=new yourApp();
app.start(yourStage);});

How do I add a Table Layout to a Java GUI in NetBeans?

For my employers purposes we are moving from .Net to Java. I have worked with .Net for the better part of the past two years and I have worked with Java for like... two months.
I know very little about it.
A bit of google searching and my employers counsel revealed that NetBeans has a GUI builder, and I've begun working with it and I like what I see. It feels very familiar to me from working with .Net.
However, what my google searches did NOT reveal was the answer to my question that I am asking here, which I suppose is two-fold:
1: What is the Java/Swing/AWT Equivalent to .Nets (C#/VB) TableLayoutPanel component (if one exists)
2: If it does exist, how do I go about adding it to the NetBeans IDE GUI Palette to make use of it? (I'm REALLY hoping it's as easy as drag/drop but I'm not holding my breath).
There is no specific panel with a table layout, but you can use a regular JPanel and give it a GridLayout:
JPanel pane = new JPanel( );
pane.setLayout( new GridLayout( nrOfRows, nrOfColumns ) );

Create logical GUI components group using windows builder

I am writing a GUI app in WindowsBuilder eclipse java and have some questions:
I have a check button that if it's checked some controls are enabled. Is there an elgant way to allow all of them by one command? I mean that I dont want to enable them one by one, just enable them at once - is it possible to define a logical group that will allow me to do it?
Is there any common design pattern to write Java GUI applications?
I am new in Java, so will appriciate any guidance in these queastion.
Thanks!
There is no build-in function to check/uncheck them all with one command.
The "easiest" way that comes to mind is to store them all in a List and create a function that iterates over that list and checks/unchecks everything.
private List<Button> buttons = new ArrayList<Button>();
// ADD YOUR BUTTONS
private void setSelectionForButtons(boolean enabled)
{
for(Button button : buttons)
button.setSelection(enabled);
}
Then you can check/uncheck them all by calling:
setSelectionForButtons(true);
or
setSelectionForButtons(false);
As for the "design patterns": There is an excellent tutorial for writing SWT applications here.

Updating JTabbedPane components

I am writing a simple chat program that shows different dialogs in different tabs of a JTabbedPane. I used a JTextArea to display the dialog. I added a JTextArea to the tab like this:
JTextArea referenceToAppend = new JTextArea();
JTabbedPane.addTab(title,new JPanel(new JScrollBar(referenceToAppend)));
I put the reference referenceToAppend into a List, then when I need to append text I do
the following :
List.get(index).append(textForAppend);
The problem is: my application becomes unresponsive. How can I solve this problem? I looked up a lot of information on forums and of course, Oracle. I can't find what I need. Maybe I was inattentive or may be I am not understanding something simple. I will be very grateful if someone could give a simple example or link to another forum where they discuss this problem.
Take a look at SwingWorker. It allows you to perform operations in a background thread an report information to the Event Dispatch Thread. If you need to block on a socket read, you need to do that on a background thread to keep the UI responsive.

JTree refreshing after setting new jtree model

I'm trying to use dynamically JTree component.
Under root node I have four nodes and one of them ("Operations") can have 0 to many children. This is set by user via editable list in separate window opened on users request. After editing this list user hits button 'Save' and then magic should happen. Edited list is sent to server(on the same machine actually, so it doesn't take to long), the window with list is closed but right before that the main window (with jtree) is told to refresh itself, and I can see that it does what is told in log output, but the changes don't show on the screen.
I am using DefaultTreeModel, this method is called to create model at the beginning(when first opening the window) and after the change to update the new model with new structure.
with dmtn.getLeafCount() I can see that newly downloaded structure from server is the right one with the changed number of leaves under 'Operations'
public DefaultTreeModel getDataStructure() {
int dataID = task.getData().getId();
LoggerUtility.logger.info("Data ID: " + dataID);
DefaultMutableTreeNode dmtn = Manager.manager.getDataStructure(task.getId());
LoggerUtility.logger.info("DTMN created "+dmtn.getLeafCount());
return new DefaultTreeModel(dmtn);
}
the method used to refresh the jtree looks like this (it's very messy):
public void updateTree(){
taskDataTree.setModel(getDataStructure());
((DefaultTreeModel)taskDataTree.getModel()).reload();
this.revalidate();
this.repaint();
taskDataTree.revalidate();
taskDataTree.repaint();
taskDataTree.updateUI();
taskDataTree.setVisible(false);
taskDataTree.setVisible(true);
jScrollPane2.setViewportView(taskDataTree);
}
It's very messy because I have tried to put in there every possible solution to my problem that I have found on forums,
I also tried with my own treemodel implementation which would call fireTreeStructureChanged(...) but it also didn't change.
I should probably also add that I'm using Netbeans GUI Builder to build my gui although I don't know if it has anything to do with that.
I would be very grateful for any help with that
BR
Lucja
EDIT!!!
I also tried puting it in another thread like that:
public void updateTree() {
SwingWorker sw = new SwingWorker() {
#Override
protected Object doInBackground() throws Exception {
taskDataTree.setModel(getDataStructure());
((DefaultTreeModel) taskDataTree.getModel()).reload();
taskDataTree.revalidate();
taskDataTree.repaint();
taskDataTree.updateUI();
taskDataTree.setVisible(false);
taskDataTree.setVisible(true);
jScrollPane2.setViewportView(taskDataTree);
return null;
}
};
sw.execute();
}
but it also didn't help.
tree.setModel( anotherModel );
Is the only line of code that you need.
If it doesn't work then it means that the tree variable does not contain a reference to the tree that was added to the GUI. Maybe you have a class variable and a local variable of the same name.
From my point of view the own TreeModel implementation was a good approach. But I know that creating an TreeModelEvent with the correct data isn't that simple.
I would suggest to update your question with your TreeModel implementation so that we can find the problem with it.
In principle it should work this way (when you set a new Model, the tree reloads itself). (This is not the most efficient way, better let the model send appropriate events when it changes.)
If this does not work, make sure you are calling the setModel method in the AWT Event Dispatch Thread (with EventQueue.invokeLater (or SwingUtilities.invokeLater, which is the same), for example. I think you should not need all your revalidate(), repaint() etc. calls (and updateUI should only be done if you changed the look-and-feel configuration).

Categories