Adding a custom component to NetBeans GUI builder! (WorldWind) - java

Ok, I'm trying to add the World Wind globe from NASA to a GUI window created by NetBeans GUI builder. My sample code instantiates its own window, and the GUI builder would like me not to edit the areas necessary to slip this in :) I'd write my own but this is part of a NetBeans platform app and contains code and annotations Im not prepared to handle yet. I am not sure how to accomplish this. Here is the sample code I would like in the window:
public class WorldWindTest {
public static void main(String[] args) {
//create a WorldWind main object
WorldWindowGLCanvas worldWindCanvas = new WorldWindowGLCanvas();
worldWindCanvas.setModel(new BasicModel());
Position myPoint = Position.fromDegrees(31.12, -88.64, 35000);
//build Java swing interface
JFrame frame = new JFrame("World Wind");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(worldWindCanvas);
frame.setSize(800,600);
frame.setVisible(true);
//create some "Position" to build a polyline
LinkedList<Position> list = new LinkedList<Position>();
// list.add(Position.fromDegrees(i,0.0,i*20000));
}
list.add(Position.fromDegrees(30.12, -85.64, 35000));
list.add(Position.fromDegrees(31.12, -88.64, 35000));
//create "Polyline" with list of "Position" and set color / thickness
Polyline polyline = new Polyline(list);
polyline.setColor(Color.RED);
polyline.setLineWidth(3.0);
//create a layer and add Polyline
RenderableLayer layer = new RenderableLayer();
layer.addRenderable(polyline);
//add layer to WorldWind
worldWindCanvas.getModel().getLayers().add(layer);
}
}

To amplify on my comment, I was thinking that you could create a class, say called SetUpWorldWindowGLCanvas, and in it, initialize and set up your WorldWindowGLCanvas object, and then give it a public getter method that would allow you to obtain the set up WorldWindowGLCanvas object. i.e.,
public class SetUpWorldWindowGLCanvas {
WorldWindowGLCanvas worldWindCanvas = new WorldWindowGLCanvas();
public SetUpWorldWindowGLCanvas() {
worldWindCanvas.setModel(new BasicModel());
Position myPoint = Position.fromDegrees(31.12, -88.64, 35000);
// ... etc
}
public WorldWindowGLCanvas getWwGlCanvas() {
return worldWindCanvas;
}
}
And then place this BorderLayout.CENTER in a JPanel that was created in your GUI builder and that uses BorderLayout as its layout manager.

Instead of using the GUI editor for your entire application, limit it's use just the few containers that will most benefit from it, e.g. difficult layouts. Then your WorldWindowGLCanvas can be added normally to your top-level container. In this example, WorldWindowGLCanvas would appear alongside NewJPanel:
JFrame f = new JFrame();
f.setLayout)new GridLayout(1, 0);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(worldWindCanvas);
f.add(new NewJPanel());
f.pack();
f.setVisible(true);

Related

How to implement pages in Java Swing app.?

I have some experience in Java creating Apps and would like to learn more, and so have decided to create an application that will have different pages. For example the initial frame will show a menu of buttons that will lead to different frames, showing different components and layouts.
I'm not too sure the best practice of implementing pages. I think I could store the JFrame windows in a list, then use a button handler class to maybe change the visibility of the different frames, only allowing the relevant frame to be visible when the user clicks on a button. I think this method could work, but is there a more efficient/practical way of doing this?
I am aware of CardLayout, however for this program I am trying to learn MigLayout; so that won't be possible (as far as I'm aware). I hope this question is not too vague, I'd just like to know the best practice when it comes to creating applications in Java with different pages.
Can use Tabbed Panes, it is the best for storing pages.
https://docs.oracle.com/javase/tutorial/uiswing/components/tabbedpane.html
Also I noticed that you need to consider top level containers properly, because you don't need to create every time a JFrame for each Page, at least if it was necessary(For example: an editor, create a new window so you need to create a new JFrame, in your case I don't think so) so please consider the link below.
https://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html
JInternalFrame is a part of Java Swing . JInternalFrame is a container that provides many features of a frame which includes displaying title, opening, closing, resizing, support for menu bar, etc. Internal frames with components example
Code to create multiple internal frames:
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
class solution extends JFrame {
// frame
static JFrame f;
// label to diaplay text
static JLabel l, l1;
// main class
public static void main(String[] args) {
// create a new frame
f = new JFrame("frame");
// set layout of frame
f.setLayout(new FlowLayout());
// create a internal frame
JInternalFrame in = new JInternalFrame("frame 1", true, true, true, true);
// create a internal frame
JInternalFrame in1 = new JInternalFrame("frame 2", true, true, true, true);
// create a Button
JButton b = new JButton("button");
JButton b1 = new JButton("button1");
// create a label to display text
l = new JLabel("This is a JInternal Frame no 1 ");
l1 = new JLabel("This is a JInternal Frame no 2 ");
// create a panel
JPanel p = new JPanel();
JPanel p1 = new JPanel();
// add label and button to panel
p.add(l);
p.add(b);
p1.add(l1);
p1.add(b1);
// set visibility internal frame
in.setVisible(true);
in1.setVisible(true);
// add panel to internal frame
in.add(p);
in1.add(p1);
// add internal frame to frame
f.add(in);
f.add(in1);
// set the size of frame
f.setSize(300, 300);
f.show();
}
}

JButton and jgraphx wont show up at the same time

I have tried several ways, but still havent found the solution. I have a jgraph in a frame and I want to add a Jbutton in that frame also in a specific location. However I only get one of them when i run the program, because they expand to the whole window. Any ideas how to fix this?
Thanks in advance.
public class GUIquery extends JFrame {
JFrame frame;
static JGraph jgraph;
final mxGraph graph = new mxGraph();
final mxGraphComponent graphComponent = new mxGraphComponent(graph);
public GUIquery() {
super("Test");
GraphD();
imgbtn();
}
public void GraphD() {
Object parent = graph.getDefaultParent();
graph.getModel().beginUpdate();
try {
........
}catch {
........
} finally {
graph.getModel().endUpdate();
}
getContentPane().add(graphComponent);
}
public void imgbtn() {
JPanel jpanel = new JPanel();
jpanel.setSize(100, 100);
jpanel.setLocation(1200, 60);
JButton imgbtn = new JButton("Export as Image");
imgbtn.setSize(100, 100);
imgbtn.setLocation(1200, 60);
jpanel.add(imgbtn);
add(jpanel);
}
public static void main(String[] args) {
GUIquery frame = new GUIquery();
frame.setLayout(null);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 320);
frame.setVisible(true);
}
}
Don't use null layouts. They inevitably result in trouble.
From your code snippet it is impossible to tell where you want them to be relative to each other, the following puts the button below the graph.
The content pane uses BorderLayout by default. For BorderLayout, you need to use place components at different positions:
// the default position, but it does not hurt to be explicit
add(graph, BorderLayout.CENTER);
...
// and the panel
add(jpanel, BorderLayout.SOUTH);
If the positioning is not what you want, take a look at the visual guide to layout managers to pick the layout manager that suits your needs best.
In the button panel the setLocation() and setSize() calls are useless. The layout manager of the panel is responsible for setting the button's bounds. If the default FlowLayout is not what you want for it, use the guide to pick another for the panel too.

JTree async node creation is not consistent with JGraph library

I am creating a Jtree with a rootNode and than create another thread that update the root node asynchronously.
It works fantastic if i run this Jtree independently in some JPanel, it was even working at some place in the project, but i was asked to have this Jtree in some new swing Component.
In new Swing Panel, it doesnot populate fully, it only populate the nodes that were inserted (at start for few milliseconds) before the Jtree was rendered on the Screen. Once the Jtree is rendered it doesnt get updated.
Now the interesting part i also made a mouse listener on the node so that i can create a new node by right click create node function, and with that new node is created and is added on the Jtree root node.
Important thing to add i was using newThread(){void run}).start() method to create a thread to add node on the Jtree, becuase i never felt the need of SwingUtilities.invokeLater method before. but now if i used SwingUtilities.invokeLater method than the main window also doesnot open it just halts during the startup, i just checked that SwingUtilities.invokeLater also works fine with the old component and ofcourse works fine independently.
And i do call model.nodeStructureChanged(changedNode); after adding the node thats why it was working fine before.
Kindly asist,
code is difficult to extract and Jtree code was working fine before, may be some component block the containing widgets to refresh itself async?
EDIT
Update to include some code, i am using Temp class as provided by Nick:-
public BasicGraphEditor(String appTitle, mxGraphComponent component)
{
// Stores and updates the frame title
this.appTitle = appTitle;
// Stores a reference to the graph and creates the command history
graphComponent = component;
final mxGraph graph = graphComponent.getGraph();
undoManager = createUndoManager();
// Do not change the scale and translation after files have been loaded
graph.setResetViewOnRootChange(false);
// Updates the modified flag if the graph model changes
graph.getModel().addListener(mxEvent.CHANGE, changeTracker);
// Adds the command history to the model and view
graph.getModel().addListener(mxEvent.UNDO, undoHandler);
graph.getView().addListener(mxEvent.UNDO, undoHandler);
// Keeps the selection in sync with the command history
mxIEventListener undoHandler = new mxIEventListener()
{
#Override
public void invoke(Object source, mxEventObject evt)
{
List<mxUndoableChange> changes = ((mxUndoableEdit) evt
.getProperty("edit")).getChanges();
graph.setSelectionCells(graph
.getSelectionCellsForChanges(changes));
}
};
undoManager.addListener(mxEvent.UNDO, undoHandler);
undoManager.addListener(mxEvent.REDO, undoHandler);
// Creates the graph outline component
graphOutline = new mxGraphOutline(graphComponent);
// Creates the library pane that contains the tabs with the palettes
libraryPane = new JTabbedPane();
/////////////////////////////////////////////////
// Only change i have done here: start
////////////////////////////////////////////////
Temp tempExplorer = new Temp();
libraryPane.add("new Explorere", tempExplorer);
/////////////////////////////////////////////////
// Only change i have done here: End
////////////////////////////////////////////////
// Creates the inner split pane that contains the library with the
// palettes and the graph outline on the left side of the window
JSplitPane inner = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
libraryPane, graphOutline);
inner.setDividerLocation(320);
inner.setResizeWeight(1);
inner.setDividerSize(6);
inner.setBorder(null);
// Creates the outer split pane that contains the inner split pane and
// the graph component on the right side of the window
JSplitPane outer = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, inner,
graphComponent);
outer.setOneTouchExpandable(true);
outer.setDividerLocation(200);
outer.setDividerSize(6);
outer.setBorder(null);
// Creates the status bar
statusBar = createStatusBar();
// Display some useful information about repaint events
installRepaintListener();
// Puts everything together
setLayout(new BorderLayout());
add(outer, BorderLayout.CENTER);
add(statusBar, BorderLayout.SOUTH);
installToolBar();
// Installs rubberband selection and handling for some special
// keystrokes such as F2, Control-C, -V, X, A etc.
installHandlers();
installListeners();
updateTitle();
}
The above class is from Jgraph library as https://github.com/jgraph/jgraphx
And i am just adding the jtree component like as above, no other changes.
please help.
Swing isn't thread safe unless explicitly stated. In the JavaDocs for JTree, it explicitly says this isn't thread safe. If you update it in a thread outside the EDT, there's no guarentee anything will work. So if you want to update a JTree from a different Thread, you need to use SwingUtilities.invokeLater(Runnable run); in order to put the request on the EDT.
I'd recommend having a data structure to store the info of the JTree, and only using the JTree for User Interaction (not data storage).
EDIT
Here's an example of using SwingUtilities.invokeLater() to update a JTree while in the component model. Without you posting any code, this is the best I have to work with. Please try to use this to recreate your problem (add pieces of your code to this example until you have narrowed down what the problem is).
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
public class Temp extends JPanel{
JTree tree = new JTree();
public Temp(){
JScrollPane jsp = new JScrollPane(tree);
// Creates the library pane that contains the tabs with the palettes
JTabbedPane libraryPane = new JTabbedPane();
libraryPane.add("new Explorere", jsp);
// Creates the inner split pane that contains the library with the
// palettes and the graph outline on the left side of the window
JSplitPane inner = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
libraryPane, new JPanel());
inner.setDividerLocation(320);
inner.setResizeWeight(1);
inner.setDividerSize(6);
inner.setBorder(null);
// Creates the outer split pane that contains the inner split pane and
// the graph component on the right side of the window
JSplitPane outer = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, inner,
new JPanel());
outer.setOneTouchExpandable(true);
outer.setDividerLocation(200);
outer.setDividerSize(6);
outer.setBorder(null);
// Puts everything together
setLayout(new BorderLayout());
add(outer, BorderLayout.CENTER);
}
public static void main(String[] args) {
final Temp temp = new Temp();
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(temp);
frame.pack();
frame.setVisible(true);
}});
Thread updater = new Thread(temp.new CustomThread());
updater.start();
}
public class CustomThread implements Runnable{
#Override
public void run() {
for(int i = 0; i < 1000; i++){
updateTree("New Item "+ i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void updateTree(final String nodeToAdd){
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot();
DefaultMutableTreeNode child = new DefaultMutableTreeNode(nodeToAdd);
model.insertNodeInto(child, root,root.getChildCount());
tree.scrollPathToVisible(new TreePath(child.getPath()));
}});
}
}
}

How to display panel which is of Singleton class in two different frames at a time?

I am trying to display a singleton obj on two different Jframe, but it is displayed only in the Jframe in which the object is added at last ( in example Frame2). Other Jframe is empty. This Singleton class is inherited from Panel and contains a label in it. Can anybody please tell me how can i display this singleton object in two different frame ?
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable()
{
public void run() {
NewJFrame inst = new NewJFrame();
inst.setTitle("Frame1");
inst.setSize(300, 300);
inst.setLocationRelativeTo(null);
inst.setVisible(true);
singltonpanel _sin = singltonpanel.instance();
inst.add(_sin);
inst.repaint();
JFrame frame = new JFrame("Frame2");
frame.setSize(300, 300);
frame.setVisible(true);
singltonpanel _sin1 = singltonpanel.instance();
frame.add(_sin1);
frame.repaint();
}
});
A Swing component is only allowed to have a single parent. You may not add a component to two containers.
From http://java.sun.com/docs/books/tutorial/uiswing/components/toplevel.html
Each GUI component can be contained
only once. If a component is already
in a container and you try to add it
to another container, the component
will be removed from the first
container and then added to the
second.
In other words, Swing requires your components to be arranged in a tree-hierarchy.
Solution: You basically need to break up your singleton-class into a model class and a view class. (Check out the MVC pattern at http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) Then instantiate multiple views of the model.

add Component to JPanel

I am using netBeans editor to create desktop application . and i want to add Component without using drag and drop way. I am trying code like this for adding JList to JPanel but nothing showed
JList jl = new JList();
Vector<String> v= new Vector<String>();
v.add("one");
v.add("Two");
v.add("Three");
jl.setListData(v);
JScrollPane js = new JScrollPane(jl);
js.setLocation(50, 50);
js.setSize(100, 100);
js.setVisible(true);
jPanel1.add(js);
I want to add Component without using drag and drop way.
Here's a simple JList example that doesn't use the NetBeans' GUI editor. See How to Use Lists for more.
import java.awt.*;
import java.util.Random;
import javax.swing.*;
public class JListTest {
private static final Random random = new Random();
public static final void main(String args[]) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
final DefaultListModel dlm = new DefaultListModel();
for (int i = 0; i < 1000; i++) {
dlm.addElement("Z" + (random.nextInt(9000) + 1000));
}
final JList list = new JList(dlm);
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(new JScrollPane(list), BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}
The scroll list doesn't appear, or the data items in the list? Also, you're setting the position manually. Seriously, don't do that -- use a layout manager, many of which are available and you can easily use in the Netbeans GUI editor Mattise.
If the main window is under the control of a layout manager and then you add something to it that specifies its position and size, all mayhem will break loose. Namely, the layout manager will overwrite this, possibly with the result of size becoming 0, 0.
What you need to do is create a JPanel in your layout manager to hold the position of the new component and make sure it has a known field name you can reference and use to add to. Make sure that Panel also has FlowLayout or something in the properties.
you may want to call repaint() when you dynamically create GUI elements.

Categories