how to find out a java Component being displayed on screen - java

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.

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.

JLayeredPane returning null on getParent()

My situation: I have a class MainScreen that extends JFrame (it really is just a JFrame with a main method to start the application) on which I added a class GameManager that extends JLayeredPane, that I'm using to display something.
public static void main(String[] args) {
MainScreen ms = new MainScreen();
}
public MainScreen() {
this.initScreen();
this.gm = new GameManager();
this.add(gm, BorderLayout.CENTER);
this.setVisible(true);
}
Now, what I want to do is, from the GameManager class I want to add a JButton to the main JFrame. I thought it would be easy, just do:
JButton button = new JButton("Hello");
this.getParent().add(button, BorderLayout.SOUTH);
but getParent() is returning null, so obviously it doesn't work. I don't know why though, I did something similar before (with a JComponent and a JPanel though), and I thought that every JComponent when added to a container would have the container as its parent. What did I miss?
If the following statement:
this.getParent().add(button, BorderLayout.SOUTH);
exists within constructor of GameManager.java, then getParent() is returning null is correct. It is because the object of GameManager is added to MainScreen after the call to this.getParent().add(button, BorderLayout.SOUTH);.
As per https://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html
Each top-level container has a content pane that, generally speaking,
contains (directly or indirectly) the visible components in that
top-level container's GUI.
In case of JFrame the default content pane is a JPanel. So when you made a call to this.add(gm, BorderLayout.CENTER);, you actually added the instance of GameManager to the default content pane of JFrame i.e. a JPanel. That is why GameManager.getParent() is a JPanel. Hope, this helps.

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.

Java, swing opening new JFrame from another class

I have this piece of code:
public class GUI extends JFrame {
private PlaneUI planeui;
public GUI(PlaneUI planeui) {
this.planeui = planeui;
}
//We have put the code that creates the GUI inside a method
public GUI() {
start();
planeui.display();
} ...
This is just a test and I need the method "planeui.display" to work when the program starts, together with the method "start();" which already works.
public final class PlaneUI extends JFrame {
public void display() {
//Creates a new JPanel object
JPanel panelStart = new JPanel();
getContentPane().add(panelStart);
//Changing the default layout from Flowlayout to absolute
panelStart.setLayout(null);
setTitle("Reservationer"); //Sets the window title
setSize(236, 256); //Sets the default size of the window
setLocationRelativeTo(null); //Start location of the window (centered)
setDefaultCloseOperation(EXIT_ON_CLOSE); //Exits the window
}
}
I have imported the needed libraries and I feel like the problem lies in an object that isn't created correctly since I get a nullpointerexception. I tried running this planeUI class in the main method and it worked correctly. I just can't get it to work this way..
In function PlaneUI.display() add one last line setVisible(true) because your adding everything but not displaying anything
you have to add this into your display() method:
setVisible(true);
Otherwise, all you are doing is setting all the aspects of the JFrame and adding the JPanel to it. You have to make it visible afterwards.

How to add external JPanel in JFrame?

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();*/
}
}

Categories

Resources