how to call jFrame on jDesktopPane without using JInternalFrame - java

I completed my project which assigned to me by university but now I am trying to create MDI for my project. I used 10 jFrame and one main form which is also jFrame, after that I add one Menu Bar, 10 jButtons for calling jFrame and one jDesktopPane for place calling jFrame. The below code using for calling jFrame place into jDesktopPane in all 10 jButton:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
try
{
asd t = new asd();
dskp.add(t);
t.setVisible(true);
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null, ex);
}
}
but not working with me and giving below error message:
java.lang.illegalargumentexception: adding a window to a container
How to do this and solve this issue because I didn't used any jInternal Frame. I think at this I am not able to use jInternale Frame because I did all work on jFrame such as full GUI with code and re-doing all work on jInternal Frame its not possible for me coz of short of time to submitting my final project.

If you're desiring to placing windows intp a JDesktopPane, then you need to use JInternalFrames. This is your best solution whether it is appealing to you or not.
A lesson in this is that you should strive to avoid creating classes that extend Swing components, especially top-level components such as JFrames, and instead create classes that produce JPanels, components that are flexible enough to be placed anywhere such as into JFrames, JInternalFrames, JDialogs, JOptionPanes, other JPanels, etc...
Note that a kludge is to get the contentPane from your JFrame, put it into a JInternalFrame and put that into the JDesktopPane, either that or set the JInternalPanes's contentPane with that from the JFrame. i.e.,
asd t = new asd();
JInternalFrame internalFrame = new JInternalFrame();
internalFrame.setContentPane(t.getContentPane());
internalFrame.pack();
// set the internalFrame's location
// ...
internalFrame.setVisible(true);
dskp.add(internalFrame);
But again note that this is a kludge and carries potential traps.

Related

How to set a JPanel to a different one [duplicate]

To put it simple, there's a simple java swing app that consists of JFrame with some components in it. One of the components is a JPanel that is meant to be replaced by another JPanel on user action.
So, what's the correct way of doing such a thing? I've tried
panel = new CustomJPanelWithComponentsOnIt();
parentFrameJPanelBelongsTo.pack();
but this won't work. What would you suggest?
Your use case, seems perfect for CardLayout.
In card layout you can add multiple panels in the same place, but then show or hide, one panel at a time.
1) Setting the first Panel:
JFrame frame=new JFrame();
frame.getContentPane().add(new JPanel());
2)Replacing the panel:
frame.getContentPane().removeAll();
frame.getContentPane().add(new JPanel());
Also notice that you must do this in the Event's Thread, to ensure this use the SwingUtilities.invokeLater or the SwingWorker
frame.setContentPane(newContents());
frame.revalidate(); // frame.pack() if you want to resize.
Remember, Java use 'copy reference by value' argument passing. So changing a variable wont change copies of the reference passed to other methods.
Also note JFrame is very confusing in the name of usability. Adding a component or setting a layout (usually) performs the operation on the content pane. Oddly enough, getting the layout really does give you the frame's layout manager.
Hope this piece of code give you an idea of changing jPanels inside a JFrame.
public class PanelTest extends JFrame {
Container contentPane;
public PanelTest() {
super("Changing JPanel inside a JFrame");
contentPane=getContentPane();
}
public void createChangePanel() {
contentPane.removeAll();
JPanel newPanel=new JPanel();
contentPane.add(newPanel);
System.out.println("new panel created");//for debugging purposes
validate();
setVisible(true);
}
}
On the user action:
// you have to do something along the lines of
myJFrame.getContentPane().removeAll()
myJFrame.getContentPane().invalidate()
myJFrame.getContentPane().add(newContentPanel)
myJFrame.getContentPane().revalidate()
Then you can resize your wndow as needed.
Game game = new Game();
getContentPane().removeAll();
setContentPane(game);
getContentPane().revalidate(); //IMPORTANT
getContentPane().repaint(); //IMPORTANT
It all depends on how its going to be used. If you will want to switch back and forth between these two panels then use a CardLayout. If you are only switching from the first to the second once and (and not going back) then I would use telcontars suggestion and just replace it. Though if the JPanel isn't the only thing in your frame I would use
remove(java.awt.Component) instead of removeAll.
If you are somewhere in between these two cases its basically a time-space tradeoff. The CardLayout will save you time but take up more memory by having to keep this whole other panel in memory at all times. But if you just replace the panel when needed and construct it on demand, you don't have to keep that meory around but it takes more time to switch.
Also you can try a JTabbedPane to use tabs instead (its even easier than CardLayout because it handles the showing/hiding automitically)
The other individuals answered the question. I want to suggest you use a JTabbedPane instead of replacing content. As a general rule, it is bad to have visual elements of your application disappear or be replaced by other content. Certainly there are exceptions to every rule, and only you and your user community can decide the best approach.
Problem: My component does not appear after I have added it to the container.
You need to invoke revalidate and repaint after adding a component before it will show up in your container.
Source: http://docs.oracle.com/javase/tutorial/uiswing/layout/problems.html
I was having exactly the same problem!! Increadible!! The solution I found was:
Adding all the components (JPanels) to the container;
Using the setVisible(false) method to all of them;
On user action, setting setVisible(true) to the panel I wanted to
show.
// Hiding all components (JPanels) added to a container (ex: another JPanel)
for (Component component : this.container.getComponents()) {
component.setVisible(false);
}
// Showing only the selected JPanel, the one user wants to see
panel.setVisible(true);
No revalidate(), no validate(), no CardLayout needed.
The layout.replace() answer only exists/works on the GroupLayout Manager.
Other LayoutManagers (CardLayout, BoxLayout etc) do NOT support this feature, but require you to first RemoveLayoutComponent( and then AddLayoutComponent( back again. :-) [Just setting the record straight]
I suggest you to add both panel at frame creation, then change the visible panel by calling setVisible(true/false) on both.
When calling setVisible, the parent will be notified and asked to repaint itself.
class Frame1 extends javax.swing.JFrame {
remove(previouspanel); //or getContentPane().removeAll();
add(newpanel); //or setContentPane(newpanel);
invalidate(); validate(); // or ((JComponent) getContentPane()).revalidate();
repaint(); //DO NOT FORGET REPAINT
}
Sometimes you can do the work without using the revalidation and sometimes without using the repaint.My advise use both.
Just call the method pack() after setting the ContentPane, (java 1.7, maybe older) like this:
JFrame frame = new JFrame();
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
....
frame.setContentPane(panel1);
frame.pack();
...
frame.setContentPane(panel2);
frame.pack();
...

Is there a way I can swap JPanel classes into and out of a JFrame? [duplicate]

To put it simple, there's a simple java swing app that consists of JFrame with some components in it. One of the components is a JPanel that is meant to be replaced by another JPanel on user action.
So, what's the correct way of doing such a thing? I've tried
panel = new CustomJPanelWithComponentsOnIt();
parentFrameJPanelBelongsTo.pack();
but this won't work. What would you suggest?
Your use case, seems perfect for CardLayout.
In card layout you can add multiple panels in the same place, but then show or hide, one panel at a time.
1) Setting the first Panel:
JFrame frame=new JFrame();
frame.getContentPane().add(new JPanel());
2)Replacing the panel:
frame.getContentPane().removeAll();
frame.getContentPane().add(new JPanel());
Also notice that you must do this in the Event's Thread, to ensure this use the SwingUtilities.invokeLater or the SwingWorker
frame.setContentPane(newContents());
frame.revalidate(); // frame.pack() if you want to resize.
Remember, Java use 'copy reference by value' argument passing. So changing a variable wont change copies of the reference passed to other methods.
Also note JFrame is very confusing in the name of usability. Adding a component or setting a layout (usually) performs the operation on the content pane. Oddly enough, getting the layout really does give you the frame's layout manager.
Hope this piece of code give you an idea of changing jPanels inside a JFrame.
public class PanelTest extends JFrame {
Container contentPane;
public PanelTest() {
super("Changing JPanel inside a JFrame");
contentPane=getContentPane();
}
public void createChangePanel() {
contentPane.removeAll();
JPanel newPanel=new JPanel();
contentPane.add(newPanel);
System.out.println("new panel created");//for debugging purposes
validate();
setVisible(true);
}
}
On the user action:
// you have to do something along the lines of
myJFrame.getContentPane().removeAll()
myJFrame.getContentPane().invalidate()
myJFrame.getContentPane().add(newContentPanel)
myJFrame.getContentPane().revalidate()
Then you can resize your wndow as needed.
Game game = new Game();
getContentPane().removeAll();
setContentPane(game);
getContentPane().revalidate(); //IMPORTANT
getContentPane().repaint(); //IMPORTANT
It all depends on how its going to be used. If you will want to switch back and forth between these two panels then use a CardLayout. If you are only switching from the first to the second once and (and not going back) then I would use telcontars suggestion and just replace it. Though if the JPanel isn't the only thing in your frame I would use
remove(java.awt.Component) instead of removeAll.
If you are somewhere in between these two cases its basically a time-space tradeoff. The CardLayout will save you time but take up more memory by having to keep this whole other panel in memory at all times. But if you just replace the panel when needed and construct it on demand, you don't have to keep that meory around but it takes more time to switch.
Also you can try a JTabbedPane to use tabs instead (its even easier than CardLayout because it handles the showing/hiding automitically)
The other individuals answered the question. I want to suggest you use a JTabbedPane instead of replacing content. As a general rule, it is bad to have visual elements of your application disappear or be replaced by other content. Certainly there are exceptions to every rule, and only you and your user community can decide the best approach.
Problem: My component does not appear after I have added it to the container.
You need to invoke revalidate and repaint after adding a component before it will show up in your container.
Source: http://docs.oracle.com/javase/tutorial/uiswing/layout/problems.html
I was having exactly the same problem!! Increadible!! The solution I found was:
Adding all the components (JPanels) to the container;
Using the setVisible(false) method to all of them;
On user action, setting setVisible(true) to the panel I wanted to
show.
// Hiding all components (JPanels) added to a container (ex: another JPanel)
for (Component component : this.container.getComponents()) {
component.setVisible(false);
}
// Showing only the selected JPanel, the one user wants to see
panel.setVisible(true);
No revalidate(), no validate(), no CardLayout needed.
The layout.replace() answer only exists/works on the GroupLayout Manager.
Other LayoutManagers (CardLayout, BoxLayout etc) do NOT support this feature, but require you to first RemoveLayoutComponent( and then AddLayoutComponent( back again. :-) [Just setting the record straight]
I suggest you to add both panel at frame creation, then change the visible panel by calling setVisible(true/false) on both.
When calling setVisible, the parent will be notified and asked to repaint itself.
class Frame1 extends javax.swing.JFrame {
remove(previouspanel); //or getContentPane().removeAll();
add(newpanel); //or setContentPane(newpanel);
invalidate(); validate(); // or ((JComponent) getContentPane()).revalidate();
repaint(); //DO NOT FORGET REPAINT
}
Sometimes you can do the work without using the revalidation and sometimes without using the repaint.My advise use both.
Just call the method pack() after setting the ContentPane, (java 1.7, maybe older) like this:
JFrame frame = new JFrame();
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
....
frame.setContentPane(panel1);
frame.pack();
...
frame.setContentPane(panel2);
frame.pack();
...

JFrame changing screens

I'm wondering how to change screens in a JFrame. For example, changing from the starting screen to a different screen. So you have an assortment of buttons, labels, trees, etc on one screen, as the user clicks a button a different layout appears.
Would the 'setVisible(false) and setVisible(true)' do the trick?
You've got it! Create separate JFrame instances for each of your frames:
JFrame frame1 = new JFrame();
JFrame frame2 = new JFrame();
//populate your frames with stuff
frame1.setVisible(false);
frame2.setVisible(true);
On a side note, you'll want to make sure to use setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE) on any secondary frames to prevent your application from terminating if a user closes a secondary frame.
All that being said, you can also use multiple JPanel instances inside of the same JFrame instead of creating multiple JFrame instances. This way, all the action of your application will take place in one window.
I would strongly recommend giving this a read through: http://docs.oracle.com/javase/tutorial/uiswing/

How can i display new GUI based on menu click

I am learning java and building one project to test basics.
I have one menu item FILE and then sub menu item like
1)Front
2)Admin
3)Booking
I have separate gui made in separate files but i want that they should be visible in one area , with click on submenus
I am using swing , JmenuBar . Also the other guis are using Jframe
I have separate gui made in separate files but i want that they should be visible in one area
Most applications should only ever have a single JFrame, which indeed is your requirement since you want the separate GUI to be visible in the same area.
Therefore your other GUI, should not extend JFrame but instead should extend JPanel. Then you can just use a CardLayout on your real GUI to swap the panels in/out depending on which panel is selected from your menu. All these basic are covered in the Swing tutorial. I guess you would start with the section on:
How to Use Card Layout
How to Use Menus
Other people have already talked about ActionListeners and stuff, so that's half of the problem. The other half is how to actually deal with the multiple windows. I would probably not use one JFrame per different GUI, given that the spirit of the JFrame suggests you should only have one instance of it per application. Instead, I would look at using either JDialog or JInternalFrame. I'm not sure what you mean by
...should be visible in one area...
but JInternalFrame will allow you to implement something like a multiple document interface, where all the sub-GUIs would be contained within the frame of the main UI. JDialog would be give you independent windows like JFrame does.
If with "they should be visible in one area" you mean modal, then you should change all your JFrames to JDialogs and leave only the JFrame that contains your main-menu.
To do this, you need an ActionListener for each of the menu items. Then have each listener pass the instance of the JFrame you want to a method that controls where you want to position the window and show it.
//Make menu items
JMenuItem font = new JMenuItem();
font.addActionListener(new ActionListener() {
showWindow(new FontFrame());
});
JMenuItem admin = new JMenuItem();
admin.addActionListener(new ActionListener() {
showWindow(new AdminFrame());
});
...
//define frame handling method
void showWindow(JFrame f) {
...
f.setVistible(true);
}

Java GUI Design Advice

I'm programming my very first GUI app in Java using the Swing framework. I've coded a basic login system using the JTextField, JPasswordField, and JButton classes. Now, I'm writing the actionPerformed method for the button, which I want to remove these items as they are no longer necessary, but I am unsure as to the best way of achieving this.
I've considered using the setVisible method of these components, which seems to work, but I'm sure that's not the preferred way of doing it. Sorry if this is a bit of a dumb question..
Have your login dialog separated from your main window. When you finished with the login, just hide the login dialog.
You can also save your text fields and buttons into a class field, and later call remove(Component) for each one.
Generally, you would want to be able to do this in one line of code. So, you should consider wrapping the different things you'd like to show or hide in a JPanel. Then, you can dynamically show or hide the JPanels.
You could have a login JPanel, which is set up and displayed and once the user's password is verified, you can show your application JPanel. This can easily be done using a CardLayout.
It treats each component in the container as a card. Only one card is visible at a time, and the container acts as a stack of cards.
Here is a tutorial.
Using a CardLayout, your code could look something like this:
instance variables:
static final String LOGINPANEL = "LOGINPANEL";
static final String MAINPANEL = "MAINPANEL";
JPanel cards;
where your panels are created:
JPanel loginPanel = new JPanel();
//add your stuff to the login panel
JPanel mainPanel = new JPanel();
//add your stuff to the main panel
cards = new JPanel(new CardLayout());
cards.add(loginPanel, LOGINPANEL);
cards.add(mainPanel, MAINPANEL);
then when your password is verified, in the AWT thread, you can do this:
CardLayout cl = (CardLayout)(cards.getLayout());
cl.show(cards, MAINPANEL);
I agree with JPanel suggestion. Add the log-in components to a JPanel, then hide the JPanel once there is a log-in.
I will suggest you to use a JDialog for your login. After a successful login you just need to call “dialog.dispose()” and then load your interface.
If the application you are building need to display several windows you should consider to use a JDesktopPane (http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JDesktopPane.html)

Categories