How to add external JPanel in JFrame? - java

I'm working on large scale program. As you can see I have one main JFrame and about 20 menu items on that. Each menu item must pop up a new window. At the beginning I have created a JLayeredPanel and then I assigned each menu item to one JPanel which is inside JFrame.Then I put 25 panel in JLayeredPanel... Default all the panels are set to invisible like:
panel1.setVisible(false);
panel2.setVisible(false);
so on
When user click on one menu item, its JPanel will be visible and rest are invisible. It looks messy and I have 5000 lines code. I used InternalFrame and TabbedPane but I'm not happy with them. I want to split my code in different JPanel classes and assign them to the main JFrame. I mean when user clicked on each menu item it will call the external JPanel and render it on the JPanel on the main JFrame. I am using design mode in netbeans and it does everything for me but the simpled structure is like this and it is not working:
public class NewJPanel extends JPanel{
//I have added buttons and etc on this panel
......
}
public class frame extends JFrame(){
JPanel panel = new JPanel();
.....
Public frame(){
frame.add(panel);
}
......
//When use click on the any button on the panel
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
//this is not working
NewJPanel fi = new NewJPanel ();
panel1.add(fi);
//or I tested this way separately but it did not work
panel1.remove();
panel1 = new NewJPanel();
add(panel);
invalidate();
}
}
please give me any suggestion how I can control this program in splited classes in professional way.

remove JPanel from JFrame.getContentPane.remove(myPanel)
add a new JPanel with constants, everyhing depends of used LayoutManager and its methods implemented in API
call JFrame.(re)validate() and JFrame.repaint() as last code lines, if everything is done, these notifiers correctly repaint available area
again to use CardLayout, there isn't signoficant performance or memory issue

Please give me any suggestion how I can control this program in splited classes in proressional way.
Ok.
You should put all of your JPanels in a JTabbedPane. The JTabbedPane would be added to the JFrame.
The JFrame, JTabbedPane, and each JPanel would be constructed in a separate class.
You use Swing components, rather than extending them. The only reason you extend a Swing component is if you override one of the component methods.
You should also create model classes for each of the JPanels, as well as a model class for the application.
Read this article to see how to put a Swing GUI together.

make's code better
public class NewJPanel extends JPanel{
//I have added buttons and etc on this panel
......
}
public class frame extends JFrame(){
JPanel panel = new JPanel();
.....
Public frame(){
//frame.add(panel); you dont need call frame because extends JFrame in frame class
add(panel);
......
//When use click on the any button on the panel
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
//this is not working
NewJPanel fi = new NewJPanel();
add(fi);
//or I tested this way separately but it did not work
/*panel1.remove();
panel1 = new NewJPanel();
add(panel);
invalidate();you must define panel1 before use it,like :JPanel panel1 = new JPanel();*/
}
}

Related

Java KeyBindings not reacting on JPanel

I have previously used Java's KeyListener, but as my programs are demanding more I have gotten the recommendation to switch over to KeyBinds.
First of all I have tried to add keybindings to JFrame which didn't work ( I don't understand what JComponent I need to use. ). Therefore I tried moving the program over to a JPanel and then adding it to a JFrame, however the Key bind do not react when the desired button is pressed (in this case it's the "1" button);
In the method call I have set the action to be Print "Hi". Here is the code:
public class Panel extends javax.swing.JPanel {
JPanel Panel = new JPanel();
/**
* Creates new form Panel
*/
public Panel() {
addKeyBinding(Panel, KeyEvent.VK_1, "1Button", (evt)->{
System.out.println("Hi");
});
initComponents();
}
.....
And here is the method
.....
public static void addKeyBinding(JComponent comp, int keyCode, String id, ActionListener actionListener){
InputMap im = comp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap ap = comp.getActionMap();
im.put(KeyStroke.getKeyStroke(keyCode, 0, false),
id);
ap.put(id, new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e) {
actionListener.actionPerformed(e);
}
});
}
What am I doing wrong? Thanks!
The key bindings are for your form panel, right? I think you're misunderstanding a few concepts about classes and objects. Also it's hard to help without seeing the full code. But your error is very likely caused by this line:
addKeyBinding(Panel, KeyEvent.VK_1, "1Button", ...
which should be:
addKeyBinding(this, KeyEvent.VK_1, "1Button", ...
The variable Panel should be replaced with the keyword this thus referencing the actual form panel.
It also should be created wherever you're creating your window so this line can also be removed:
JPanel Panel = new JPanel();
There are many things wrong with your code. I can't imagine the code in the first snippet even compiles. You are trying to name a variable the same as your classname.
Your class has no reason to extend JPanel since it isn't a new type of JPanel. Simply remove your extends. Then change the first line to:
JPanel panel = new JPanel();
Then pass lower-case panel to the addKeyBinding method.
If for some strange reason you want to keep your class extending JPanel then pass this as the first parameter to addKeyBinding as /u/tiiv said and remove the JPanel Panel = new JPanel line since that isn't needed (as you have it written now your class is the JPanel).
As far as which component to use JFrame is a top-level container so that is usually your main application window. And then you put JPanel and other components in the JFrame. There are actually 4 top-level containers in swing (JFrame, JWindow, JDialog, and JApplet) but JFrame is generally the one you will use as your main app window.
I hope that helps.

how to organize code while using multiple jpanel tabs in swing

I am new to swing programming. I have created a Jtabbedpane and added 4 jpanel to it.
all the button and labels in the 4 jpanel are in the same java class and is starting to look cluttered. I am using Intellij. It would be nice if I can put all the items and events related to one panel in its own class so 4 classes for 4 panels and just a reference to those classes in the main frame. Not sure how to do this as most of the code is generated by the IDE.
If there is a way to do this or a tutorial that does this please let me know.
Yes you can break this up rather easily. Anywhere the code generates a new panel, probably as a "build" method, you can pull that out and make in a structure in another class. An example would look something like this:
// New class file named testPanel.java
public class testPanel extends JPanel{
// Constructor
public textPanel(){
// Add an example button
JButton btn_exit = new JButton("Exit");
btn_exit.addActionListener(new ExitButtonListener());
buttons.add(btn_exit);
}
// Private inner class which does event handling for our example button
private class ExitButtonListener implements ActionListener{
public void actionPerformed(ActionEvent e){
System.exit(0);
}
}
// Add whatever other code you like here or above or anywhere else :)
}
Then to use that panel in your main JFrame, you can aggregate it like this:
private testPanel pnl_test = new textPanel();
// You can place this in the constructor
// for your JFrame without the "MyJFrame."
// But for demonstration purposes I will include it
MyJFrame.add(pnl_test);
// Or if you were placing a panel inside of another panel,
// you can use the same method associated with a JPanel object
MyJPanel.add(pnl_test);

How to change 'card' in Jframe cardlayout from Jpanel which belonging to card and its placed in another class?

I have written a jframe with cardlayout as in the following code :
public class Gui extends JFrame {
private static CardLayout cardlayout = new CardLayout();
private static JPanel cards = new JPanel(cardlayout);
public Gui() {
cards.setLayout(cardlayout);
CasaPanel card =new CasaPanel();
cards.add(card,"casa");
InCash card_1 = new InCash();
cards.add(card_1,"in");
OutCash card_2 = new OutCash();
cards.add(card_2,"out");
setLayout(new BorderLayout());
add(cards, BorderLayout.CENTER);
}
public static void showCard(String name)
{
cardlayout.show(cards, name);
}
i'm trying to call method to change card (ShowCard) from one of the JPanel(CasaPanel) , which is itself a 'card'. I want change a 'card' after clicking a button in a JPanel(CasaPanel) which is in another class. How to do this?I mean i know how to add button and listener but i don't know if is it possible to call a method in JFrame from a Jpanel class belonging to that frame ? How to refer to method in JFrame from other classes? I looked at this question but i really don't want put all code in one class.
Your "card" is added to the panel which uses the CardLayout. If you want to change cards then you just need access to the layout mananger. So from your panel you can use the getParent() method to get the parent panel and then use the getLayout() method to get the CardLayout.
So the code in the ActionListener might be something like:
JPanel parent = (JPanel)getParent();
CardLayout layout = parent.getLayout();
layout.show(panel, "...");
Also, then general design on your class is wrong. You should NOT be using static methods. Read the section from the Swing tutorial on How to Use CardLayout for working examples and a better way to structure your code.

how to find out a java Component being displayed on screen

I want to find out if a JPanel is on the screen or not. It doesn't mean that isVisible() method could be used for this situation. I mean I want to find out whether a component that has been initiated before, presently is one of components on my main panel or not.
Edit and more explanation: I have several panels initiated before in my program and use them on my form as needed. I want to know for example jpanel1 in now on any of panels that now are present on my form.
Example:
public class GUI extends JFrame() {
private JPanel1, jPanel2;
public static void main(String[] args) {
GUI gui = new GUI();
jPanel1 = new JPanel();
jPanel2 = new JPanel();
gui.setContentpane(jPanel1);
gui.setVisible(true);
}
}
now jPanel1 is visible on screen bu jPanel2 is not visible.
How can I find out this?
After investigation I find out this method represents that the component is displayed on screen or not:
isDisplayable()
in my Example:
jPanel1.isDisplayable() // returns true
jPanel2.isDisplayable() // returns false
as Simple as this!
jPanel1.isVisible()==true
jPanel1.isVisible()==false
for panel
jPanel1.isShowing() also works
If you're looking for children of a main panel, you could call getComponents() on the main panel to return an array of its Components, then iterate through them to check if any of them are the Panel you are looking for. You may need to call this recursively if the panel is not a direct child of the main panel.
Write your own panel class that extends JPanel. Add a new method to this class named isOnTheScreen() which return a boolean indicating whether the panel is added to the window or not.
public class MyPanel extends JPanel
{
boolean isAdded = false;
public boolean isOnTheScreen()
{
return isAdded;
}
public void setOnTheScreen(boolean isAdded)
{
this.isAdded = isAdded;
}
}
After creating your own panel objects, use the methods above to learn whether a panel is added to main panel/frame or not. Suppose you have added a panel to a frame:
JFrame frame = new JFrame()
MyPanel panel = new MyPanel();
frame.getContentPane().add(panel);
panel.setOnTheScreen(true);
As soon as you add it to the main screen, in this case a frame, call setOnTheScreen(true)
And similarly call setOnTheScreen(false) when you remove the panel.
After this design you can determine whether a panel is added to the main window or not by just invoking isOnTheScreen() anywhere else in your code. I hope this design helps you.

Why won't this Swing tabbed pane display?

Could someone explain what I am doing wrong with my classes that my JTabbedPane doesn't display when the JFrame.setvisible is set to true?
Yes, the main method of the program (which I won't put here) uses the event dispatching thread to initiate ArionGUI.
Here is my code for the JFrame:
import javax.swing.*;
public class ArionGUI extends JFrame {
public ArionGUI() {
// Set up GUI frame for Arion
JFrame arionFrame = new JFrame("Arion v 0.01");
// Add Arion Tabbed Pane
arionFrame.getContentPane().add(new ArionTabbedPane());
// Terminate the application when closed
arionFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
// Set the size of the frame
arionFrame.setSize(500, 500);
// Center window
arionFrame.setLocationRelativeTo(null);
// Prevent user from resizing window
arionFrame.setResizable(false);
// Make Arion frame visible on screen
arionFrame.setVisible(true);
}
}
And here is my code for the JTabbedPane:
import javax.swing.JTabbedPane;
import javax.swing.JLabel;
import javax.swing.JComponent;
public class ArionTabbedPane extends JComponent {
JTabbedPane arionTabbedPane;
public ArionTabbedPane() {
arionTabbedPane = new JTabbedPane(JTabbedPane.TOP);
arionTabbedPane.addTab("Characters", new JLabel("This is the characterz tab"));
arionTabbedPane.addTab("Miscellaneous", new JLabel("This is the miscellaneous tab"));
add(arionTabbedPane);
}
}
Because ArionTabbedPane isn't actually a tabbed pane. It's a wrapper for one. So you're just adding a component to your JFrame not a TabbedPane. If you want to be able to add ArionTabbed pane to your JFrame it needs to extend JTabbedPane. If you want to add the Pane it's wrapping, then you need a function that returns a reference to it's internal tabbed pane and you need to add that to your JFrame. Something like this:
ArionTabbedPane tabbedPane = new ArionTabbedPane();
arionFrame.getContentPane().add(tabbedPane.getPane());
Where ArionTabbedPane.getPane() is something like this:
Public JTabbedPane getPane() {
return arionTabbedPane;
}
Edit: Hmm.. the other thing you could do that mioght work, if you don't want to do either of those is have ArionTabbedPane extend JPanel instead of JComponent. Java knows JPanel is a container and so when it's added to your JFrame it should check inside the JPanel for things to show. The only thing you'd have to change for that would be having ArionTabbedPane extend JPanel instead of JComponent.
Edit again, if you extend JTabbedPane then you'll need to remove the internal JTabbedPane. The new ArionTabbedPane should look something like this:
public class ArionTabbedPane extends JTabbedPane {
public ArionTabbedPane() {
super(JTabbedPane.TOP); // Calls JTabbedPane's constructor.
this.addTab("Characters", new JLabel("This is the characterz tab"));
this.addTab("Miscellaneous", new JLabel("This is the miscellaneous tab"));
}
}
Much simpler really.
What he said:
alt text http://img182.imageshack.us/img182/3585/imagen7e.png

Categories

Resources